[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
chown - change file owner and group
Lines of code: 332
Principal syscall: chownat()
Support syscalls: stat()
Options: 21 (8 short, 13 long, does not include perm digits)
Descended from chown introduced in Version 1 UNIX (1971)
Added to Fileutils in October 1992 [First version]
Number of revisions: 169
The chown utility pushes much of the work to a separate source file (chown-core.c), which it shared with chgrp
Helpers:- None
chown_files()
- Processes all input files via chown-core.cdie()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process terminationgid_to_name()
- Converts a group id to a stringparse_user_spec()
- Separates UID:GID strings.uid_to_name()
- Converts a user id to a string
Setup
At global scope, chown.c defines *reference_file
to hold a possible file name argument passed by the user.
Afterward, main() initializes the following:
bit_flags
- Bit flags for behavior of the file traversal systemschopt
- A structure that organizes option settings for the utilitydereference
- Flag for how to handle symlinks (link or target)gid
- GID specified by the user (from ref file)ok
- The final return status. Note overloaded usageoptc
- The character for the next option to processpreserve_root
- Flag set to preserve root (--preserve-root option)required_gid
- The original GID as passed directly (--from)required_uid
- The original UID as passed directly (--from)uid
- UID specified by the user (from ref file)
Parsing kicks off with the short options passed as a string literal:
"HLPRcfhv"
Parsing
Parsing, collects options and arguments to answer the following questions:
- Which file(s) do we modify
- What is the new group?
- Is the user:group provided directly or with a reference file
- Are we preserving root?
- Are we operating recursively
- What amount of reporting should we provide?
Parsing failures
These failure cases are explicitly checked:
- Providing conflicting options for recursion and symlink handling
- Mismatch between actual and expected operand count (references files, etc)
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
Execution begins by finding UID:GID and associated name strings. The source is provided either as reference file to stat()
or directly by the user as an argument.
Next, if we're preserving root, we find the root inode and buffer it
Changing User:Group is handed off to chown-core. We push the computed parameters (uid, gid, bit fields, and behavior flags) to chown_files()
. In most cases, this ends with a call to a chown()
variant depending on the target file types.
Failure cases:
- Cannot
stat()
reference file (missing, no perms, etc) - Cannot access filesystem root while preserving and recursing
- Implicitly, failure includes the ways that
chown()
could fail.
All failures at this stage output an error message to STDERR and return without displaying usage help