Viewing file: tee.c (3.32 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* tee - duplicate standard input */
/* See Makefile for compilation details. */
#include "config.h"
#include "bashtypes.h" #include "posixstat.h" #include "filecntl.h"
#include <signal.h>
#if defined (HAVE_UNISTD_H) # include <unistd.h> #endif
#include "bashansi.h"
#include <stdio.h> #include <errno.h>
#include "builtins.h" #include "shell.h" #include "bashgetopt.h"
#if !defined (errno) extern int errno; #endif
typedef struct flist { struct flist *next; int fd; char *fname; } FLIST;
static FLIST *tee_flist;
#define TEE_BUFSIZE 8192
extern int interrupt_immediately;
extern char *strerror ();
tee_builtin (list) WORD_LIST *list; { int opt, append, nointr, rval, fd, fflags; int n, nr, nw; FLIST *fl; char *buf, *bp;
char *t;
reset_internal_getopt (); append = nointr = 0; tee_flist = (FLIST *)NULL; while ((opt = internal_getopt (list, "ai")) != -1) { switch (opt) { case 'a': append = 1; break; case 'i': nointr = 1; break; default: builtin_usage (); return (EX_USAGE); } } list = loptend;
if (nointr == 0) interrupt_immediately++;
buf = xmalloc (TEE_BUFSIZE);
/* Initialize output file list. */ fl = tee_flist = (FLIST *)xmalloc (sizeof(FLIST)); tee_flist->fd = 1; tee_flist->fname = "stdout"; tee_flist->next = (FLIST *)NULL;
/* Add file arguments to list of output files. */ fflags = append ? O_WRONLY|O_CREAT|O_APPEND : O_WRONLY|O_CREAT|O_TRUNC; for (rval = EXECUTION_SUCCESS; list; list = list->next) { fd = open (list->word->word, fflags, 0666); if (fd < 0) { builtin_error ("%s: cannot open: %s", list->word->word, strerror (errno)); rval = EXECUTION_FAILURE; } else { fl->next = (FLIST *)xmalloc (sizeof(FLIST)); fl->next->fd = fd; fl->next->fname = list->word->word; fl = fl->next; fl->next = (FLIST *)NULL; } }
while ((nr = read(0, buf, TEE_BUFSIZE)) > 0) for (fl = tee_flist; fl; fl = fl->next) { n = nr; bp = buf; do { if ((nw = write (fl->fd, bp, n)) == -1) { builtin_error ("%s: write error: %s", fl->fname, strerror (errno)); rval = EXECUTION_FAILURE; break; } bp += nw; } while (n -= nw); } if (nr < 0) builtin_error ("read error: %s", strerror (errno));
/* Deallocate resources -- this is a builtin command. */ tee_flist = tee_flist->next; /* skip bogus close of stdout */ while (tee_flist) { fl = tee_flist; if (close (fl->fd) < 0) { builtin_error ("%s: close_error: %s", fl->fname, strerror (errno)); rval = EXECUTION_FAILURE; } tee_flist = tee_flist->next; free (fl); } return (rval); }
char *tee_doc[] = { "Copy standard input to standard output, making a copy in each", "filename argument. If the `-a' option is gived, the specified", "files are appended to, otherwise they are overwritten. If the", "`-i' option is supplied, tee ignores interrupts.", (char *)NULL };
struct builtin tee_struct = { "tee", /* builtin name */ tee_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ tee_doc, /* array of long documentation strings. */ "tee [-ai] [file ...]", /* usage synopsis; becomes short_doc */ 0 /* reserved for internal use */ };
|