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