From a40ac0f34cc0611cdeb04a8b6d9201c23c358b9c Mon Sep 17 00:00:00 2001 From: gdr Date: Sun, 28 Jan 1996 00:53:44 +0000 Subject: [PATCH] version 1.1 of tee for GNO. Version 1.0 was by another author. --- bin/tee/README | 15 +++++ bin/tee/makefile.mk | 11 ++++ bin/tee/tee.1 | 54 +++++++++++++++++ bin/tee/tee.DESCRIBE | 10 ++++ bin/tee/tee.c | 140 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 bin/tee/README create mode 100644 bin/tee/makefile.mk create mode 100644 bin/tee/tee.1 create mode 100644 bin/tee/tee.DESCRIBE create mode 100644 bin/tee/tee.c diff --git a/bin/tee/README b/bin/tee/README new file mode 100644 index 0000000..290052a --- /dev/null +++ b/bin/tee/README @@ -0,0 +1,15 @@ +tee v1.1 for Gno + +The tee that ships with Gno (and hereforth designated v1.0) seems to have +buffered output, making it next to useless. This one has no buffering on +stdout, so you see the output as it's being read. This one also allows +multiple output files, appending, and ignoring of SIGINT. + +To install copy tee to /bin and tee.1 to /usr/man/man1, or just type +"dmake install". + +This program contains material from the Orca/C Run-Time Libraries, +copyright 198701994 by Byte Works, Inc. Used with Permission. + +Devin Reade + diff --git a/bin/tee/makefile.mk b/bin/tee/makefile.mk new file mode 100644 index 0000000..a9c956e --- /dev/null +++ b/bin/tee/makefile.mk @@ -0,0 +1,11 @@ +# CFLAGS = -w -i -G25 -v -DCHECK_STACK=1 +# LDFLAGS = -l/usr/lib/gnulib -l/usr/lib/stack + +CFLAGS = -w -i -O -s768 +LDFLAGS = -l/usr/lib/gnulib -s768 + +all: tee + +install: + cp -f tee /bin + cp -f tee.1 /usr/man/man1 diff --git a/bin/tee/tee.1 b/bin/tee/tee.1 new file mode 100644 index 0000000..29f3e07 --- /dev/null +++ b/bin/tee/tee.1 @@ -0,0 +1,54 @@ +.TH TEE 1 "Commands and Applications" "23 November 1994" "Version 1.1" +.SH NAME +tee \- Pipe fitting. +.SH SYNOPSIS +.B tee +[ +.I -ai +] +.I file1 +[ +.IR file2 ... +] +.SH DESCRIPTION +The +.B tee +utility copies standard input to standard +output, making a copy in +.IR file1 , +.IR file2 , +etc. +The standard output is unbuffered, while output to the +.IR file s +is fully buffered +.LP +The following options are available: +.IP "\fI-a\fR +Append the output to the +.IR file s +rather than overwriting them. +.br +.IP "\fI-i\fR +Ignore the SIGINT signal. +.RE +.LP +The +.B tee +utility takes the default action for all +signals, except in the event of the +.I -i +option. +.LP +If an error occurs while reading stdin, only the first specified +.I file +will contain the output up to that point. +.LP +The return value is 0 on success, and 1 if an error +occurs. +.SH STANDARDS +.B Tee +is POSIX p1003.2 compatible. +.SH HISTORY +.B Tee +first appeared in Gno v1.x. Version 1.1 updated by Devin Reade +to use proper (non) buffering. diff --git a/bin/tee/tee.DESCRIBE b/bin/tee/tee.DESCRIBE new file mode 100644 index 0000000..3653f52 --- /dev/null +++ b/bin/tee/tee.DESCRIBE @@ -0,0 +1,10 @@ +Name: tee +Version: 1.1 (23 Nov 94) +Author: Devin Reade +Contact: +Where: /bin/tee +FTP: cco.caltech.edu, grind.isca.uiowa.edu. + +Tee copies stdin to stdout without buffering and also makes a copy +of the data to a specified file(s). It is useful when you want to watch +the output of a process, but also save it. diff --git a/bin/tee/tee.c b/bin/tee/tee.c new file mode 100644 index 0000000..6fe6060 --- /dev/null +++ b/bin/tee/tee.c @@ -0,0 +1,140 @@ +/* + * tee - send a copy of stdin to a file as well as stdout. + * + * Version 1.1 by Devin Reade + * + * tee originally appeared with Gno v1.x, but was fully buffered. + * This is a complete re-write which uses full buffering for the + * output file, but _no_ buffering on stdin and stdout. + */ + +#include +#include +#include +#include +#include +#include "getopt.h" + +#ifdef CHECK_STACK + void begin_stack_check(void); + int end_stack_check(void); +# define STACKSTART begin_stack_check() +# define STACKEND(n) { \ + fprintf(stderr,"stack usage: %d bytes\n",end_stack_check()); \ + return n; \ + } +#else +# define STACKSTART +# define STACKEND(n) return n +#endif + +#define BUFFERSIZE 512 +#define USAGE { \ + fprintf(stderr,"%s %s\nUsage:\t%s %s\n",argv[0],versionstr,argv[0], \ + usagestr); \ + STACKEND(-1); \ +} + +char *versionstr="version 1.1 by Devin Reade"; +char *usagestr="[ -ai ] filename\n\ +\t-a\tappend to filename\n\ +\t-i\tignore SIGINT\n"; + +char buf2[BUFFERSIZE]; + +int main (int argc, char **argv) { + int c; + char *mode, buf; + FILE *fp, *fp2; + extern int optind; + + /* initialization */ + STACKSTART; + mode = "w+"; + + /* parse the command line */ + while ((c = getopt(argc, argv, "aiV")) != EOF) + switch (c) { + case 'a': + /* append to instead of truncate output file*/ + mode = "a+"; + break; + case 'i': + /* ignore SIGINT */ + signal(SIGINT,SIG_IGN); + break; + case 'V': /*FALLTHROUGH*/ + default: + USAGE; + /*NOTREACHED*/ + } + if ((argc - optind) < 1) USAGE; + + /* open the output file */ + if ((fp = fopen(argv[optind],mode)) == NULL) { + perror("opening master file"); + STACKEND(1); + } + + /* loop until done with the first file */ + for(;;) { + int done = 0; + switch (read(STDIN_FILENO,&buf,1)) { + case -1: + fclose(fp); + STACKEND(1); + /*NOTREACHED*/ + case 0: + done=1; + break; + default: + write(STDOUT_FILENO,&buf,1); + fputc(buf,fp); + break; + } + if (done) break; + } + + /* make additional copies if necessary */ + optind++; + if (argc<=optind) { + fclose(fp); + STACKEND(0); + } + while (argc>optind) { + size_t count; + + /* rewind the master file */ + rewind(fp); + + /* open the new file */ + if ((fp2 = fopen(argv[optind],mode)) == NULL) { + perror("opening duplicate file"); + fclose(fp); + STACKEND(1); + } + + /* make the copy */ + while (!feof(fp) && !(ferror(fp))) { + count = fread(buf2,sizeof(char),BUFFERSIZE,fp); + if (count>0) { + fwrite(buf2,sizeof(char),count,fp2); + if (ferror(fp2)) { + perror("writing duplicate file"); + fclose(fp); + fclose(fp2); + STACKEND(1); + } + } + } + fclose(fp2); + if (ferror(fp)) { + perror("reading master file"); + fclose(fp); + STACKEND(1); + } + optind++; + } + fclose(fp); + STACKEND(0); +}