diff options
Diffstat (limited to 'toys')
-rw-r--r-- | toys/tee.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/toys/tee.c b/toys/tee.c new file mode 100644 index 00000000..8c8f3d5c --- /dev/null +++ b/toys/tee.c @@ -0,0 +1,74 @@ +/* vi: set sw=4 ts=4: + * + * tee.c - cat to multiple outputs. + * + * Copyright 2008 Rob Landley <rob@landley.net> + * + * See http://www.opengroup.org/onlinepubs/009695399/utilities/tee.html + +USE_TEE(NEWTOY(tee, "ia", TOYFLAG_BIN)) + +config TEE + bool "tee" + default y + help + usage: tee [-ai] [file...] + + Copy stdin to each listed file, and also to stdout. + Filename "-" is a synonym for stdout. + + -a append to files. + -i ignore SIGINT. +*/ + +#include "toys.h" + +DEFINE_GLOBALS( + void *outputs; +) + +#define TT this.tee + +struct fd_list { + struct fd_list *next; + int fd; +}; + +// Open each output file, saving filehandles to a linked list. + +static void do_tee_open(int fd, char *name) +{ + struct fd_list *temp; + + temp = xmalloc(sizeof(struct fd_list)); + temp->next = TT.outputs; + temp->fd = fd; + TT.outputs = temp; +} + +void tee_main(void) +{ + if (toys.optflags&2) signal(SIGINT, SIG_IGN); + + // Open output files + loopfiles_rw(toys.optargs, + O_RDWR|O_CREAT|((toys.optflags&1)?O_APPEND:O_TRUNC), do_tee_open); + + for (;;) { + struct fd_list *fdl; + int len; + + // Read data from stdin + len = xread(0, toybuf, sizeof(toybuf)); + if (len<1) break; + + // Write data to each output file, plus stdout. + fdl = TT.outputs; + for (;;) { + if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1; + if (!fdl) break; + fdl = fdl->next; + } + } + +} |