]>
git.ipfire.org Git - thirdparty/bash.git/blob - examples/loadables/tee.c
1 /* tee - duplicate standard input */
3 /* See Makefile for compilation details. */
6 Copyright (C) 1999-2009 Free Software Foundation, Inc.
8 This file is part of GNU Bash.
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
25 #include "bashtypes.h"
26 #include "posixstat.h"
31 #if defined (HAVE_UNISTD_H)
42 #include "bashgetopt.h"
49 typedef struct flist
{
55 static FLIST
*tee_flist
;
57 #define TEE_BUFSIZE 8192
59 extern int interrupt_immediately
;
61 extern char *strerror ();
67 int opt
, append
, nointr
, rval
, fd
, fflags
;
74 reset_internal_getopt ();
76 tee_flist
= (FLIST
*)NULL
;
77 while ((opt
= internal_getopt (list
, "ai")) != -1)
96 interrupt_immediately
++;
98 buf
= xmalloc (TEE_BUFSIZE
);
100 /* Initialize output file list. */
101 fl
= tee_flist
= (FLIST
*)xmalloc (sizeof(FLIST
));
103 tee_flist
->fname
= "stdout";
104 tee_flist
->next
= (FLIST
*)NULL
;
106 /* Add file arguments to list of output files. */
107 fflags
= append
? O_WRONLY
|O_CREAT
|O_APPEND
: O_WRONLY
|O_CREAT
|O_TRUNC
;
108 for (rval
= EXECUTION_SUCCESS
; list
; list
= list
->next
)
110 fd
= open (list
->word
->word
, fflags
, 0666);
113 builtin_error ("%s: cannot open: %s", list
->word
->word
, strerror (errno
));
114 rval
= EXECUTION_FAILURE
;
118 fl
->next
= (FLIST
*)xmalloc (sizeof(FLIST
));
120 fl
->next
->fname
= list
->word
->word
;
122 fl
->next
= (FLIST
*)NULL
;
126 while ((nr
= read(0, buf
, TEE_BUFSIZE
)) > 0)
127 for (fl
= tee_flist
; fl
; fl
= fl
->next
)
133 if ((nw
= write (fl
->fd
, bp
, n
)) == -1)
135 builtin_error ("%s: write error: %s", fl
->fname
, strerror (errno
));
136 rval
= EXECUTION_FAILURE
;
144 builtin_error ("read error: %s", strerror (errno
));
146 /* Deallocate resources -- this is a builtin command. */
147 tee_flist
= tee_flist
->next
; /* skip bogus close of stdout */
151 if (close (fl
->fd
) < 0)
153 builtin_error ("%s: close_error: %s", fl
->fname
, strerror (errno
));
154 rval
= EXECUTION_FAILURE
;
156 tee_flist
= tee_flist
->next
;
164 "Duplicate standard output.",
166 "Copy standard input to standard output, making a copy in each",
167 "filename argument. If the `-a' option is given, the specified",
168 "files are appended to, otherwise they are overwritten. If the",
169 "`-i' option is supplied, tee ignores interrupts.",
173 struct builtin tee_struct
= {
174 "tee", /* builtin name */
175 tee_builtin
, /* function implementing the builtin */
176 BUILTIN_ENABLED
, /* initial flags for builtin */
177 tee_doc
, /* array of long documentation strings. */
178 "tee [-ai] [file ...]", /* usage synopsis; becomes short_doc */
179 0 /* reserved for internal use */