Decoded: whoami (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 whoami command (coreutils)

Summary

whoami - print effective user id

[Source] [Code Walkthrough]

Lines of code: 98
Principal syscall: geteuid()
Support syscalls: None (getpwuid() is not a syscall)
Options: 2 (help and version)

Oldest conceptual ancestor is WHOAMI from CTSS 2ed. (1969)
Added to Shellutils in November 1992 [First version]
Number of revisions: 85 [Code Evolution]

Helpers:
  • None
External non-standard helpers:
  • die() - Exit with mandatory non-zero error and message to stderr

Setup

whoami only uses the default parsing options, which require no initialization

main() initializes the following:

  • uid - Holds the result of geteuid()
  • NO_UID - Holds the failure uid for comparison (-1)
  • errno - Self-explanatory
  • pw - Holds the resulting struct passwd from getpwuid()

Parsing

Parsing for whoami involves two checks:

  • Check for any long options
  • Check for anything else

Parsing failures

This failure case is explicitly checked:

  • If any non-long operand is passed

This failure results in a short error message followed by the usage instructions.


Execution

Successful execution is a simple sequential procedure: Call geteuid(), compare the returned value against passwd and return the resulting name.

Failure cases:

  • No matching uid is found in passwd
  • geteuid() returned -1 and set errno

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

Extra comments

whoami vs logname

Both commands return user names that often match...but not always. Consider this:

$ whoami
maizure
$ logname
maizure


$ sudo whoami
root
$ sudo logname
maizure

whoami returns the effective user id running the process using geteuid(). sudo temporarily changes the effective user.

logname returns the user name of whoever launched the terminal -- typically the user logged in to the system. My system pulls this info from /proc/self/loginuid

Fun fact: Comparing results between geteuid() and /proc/self/loginuid is a common check for altered execution state in your scripts and utilities

POSIX inconsistency

Possible inconsistency with POSIX, which says:

The geteuid() function shall always be successful and no return value is reserved to indicate an error.

Since these utilities may be useful in non-corforming environments, POSIX offers an extension that says:

In a conforming environment, geteuid() will always succeed. It is possible for implementations to provide an extension where a process in a non-conforming environment will not be associated with a user or group ID. It is recommended that such implementations return (uid_t)-1 and set errno to indicate such an environment; doing so does not violate this standard, since such an environment is already an extension.

[Back to Project Main Page]