1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
/* vi: set sw=4 ts=4:
*
* 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_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;
)
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 & FLAG_i) signal(SIGINT, SIG_IGN);
// Open output files
loopfiles_rw(toys.optargs,
O_RDWR|O_CREAT|((toys.optflags & FLAG_a)?O_APPEND:O_TRUNC),
0666, 0, 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;
}
}
}
|