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

Summary

tee - redirect output to multiple files or processes

[Source] [Code Walkthrough]

Lines of code: 279
Principal syscall: fopen()
Support syscalls: fwrite(), fadvise()
Options: 8 (3 short, 5 long)

Descended from tee introduced in Version 5 UNIX (1974)
Added to Shellutils in November 1992 [First version]
Number of revisions: 131

Helpers:
  • tee_files() - Performs the tee operation on the given file list
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

Setup

tee sets up the options and argument values at global scope. It also declares operating mode flags including:

  • append - Flag for appending output (-a)
  • ignore_interrupts - Flag to mask interrupts(-i)

main() defines two local variables:

  • ok - Tracks the status results of the operation
  • optc - The next option character to process

Parsing begins with the short options passed as a string literal:
"aip"


Parsing

The tee utility needs the user to answer these questions:

  • Should I/O append or overwrite?
  • How should interrupts be handled?
  • How should errors be handled?

Parsing failures

The only parsing error explicitly check is if an unknown option is used. The result is a short error message followed by the usage instructions.


Execution

The tee execution path follows the aniticapted flow: Open targets, read standard input, write to all outputs (and STDIO). Close targets afterward.

There are a few more considerations. Consider this more detailed flow that picks up after parsing:

  • If the user chose to ignore interrupts, replace the default hander - signal (SIGINT, SIG_IGN);
  • In most cases, the user won't want default SIGPIPE behavior so ignore - signal (SIGPIPE, SIG_IGN);
  • Open each target file with no buffering
  • While STDIN has more data to read...
    • Read in data to a buffer
    • Write that data to each target, checking for failures
  • Close all target files

The tee utility may fail in several ways. An EXIT_FAILURE status indicates a failure of tee, while EXIT_ENOENT or EXIT_CANNOT_INVOKE points to a problem with the target command.

Failure cases:

  • STDIN did not close properly
  • Unable to open a target
  • Unable to read data in from STDIN
  • A write error occurs as requested by the user
  • Unable to close a target

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


[Back to Project Main Page]