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

Summary

rmdir - remove empty directories

[Source] [Code Walkthrough]

Lines of code: 252
Principal syscall: rmdir()
Support syscalls: None
Options: 8 (2 short, 6 long)

Descended from rmdir introduced in Version 1 UNIX (1971)
Added to Fileutils in October 1992 [First version]
Number of revisions: 120

Helpers:
  • errno_may_be_empty() - True if errno shows a possible empty directory
  • errno_rmdir_non_empty() - True if errno is due to non-empty target
  • ignorable_failure() - True if the error is ignorable
  • remove_parents() - Remove ancestors of the target directory
External non-standard helpers:
  • error() - Outputs error message to standard error with possible process termination
  • prog_fprintf() - Outputs program name and given extras
  • strip_trailing_slashes() - Removes extra slashes at the end of an input path

Setup

At global scope, rmdir does the following:

  • Defines remove_empty_parents flag set by user options to delete ancestor directories
  • Defines ignore_fail_on_empty flag set by user options to continue on non-empty failure
  • Defines verbose flag to control output display

main() initializes the following:

  • ok - The final return status. Note overloaded usage
  • optc - The current command line option letter we're parsing

Parsing

Parsing for rmdir answers a couple questions:

  • Should we delete ancestor directories as well as the target?
  • Continue processing if there is a non-empty failure?
  • Which directories should be delete?

The final question is answered from provided arguments no parsing.

Parsing failures

The only failure case checked is if the user provides not target directory arguments. The result is a short error message followed by the usage instructions.


Execution

rmdir has a simple and predictable operation:

  • Loop through all target directories and invoke the rmdir() syscall to delete.
  • If requested, call the recursive remove_parents function:
    • Parse the parent name by removing slashes
    • Call rmdir() on the parent
    • Repeat remove_parents() on the next parent

The primary failure case follows the result of the rmdir() syscall. The user may choose to ignore some errors and continue processing with all directories. Otheriwse, all failures at this stage output an error message to STDERR and return without displaying usage help.

Ignorable Errors

Failure of rmdir() sets errno. Certain errors may be ignore so processing can continue. These include:

  • EACCES - Lack of permissions (no search or no write on parent)
  • EPERM - Lack of permissions (not owner)
  • EROFS - Directory is read-only
  • EEXIST - Directory is not empty
  • EBUSY - Directory is being accessed elsewhere

[Back to Project Main Page]