comparison toys/tee.c @ 308:52600eee8dd6

Add "tee" command.
author Rob Landley <rob@landley.net>
date Thu, 03 Jul 2008 19:19:00 -0500
parents
children 32c7b6af5b29
comparison
equal deleted inserted replaced
307:937148640ac5 308:52600eee8dd6
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,
55 O_RDWR|O_CREAT|((toys.optflags&1)?O_APPEND:O_TRUNC), do_tee_open);
56
57 for (;;) {
58 struct fd_list *fdl;
59 int len;
60
61 // Read data from stdin
62 len = xread(0, toybuf, sizeof(toybuf));
63 if (len<1) break;
64
65 // Write data to each output file, plus stdout.
66 fdl = TT.outputs;
67 for (;;) {
68 if(len != writeall(fdl ? fdl->fd : 1, toybuf, len)) toys.exitval=1;
69 if (!fdl) break;
70 fdl = fdl->next;
71 }
72 }
73
74 }