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

Summary

groups - print group names a user is in

[Source] [Code Walkthrough]

Lines of code: 146
Principal syscall: getuid(), getegid(), getgid(), getgroups() (via mgetgroups() in gnulib)
Support syscalls: None
Options: 2 (--help and --version)

Added to Coreutils in February 2008 [First version]
Number of revisions: 36 [Code Evolution]

Helpers:

None

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
  • print_group_list() - Prints the distinct groups the user is in (in group-list.c)

Setup

main() introduces a few local variables:

  • egid - The effective gid currently being evaluated
  • ok - The final return status
  • optc - The character for the next option to process
  • rgid - The real gid currently being evaluated
  • ruid - The uid currently being evaluated

Parsing

Parsing groups is limited. There are only the default options (help/version) plus optional arguments representing the usernames to look up.

Using any option other than --help and --version is a parsing failure which results in a short error message followed by the usage instructions.


Execution

The primary job of the groups utility is to get the uid/gid of the input username and then pass it to an external function that does the real effort (print_group_list())

. The two approaches are if the user provides user names, or if none are provided and we need to lookup the current user.

No username provided:

  • Get the current user real UID using getuid()
  • Get the current user effective GID using getegid()
  • Get the current user real GID using getgid()
  • Pass the IDs to print_group_list() to print the information
  • Print new line character

Username(s) provided:

  • Loop through each user name argument and:
    • Look up the user in passwd using getpwnam()
    • Pull the UID, EGID, and GID from the passwd entry
    • Pass the IDs to print_group_list() to print the information
    • Print new line character

Failure cases:

  • Cannot get the UID, EGID, or GID.
  • User not found in passwd

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


[Back to Project Main Page]