diff --git a/bin/tee/README b/bin/tee/README index 290052a..b11f138 100644 --- a/bin/tee/README +++ b/bin/tee/README @@ -1,15 +1,29 @@ -tee v1.1 for Gno +tee v1.2 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. +fully buffered output, making it next to useless. This version of tee +has no buffering on stdin/stdout by default, so you see the output as +it's being read. This version 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. +copyright 1987-1994 by Byte Works, Inc. Used with Permission. Devin Reade + +$Id: README,v 1.2 1996/09/03 03:56:05 gdr Exp $ + +Change Log +========== + +v1.0 Designated as the version shipped with GNO v2.0.4 + +v1.1 Rewrite from scratch by Devin Reade. Default changed from + full buffering to no buffering. Added options for multiple + output files, appending and ignoring of SIGINT. + +v1.2 Added -b (line buffering) option. diff --git a/bin/tee/makefile.mk b/bin/tee/makefile.mk index a9c956e..e0014ad 100644 --- a/bin/tee/makefile.mk +++ b/bin/tee/makefile.mk @@ -1,11 +1,29 @@ -# CFLAGS = -w -i -G25 -v -DCHECK_STACK=1 +# +# This makefile is intended for use with dmake(1) +# +# $Id: makefile.mk,v 1.2 1996/09/03 03:56:06 gdr Exp $ +# + +INSTALL = /usr/bin/install +BINDIR = /bin +MANDIR = /man/man1 + +DEFINES = -D_POSIX_SOURCE + +# CFLAGS = -w -i -G25 -v -DCHECK_STACK=1 $(DEFINES) # LDFLAGS = -l/usr/lib/gnulib -l/usr/lib/stack -CFLAGS = -w -i -O -s768 +CFLAGS = -w -i -O -s768 $(DEFINES) LDFLAGS = -l/usr/lib/gnulib -s768 -all: tee +tee: tee.o tee.r + $(CC) $(LDFLAGS) tee.o $(LDLIBS) -o $@ + copyfork tee.r tee -r install: - cp -f tee /bin - cp -f tee.1 /usr/man/man1 + $(INSTALL) -m755 -obin -gsys -d $(BINDIR) $(MANDIR) + $(INSTALL) -m755 -obin -gsys tee $(BINDIR) + $(INSTALL) -m644 -obin -gsys tee.1 $(MANDIR) + +clean clobber: + $(RM) tee.r tee.o tee.root diff --git a/bin/tee/tee.1 b/bin/tee/tee.1 index 29f3e07..57c349a 100644 --- a/bin/tee/tee.1 +++ b/bin/tee/tee.1 @@ -1,10 +1,13 @@ -.TH TEE 1 "Commands and Applications" "23 November 1994" "Version 1.1" +.\" $Id: tee.1,v 1.2 1996/09/03 03:56:06 gdr Exp $ +.\" +.\" .TH TEE 1 "2 September 1996" "Version 1.2" "Commands and Applications" +.TH TEE 1 "Commands and Applications" "2 September 1996" "Version 1.2" .SH NAME tee \- Pipe fitting. .SH SYNOPSIS .B tee [ -.I -ai +.I -aviV ] .I file1 [ @@ -18,18 +21,23 @@ output, making a copy in .IR file1 , .IR file2 , etc. -The standard output is unbuffered, while output to the +The standard output is by default unbuffered, while output to the .IR file s is fully buffered .LP The following options are available: +.RS .IP "\fI-a\fR Append the output to the .IR file s rather than overwriting them. -.br -.IP "\fI-i\fR +.IP \fI-b\fR +Use line buffering on stdin and stdout. By default, there is no buffering +on these two streams. +.IP \fI-i\fR Ignore the SIGINT signal. +.IP \fI-V\fR +Show version and usage information, then exit. .RE .LP The @@ -50,5 +58,4 @@ occurs. 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. +first appeared in Gno v1.x. Version 1.1 and later written by Devin Reade. diff --git a/bin/tee/tee.DESCRIBE b/bin/tee/tee.DESCRIBE index 3653f52..b940614 100644 --- a/bin/tee/tee.DESCRIBE +++ b/bin/tee/tee.DESCRIBE @@ -1,10 +1,10 @@ Name: tee -Version: 1.1 (23 Nov 94) +Version: 1.2 (2 Sep 96) 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. +Tee copies stdin to stdout, by default without buffering. It 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 index 6fe6060..754aeb4 100644 --- a/bin/tee/tee.c +++ b/bin/tee/tee.c @@ -1,13 +1,16 @@ /* * tee - send a copy of stdin to a file as well as stdout. * - * Version 1.1 by Devin Reade + * Version 1.1 and later 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. + * + * $Id: tee.c,v 1.2 1996/09/03 03:56:07 gdr Exp $ */ +#include #include #include #include @@ -16,125 +19,170 @@ #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; \ - } +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 +#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); \ + 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\ +char *versionstr = "version 1.2 by Devin Reade"; +char *usagestr = "[ -abiV ] 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; +int +main(int argc, char **argv) +{ + int c, b_flag; + char *mode, buf; + FILE *fp, *fp2; + extern int optind; - /* initialization */ - STACKSTART; - mode = "w+"; + /* + * initialization + */ + STACKSTART; + mode = "w+"; + b_flag = 0; - /* 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*/ + /* + * parse the command line + */ + while ((c = getopt(argc, argv, "abiV")) != EOF) { + switch (c) { + case 'a': + /* append to instead of truncate output file */ + mode = "a+"; + break; + + case 'b': + /* do line buffering */ + b_flag++; + 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 + */ + if (b_flag) { + /* line buffering */ + int done = 0; + + while (!done) { + c = fread(buf2, sizeof(char), BUFFERSIZE, stdin); + + if (c == 0) { + if (ferror(stdin)) { + fclose(fp); + STACKEND(1); + /* NOTREACHED */ + } + done = 1; } - if ((argc - optind) < 1) USAGE; + fwrite(buf2, sizeof(char), c, stdout); + fwrite(buf2, sizeof(char), c, fp); + } + } else { + /* no buffering */ + int done = 0; - /* 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)) { + while (!done) { + switch (read(STDIN_FILENO, &buf, 1)) { case -1: - fclose(fp); - STACKEND(1); - /*NOTREACHED*/ + fclose(fp); + STACKEND(1); + /* NOTREACHED */ case 0: - done=1; - break; + done = 1; + break; default: - write(STDOUT_FILENO,&buf,1); - fputc(buf,fp); - break; + 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; + /* + * 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); + /* 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); - } + /* 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); - /* 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); - } - } + 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); + } + fclose(fp2); + if (ferror(fp)) { + perror("reading master file"); + fclose(fp); + STACKEND(1); + } + optind++; + } + fclose(fp); + STACKEND(0); } diff --git a/bin/tee/tee.rez b/bin/tee/tee.rez new file mode 100644 index 0000000..4abe892 --- /dev/null +++ b/bin/tee/tee.rez @@ -0,0 +1,18 @@ +/* + * $Id: tee.rez,v 1.1 1996/09/03 03:56:08 gdr Exp $ + */ + +#include "Types.Rez" + +resource rVersion (0x1, purgeable3, nocrossbank) { + + { 1, 2, 0, /* version 1.2.0 */ + release, /* development|alpha|beta|final|release */ + 0 /* non-final release number */ + }, + verBritain, /* close enough */ + "tee", + "pipe fitting\n" + "Devin Reade \n" + "Canada" +};