308
|
1 /* vi: set sw=4 ts=4:
|
|
2 *
|
|
3 * tee.c - cat to multiple outputs.
|
|
4 *
|
|
5 * Copyright 2008 Rob Landley <rob@landley.net>
|
|
6 *
|
|
7 * See http://www.opengroup.org/onlinepubs/009695399/utilities/tee.html
|
|
8
|
|
9 USE_TEE(NEWTOY(tee, "ia", TOYFLAG_BIN))
|
|
10
|
|
11 config TEE
|
|
12 bool "tee"
|
|
13 default y
|
|
14 help
|
|
15 usage: tee [-ai] [file...]
|
|
16
|
|
17 Copy stdin to each listed file, and also to stdout.
|
|
18 Filename "-" is a synonym for stdout.
|
|
19
|
|
20 -a append to files.
|
|
21 -i ignore SIGINT.
|
|
22 */
|
|
23
|
|
24 #include "toys.h"
|
|
25
|
|
26 DEFINE_GLOBALS(
|
|
27 void *outputs;
|
|
28 )
|
|
29
|
|
30 #define TT this.tee
|
|
31
|
|
32 struct fd_list {
|
|
33 struct fd_list *next;
|
|
34 int fd;
|
|
35 };
|
|
36
|
|
37 // Open each output file, saving filehandles to a linked list.
|
|
38
|
|
39 static void do_tee_open(int fd, char *name)
|
|
40 {
|
|
41 struct fd_list *temp;
|
|
42
|
|
43 temp = xmalloc(sizeof(struct fd_list));
|
|
44 temp->next = TT.outputs;
|
|
45 temp->fd = fd;
|
|
46 TT.outputs = temp;
|
|
47 }
|
|
48
|
|
49 void tee_main(void)
|
|
50 {
|
|
51 if (toys.optflags&2) signal(SIGINT, SIG_IGN);
|
|
52
|
|
53 // Open output files
|
|
54 loopfiles_rw(toys.optargs,
|
395
|
55 O_RDWR|O_CREAT|((toys.optflags&1)?O_APPEND:O_TRUNC), 0666, 0,
|
|
56 do_tee_open);
|
308
|
57
|
|
58 for (;;) {
|
|
59 struct fd_list *fdl;
|
|
60 int len;
|
|
61
|
|
62 // Read data from stdin
|
|
63 len = xread(0, toybuf, sizeof(toybuf));
|
|
64 if (len<1) break;
|
|
65
|
|
66 // Write data to each output file, plus stdout.
|
|
67 fdl = TT.outputs;
|
|
68 for (;;) {
|
|
69 if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1;
|
|
70 if (!fdl) break;
|
|
71 fdl = fdl->next;
|
|
72 }
|
|
73 }
|
|
74
|
|
75 }
|