Decoded: stat (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[GNU Manual] [No POSIX requirement] [Linux man] [FreeBSD man]

Logical flow of stat command (coreutils)

Summary

stat - report file or file system status

[Source] [Code Walkthrough]

Lines of code: 1686
Principal syscall: statvfs()
Support syscalls: stat(), fstat(), lstat()
Options: 11 (4 short, 7 long)

This is a relatively recent utility
Added to Shellutils in November 2001 [First version]
Number of revisions: 244

Don't confuse this stat utility with the stat() system call. This utility is for displaying detailed file information beyond that of other utilities, like ls.

Helpers:
  • default_format() - Applies the default format string (File, ID, Block size, etc)
  • do_stat() - The formatted stat procedure for files
  • do_statfs() - The formatted statfs procedure for filesystems
  • find_bind_mount() - Retrieves the mount point for the name from the mount list
  • get_birthtime() - Finds the creation time of a file
  • getenv_quoting_style() - Sets the quoting style depending on environment
  • human_access() - Retrieves file the access string (i.e. drwxr--r--)
  • human_fstype() - Returns a string describing the type of file system
  • human_time() - Formats a readable timestamp
  • make_format() - Finalizes the pformat with only allowables
  • neg_to_zero() - Returns a zero timepsec for comparison
  • out_epoch_sec() - Oututs the number of seconds since an unput timespec
  • out_file_context() - Prints the security context
  • out_int() - Outputs a signed integer and returns the character count
  • out_minus_zero() - Outputs the number without any decimal precision
  • out_mount_point() - Prints the mount point
  • out_string() - Outputs a string and returns the character count
  • out_uint() - Outputs an unsigned decimal integer and returns the character count
  • out_uint_o() - Outputs an unsigned octal integer and returns the character count
  • out_uint_x() - Outputs an unsigned hex and returns the character count
  • print_esc_char() - Outputs a processed escape character
  • print_it() - Generic print wrapper to execute print_statfs() or print_stat()
  • print_statfs() - Prints statfs information based on given format
  • print_stat() - Prints stat information based on given format
  • statfs() - A BeOS specific workaround for statvfs()
External non-standard helpers:
  • die() - Exit with mandatory non-zero error and message to stderr
  • error() - Outputs error message to standard error with possible process termination

Setup

stat uses over 150 lines of code for macros detecting system features available for collecting file information. In most cases, the information will come from a statvfs() syscall. Portability (esp. BeOS) demands that we include several possible angles to find information. The result is a robust layer of macros to unify calls during utility execution. One example is STATFS, which resolves to the appropriate function on the system

stat keeps several flags and variables as globals, including:

  • *decimal_point - The decimal point in the current locale
  • decimal_point_len - The length of the decimal point in the current locale
  • fmt_terse_fs[] - Terse formats accepted when we're print file system status
  • fmt_terse_regular[] - Terse formats accepted by non-SELinux
  • fmt_terse_selinux[] - Terse formats accepted by SELinux
  • follow_links - Flag to dereference links (-L)
  • interpret_backslash_escapes - Flag to force interpreting backslashes
  • trailing_delim - The end of string delimiter

main() introduces a few local variables:

  • c - The character for the next option to process
  • *format - The user-provided format string (-c)
  • *format2 - Alternate format for block and character devices
  • fs - Flag if user requests file system information (-f)
  • ok - The final return status
  • terse - Flag if the user requests terse mode (-t)

Parsing

Parsing answers the following questions to define the execution parameters

  • What is the format of the output information? Is it terse output?
  • Should we report file system information?
  • Follow links or report on the link itself?

Parsing failures

These failure cases are explicitly checked:

  • User fails to provide a target file
  • Improper format provided (unknown option)
  • Unknown option used

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

stat has a straight-forward design despite the number of lines of code. The process looks like this:

  • Verify the format requested, either from the user or the default.
  • If this is a file, stat() it, (or fstat() for STDIN, lstat() for a link)
  • If this is a file system, call the system statvfs() or equivalent
  • In all cases, format print the output.

Failure cases:

  • Any stat() fails
  • Unable to follow a symbolic link

All failures at this stage output an error message to STDERR and return without displaying usage help


[Back to Project Main Page]