source: vendor/bash/3.1-p17/examples/loadables/tee.c

Last change on this file was 3231, checked in by bird, 18 years ago

eol style.

  • Property svn:eol-style set to native
File size: 3.3 KB
Line 
1/* tee - duplicate standard input */
2
3/* See Makefile for compilation details. */
4
5#include "config.h"
6
7#include "bashtypes.h"
8#include "posixstat.h"
9#include "filecntl.h"
10
11#include <signal.h>
12
13#if defined (HAVE_UNISTD_H)
14# include <unistd.h>
15#endif
16
17#include "bashansi.h"
18
19#include <stdio.h>
20#include <errno.h>
21
22#include "builtins.h"
23#include "shell.h"
24#include "bashgetopt.h"
25
26#if !defined (errno)
27extern int errno;
28#endif
29
30typedef struct flist {
31 struct flist *next;
32 int fd;
33 char *fname;
34} FLIST;
35
36static FLIST *tee_flist;
37
38#define TEE_BUFSIZE 8192
39
40extern int interrupt_immediately;
41
42extern char *strerror ();
43
44tee_builtin (list)
45 WORD_LIST *list;
46{
47 int opt, append, nointr, rval, fd, fflags;
48 int n, nr, nw;
49 FLIST *fl;
50 char *buf, *bp;
51
52 char *t;
53
54 reset_internal_getopt ();
55 append = nointr = 0;
56 tee_flist = (FLIST *)NULL;
57 while ((opt = internal_getopt (list, "ai")) != -1)
58 {
59 switch (opt)
60 {
61 case 'a':
62 append = 1;
63 break;
64 case 'i':
65 nointr = 1;
66 break;
67 default:
68 builtin_usage ();
69 return (EX_USAGE);
70 }
71 }
72 list = loptend;
73
74 if (nointr == 0)
75 interrupt_immediately++;
76
77 buf = xmalloc (TEE_BUFSIZE);
78
79 /* Initialize output file list. */
80 fl = tee_flist = (FLIST *)xmalloc (sizeof(FLIST));
81 tee_flist->fd = 1;
82 tee_flist->fname = "stdout";
83 tee_flist->next = (FLIST *)NULL;
84
85 /* Add file arguments to list of output files. */
86 fflags = append ? O_WRONLY|O_CREAT|O_APPEND : O_WRONLY|O_CREAT|O_TRUNC;
87 for (rval = EXECUTION_SUCCESS; list; list = list->next)
88 {
89 fd = open (list->word->word, fflags, 0666);
90 if (fd < 0)
91 {
92 builtin_error ("%s: cannot open: %s", list->word->word, strerror (errno));
93 rval = EXECUTION_FAILURE;
94 }
95 else
96 {
97 fl->next = (FLIST *)xmalloc (sizeof(FLIST));
98 fl->next->fd = fd;
99 fl->next->fname = list->word->word;
100 fl = fl->next;
101 fl->next = (FLIST *)NULL;
102 }
103 }
104
105 while ((nr = read(0, buf, TEE_BUFSIZE)) > 0)
106 for (fl = tee_flist; fl; fl = fl->next)
107 {
108 n = nr;
109 bp = buf;
110 do
111 {
112 if ((nw = write (fl->fd, bp, n)) == -1)
113 {
114 builtin_error ("%s: write error: %s", fl->fname, strerror (errno));
115 rval = EXECUTION_FAILURE;
116 break;
117 }
118 bp += nw;
119 }
120 while (n -= nw);
121 }
122 if (nr < 0)
123 builtin_error ("read error: %s", strerror (errno));
124
125 /* Deallocate resources -- this is a builtin command. */
126 tee_flist = tee_flist->next; /* skip bogus close of stdout */
127 while (tee_flist)
128 {
129 fl = tee_flist;
130 if (close (fl->fd) < 0)
131 {
132 builtin_error ("%s: close_error: %s", fl->fname, strerror (errno));
133 rval = EXECUTION_FAILURE;
134 }
135 tee_flist = tee_flist->next;
136 free (fl);
137 }
138
139 return (rval);
140}
141
142char *tee_doc[] = {
143 "Copy standard input to standard output, making a copy in each",
144 "filename argument. If the `-a' option is gived, the specified",
145 "files are appended to, otherwise they are overwritten. If the",
146 "`-i' option is supplied, tee ignores interrupts.",
147 (char *)NULL
148};
149
150struct builtin tee_struct = {
151 "tee", /* builtin name */
152 tee_builtin, /* function implementing the builtin */
153 BUILTIN_ENABLED, /* initial flags for builtin */
154 tee_doc, /* array of long documentation strings. */
155 "tee [-ai] [file ...]", /* usage synopsis; becomes short_doc */
156 0 /* reserved for internal use */
157};
Note: See TracBrowser for help on using the repository browser.