OSDN Git Service

Evgenii Stepanov found a bug where argv0len was set wrong for threads
[android-x86/external-toybox.git] / toys / posix / tee.c
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
7 USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
8
9 config 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
25 GLOBALS(
26   void *outputs;
27 )
28
29 struct fd_list {
30   struct fd_list *next;
31   int fd;
32 };
33
34 // Open each output file, saving filehandles to a linked list.
35
36 static 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
46 void tee_main(void)
47 {
48   if (toys.optflags & FLAG_i) xsignal(SIGINT, SIG_IGN);
49
50   // Open output files
51   loopfiles_rw(toys.optargs,
52     O_RDWR|O_CREAT|WARN_ONLY|((toys.optflags & 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 }