17aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley/* tee.c - cat to multiple outputs.
22bfaaf25614985ada5490d08e005b36f948d8186Rob Landley *
32bfaaf25614985ada5490d08e005b36f948d8186Rob Landley * Copyright 2008 Rob Landley <rob@landley.net>
42bfaaf25614985ada5490d08e005b36f948d8186Rob Landley *
5f91b7c89bc852868692b9518185421ebb52d67b3Rob Landley * See http://opengroup.org/onlinepubs/9699919799/utilities/tee.html
62bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
71dd3704c5ffea926f61a96bb7de7d9dbee52fa44Paul BarkerUSE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
82bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
92bfaaf25614985ada5490d08e005b36f948d8186Rob Landleyconfig TEE
107aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  bool "tee"
117aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  default y
127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  help
137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    usage: tee [-ai] [file...]
142bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    Copy stdin to each listed file, and also to stdout.
167aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    Filename "-" is a synonym for stdout.
172bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
187aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    -a	append to files.
197aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    -i	ignore SIGINT.
202bfaaf25614985ada5490d08e005b36f948d8186Rob Landley*/
212bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
22c0e56edaf256adb6c60c5a052525a1ffbb927901Rob Landley#define FOR_tee
232bfaaf25614985ada5490d08e005b36f948d8186Rob Landley#include "toys.h"
242bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
25c0e56edaf256adb6c60c5a052525a1ffbb927901Rob LandleyGLOBALS(
267aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  void *outputs;
272bfaaf25614985ada5490d08e005b36f948d8186Rob Landley)
282bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
292bfaaf25614985ada5490d08e005b36f948d8186Rob Landleystruct fd_list {
307aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct fd_list *next;
317aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int fd;
322bfaaf25614985ada5490d08e005b36f948d8186Rob Landley};
332bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
342bfaaf25614985ada5490d08e005b36f948d8186Rob Landley// Open each output file, saving filehandles to a linked list.
352bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
362bfaaf25614985ada5490d08e005b36f948d8186Rob Landleystatic void do_tee_open(int fd, char *name)
372bfaaf25614985ada5490d08e005b36f948d8186Rob Landley{
387aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct fd_list *temp;
392bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
407aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  temp = xmalloc(sizeof(struct fd_list));
417aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  temp->next = TT.outputs;
427aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  temp->fd = fd;
437aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  TT.outputs = temp;
442bfaaf25614985ada5490d08e005b36f948d8186Rob Landley}
452bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
462bfaaf25614985ada5490d08e005b36f948d8186Rob Landleyvoid tee_main(void)
472bfaaf25614985ada5490d08e005b36f948d8186Rob Landley{
48c776bde13bb2767db2943bc3b02df737a465c035Rob Landley  if (toys.optflags & FLAG_i) xsignal(SIGINT, SIG_IGN);
492bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
507aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  // Open output files
517aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  loopfiles_rw(toys.optargs,
527aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    O_RDWR|O_CREAT|((toys.optflags & FLAG_a)?O_APPEND:O_TRUNC),
537aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    0666, 0, do_tee_open);
542bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
557aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  for (;;) {
567aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    struct fd_list *fdl;
577aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    int len;
582bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
597aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    // Read data from stdin
607aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    len = xread(0, toybuf, sizeof(toybuf));
617aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    if (len<1) break;
622bfaaf25614985ada5490d08e005b36f948d8186Rob Landley
637aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    // Write data to each output file, plus stdout.
647aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    fdl = TT.outputs;
657aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley    for (;;) {
667aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1;
677aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      if (!fdl) break;
687aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley      fdl = fdl->next;
692bfaaf25614985ada5490d08e005b36f948d8186Rob Landley    }
707aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  }
712bfaaf25614985ada5490d08e005b36f948d8186Rob Landley}
72