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

Summary

mktemp - make directories

[Source] [Code Walkthrough]

Lines of code: 351
Principal syscall: mkdir(), open(), stat()
Support syscalls: write() via puts()
Options: 13 (6 short, 7 long)

Added to Coreutils in October 2007 [First version]
Number of revisions: 49 [Code Evolution]

The core work behind mktemp happens within gnulib. The utility allocates buffers and parses the target name to provide appropriate counts before passing off file creation responsibility

Helpers:
  • count_consecutive_X_s() - Returns a size_t count of Xs
  • maybe_close_stdout() - Closes STDOUT based on global flag setting
  • mkdtemp_len() - Wrapper for gen_tempname() to create a temp directory
  • mkstemp_len() - Wrapper for gen_tempname() to create a temp file
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
  • file_name_concat() - Concatenates two files names (in gnulib)
  • gen_tempname_len() - Generates a hard-to-predict temp file name (in gnulib)
  • last_component() - Returns the final component of an input path (in gnulib)

Setup

mktemp defines one global flag, stdout_closed to track if STDOUT has been closed during execution. It is checked prior to exit to avoid a double close.

mktemp initializes a list of local variables in main(), including:

  • c - The first letter of the next option to process
  • create_directory - Flag if the target is a directory
  • *dest_dir - Pointer to the destination directory, user provided or default
  • *dest_dir_arg - Pointer to the provided directory string
  • *dest_name - The name of the final target created
  • deprecated_t_option - Flag set if the name is a single file name (-t)
  • dry_run - Flag to test the generated name (-u)
  • n_args - Number of arguments (beyond options)
  • *template - The user provided template string, default tmp.XXXXXXXXXX
  • status - The final return status of the utility
  • *suffix - Pointer to the user provided suffix string
  • suffix_len - The length of the suffix
  • suppress_file_err - Flag for quiet mode
  • use_dest_dir - Flag to use the user provided directory (-p or -t)
  • x_count - The consecutive X count

Parsing

Parsing mktemp considers five questions:

  • Are we creating a file or directory?
  • Is this a test run to see resulting output?
  • Is there a desired file suffix, such as an extension?
  • Should the target file follow a specified template
  • Should error messages be suppressed

Parsing failures

These failure cases are explicitly checked:

  • Adding more than one template argument
  • Specifying suffix with a template that doesn't end in X
  • Embedding a directory with a suffix
  • Including a directory within a template
  • Using an absolute-form template
  • Less than 3 Xs provided in the template
  • Unknown options used

Failures result in a short error message followed by the usage instructions.


Execution

The mktemp utility computes the boundaries of the temporary name before passing them to the gnulib. The logic is this:

  • Get the length of the template.
  • Get the length of the suffix, which may be 1 if default.
  • Allocate space for the name.
  • Count the number of Xs in the template
  • Get the leading path length, if any.
  • Concatenate the path, unprocessed template, and suffix components
  • Pass the incomplete template to gnulib via wrappers
    • Files: mkstemp_len() Directories: mkdtemp_len()
  • Output the random temp file name created

Failure cases:

  • Unable to create target file or directory
  • Unable to print name of the successfully created target
    • The target is removed if it cannot be reported properly

Failures at this stage output an error message to STDERR unless quiet mode was enabled


[Back to Project Main Page]