toybox/toys/posix/tee.c
<<
>>
Prefs
   1/* tee.c - cat to multiple outputs.
   2 *
   3 * Copyright 2008 Rob Landley <rob@landley.net>
   4 *
   5 * See http://opengroup.org/onlinepubs/9699919799/utilities/tee.html
   6
   7USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
   8
   9config TEE
  10  bool "tee"
  11  default y
  12  help
  13    usage: tee [-ai] [file...]
  14
  15    Copy stdin to each listed file, and also to stdout.
  16    Filename "-" is a synonym for stdout.
  17
  18    -a  Append to files
  19    -i  Ignore SIGINT
  20*/
  21
  22#define FOR_tee
  23#include "toys.h"
  24
  25GLOBALS(
  26  void *outputs;
  27)
  28
  29struct fd_list {
  30  struct fd_list *next;
  31  int fd;
  32};
  33
  34// Open each output file, saving filehandles to a linked list.
  35
  36static void do_tee_open(int fd, char *name)
  37{
  38  struct fd_list *temp;
  39
  40  temp = xmalloc(sizeof(struct fd_list));
  41  temp->next = TT.outputs;
  42  temp->fd = fd;
  43  TT.outputs = temp;
  44}
  45
  46void tee_main(void)
  47{
  48  if (FLAG(i)) xsignal(SIGINT, SIG_IGN);
  49
  50  // Open output files
  51  loopfiles_rw(toys.optargs,
  52    O_RDWR|O_CREAT|WARN_ONLY|(FLAG(a)?O_APPEND:O_TRUNC),
  53    0666, do_tee_open);
  54
  55  for (;;) {
  56    struct fd_list *fdl;
  57    int len;
  58
  59    // Read data from stdin
  60    len = xread(0, toybuf, sizeof(toybuf));
  61    if (len<1) break;
  62
  63    // Write data to each output file, plus stdout.
  64    fdl = TT.outputs;
  65    for (;;) {
  66      if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1;
  67      if (!fdl) break;
  68      fdl = fdl->next;
  69    }
  70  }
  71}
  72