[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
mv - move (rename) files
Lines of code: 513
Principal syscall: None
Support syscalls: fstatat()
Options: 23 (10 short, 13 long, does not include perm digits)
Descended from mv introduced in Version 1 UNIX (1971)
Added to Fileutils in October 1992 [First version]
Number of revisions: 250
The actual move procedure is a type of copy that is over 1000 lines long due to the many implementation methods and edge cases. Since it's only referenced from mv.c
, I won't discuss it directly, but if you need more details, dig in to copy.h
.
cp_option_init()
- Initializes astruct cp_options
to default valuesdo_move()
- The procedure for moving a single filemovefile()
- Moves a single file, handling directories as needrm_option_init()
- Initializes astruct rm_options
to default valuestarget_directory_operand()
- Detects if an input file path\name is a directory
copy()
- The tie to coreutils copy implementationdie()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process termination
Setup
mv does little work at global scope but defines a long list of variables in main():
*backup_suffix
- The suffix added to backup filesc
- The current command line option letter we're parsing**file
- The start of the file arraymake_backups
- Flag if backups of processed files should be maden_files
- The number of files provided be the user (index to file[])no_target_directory
- Flag to ignore special trailing directory handlingok
- The final return status. Note overloaded usageselinux_enabled
- Flag if SELinux is enabled*target_directory
- The destination path as provided by the user*version_control_string
- The backup method argument provided by the userx
- A copy options structure used to control move behavior
Parsing begins with the short options passed as a string literal:
"bfint:uvS:TZ"
Parsing
Parsing collects all of the user specified options, answering questions about execution:
- Which file do we move and where to?
- If it's a directory, how should we handle certain cases?
- Should we create a backup, if so, is there a special suffix?
- Should the operation force move?
- Is there a security context?
Parsing failures
These failure cases are explicitly checked:
- Specifying multiple target directories
- Specifying an inaccessible or non-existent target directory
- Using both no-target-directory and target-directory
- Missing source or destination files
- Using both backup and no-clobber options
- Using an unknown option
User specified parsing failures result in a short error message followed by the usage instructions. Access related parsing errors die with an error message.
Execution
mv
passes off most of the execution to the copy subsystem (copy.h). However some prep work is still required.
- Initialize a hash table used for file system triples (name, inode, device)
- If there is a target directory, build the full path and remove trailing slashes
- Pass the files and the parsed options to
copy()
- Return the status from
copy()
While no failure cases are explicitly checked for mv, the copy subsystem mail fail for a variety of reasons.