Decoded: pwd (coreutils)

[Back to Project Main Page]

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

Logical flow of pwd command (coreutils)

Summary

pwd - print working directory

[Source] [Code Walkthrough]

Lines of code: 395
Principal syscall: None
Support syscalls: stat()
Options: 6 (2 short, 4 long)

Decended from the UNIX 6th ed pwd utility (1975)
Added to Shellutils in April 1994 [First version]
Number of revisions: 99 [Code Evolution]

Helpers:
  • file_name_free() - Frees a file_name struct
  • file_name_init() - Allocates and initializes a file_name struct
  • file_name_prepend() - Add a string component to the current file name
  • find_dir_entry() - Resolves the base of the current directory (".")
  • logical_getcwd() - Resolves the logical path using the shell environment (-L)
  • nth_parent() - Returns an allocates string of parent components ("../")
  • robust_getcwd() - Resolves the absolute physical path (-P)
External non-standard helpers:
  • xgetcwd() - gnulib wrapper for getcwd()

Setup

pwd defines on a struct, file_name, to maintain a reconstructed current working directory. The utility initializes, constructs, and eventually outputs the data from this structure.

main() initializes two variables of interest:

  • logical - The flag that determines the execution mode
  • *wd - Pointer to the working directory name

Parsing begins with the two character literal for short-options: "LP"


Parsing

Parsing pwd comes down to one question: Should we use the physical or logical representation. We check the options to determine usage

Parsing failures

Parsing may fail if the user provides an unknown option. There may also be a warning if any arguments are passed (none are expected)


Execution

Executing pwd utility follows two distinct paths depending on if the user wants the logical or physical resolution. The key difference between the two is that the physical path contains no symlinks.

Logical pwd

The user must request a logical resolution, which primarily relies on the environment variable $PWD. The process is:

  • Get the $PWD value with getenv()
  • Verify the value (not NULL, not from root, and no dot components)
  • stat() the result to verify it exists and matches "."
  • Print the result

Physical pwd

If the user provided the -P option or the logical pwd failed, we try a physical resolution.

  • Get the current working directory with the xgetcwd() wrapper
  • Print the result (if there is one)
  • If there is no result, attempt to reconstruct the cwd:
    • Initialize the file_name data structure
    • Work backwards from the present directory to root, resolving each path component
    • Null-term the buffer
    • Print the result

Failure cases:

  • No file systems are processed (nothing mounted or target not available)
  • Unable to access file systems

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


[Back to Project Main Page]