123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- /* tee.c - cat to multiple outputs.
- *
- * Copyright 2008 Rob Landley <rob@landley.net>
- *
- * See http://opengroup.org/onlinepubs/9699919799/utilities/tee.html
- USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|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
- */
- #define FOR_tee
- #include "toys.h"
- GLOBALS(
- void *outputs;
- int out;
- )
- 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;
- if (1 == (temp->fd = fd)) TT.out++;
- TT.outputs = temp;
- }
- void tee_main(void)
- {
- struct fd_list *fdl;
- int len;
- if (FLAG(i)) xsignal(SIGINT, SIG_IGN);
- // Open output files (plus stdout if not already in output list)
- loopfiles_rw(toys.optargs,
- O_RDWR|O_CREAT|WARN_ONLY|(FLAG(a)?O_APPEND:O_TRUNC),
- 0666, do_tee_open);
- if (!TT.out) do_tee_open(1, 0);
- // Read data from stdin, write to each output file.
- for (;;) {
- if (1>(len = xread(0, toybuf, sizeof(toybuf)))) break;
- for (fdl = TT.outputs; fdl;fdl = fdl->next)
- if (len != writeall(fdl->fd, toybuf, len)) toys.exitval = 1;
- }
- }
|