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