- Added -b flag.

- Added *.rez file.
- Makefile now uses install(1) for installation.
This commit is contained in:
gdr 1996-09-03 03:56:08 +00:00
parent 469a09b80b
commit 8b04cea893
6 changed files with 223 additions and 118 deletions

View File

@ -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 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 fully buffered output, making it next to useless. This version of tee
stdout, so you see the output as it's being read. This one also allows has no buffering on stdin/stdout by default, so you see the output as
multiple output files, appending, and ignoring of SIGINT. 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 To install copy tee to /bin and tee.1 to /usr/man/man1, or just type
"dmake install". "dmake install".
This program contains material from the Orca/C Run-Time Libraries, 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 Devin Reade
<gdr@myrias.ab.ca> <gdr@myrias.ab.ca>
$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.

View File

@ -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 # 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 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: install:
cp -f tee /bin $(INSTALL) -m755 -obin -gsys -d $(BINDIR) $(MANDIR)
cp -f tee.1 /usr/man/man1 $(INSTALL) -m755 -obin -gsys tee $(BINDIR)
$(INSTALL) -m644 -obin -gsys tee.1 $(MANDIR)
clean clobber:
$(RM) tee.r tee.o tee.root

View File

@ -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 .SH NAME
tee \- Pipe fitting. tee \- Pipe fitting.
.SH SYNOPSIS .SH SYNOPSIS
.B tee .B tee
[ [
.I -ai .I -aviV
] ]
.I file1 .I file1
[ [
@ -18,18 +21,23 @@ output, making a copy in
.IR file1 , .IR file1 ,
.IR file2 , .IR file2 ,
etc. etc.
The standard output is unbuffered, while output to the The standard output is by default unbuffered, while output to the
.IR file s .IR file s
is fully buffered is fully buffered
.LP .LP
The following options are available: The following options are available:
.RS
.IP "\fI-a\fR .IP "\fI-a\fR
Append the output to the Append the output to the
.IR file s .IR file s
rather than overwriting them. rather than overwriting them.
.br .IP \fI-b\fR
.IP "\fI-i\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. Ignore the SIGINT signal.
.IP \fI-V\fR
Show version and usage information, then exit.
.RE .RE
.LP .LP
The The
@ -50,5 +58,4 @@ occurs.
is POSIX p1003.2 compatible. is POSIX p1003.2 compatible.
.SH HISTORY .SH HISTORY
.B Tee .B Tee
first appeared in Gno v1.x. Version 1.1 updated by Devin Reade first appeared in Gno v1.x. Version 1.1 and later written by Devin Reade.
to use proper (non) buffering.

View File

@ -1,10 +1,10 @@
Name: tee Name: tee
Version: 1.1 (23 Nov 94) Version: 1.2 (2 Sep 96)
Author: Devin Reade Author: Devin Reade
Contact: <gdr@myrias.ab.ca> Contact: <gdr@myrias.ab.ca>
Where: /bin/tee Where: /bin/tee
FTP: cco.caltech.edu, grind.isca.uiowa.edu. FTP: cco.caltech.edu, grind.isca.uiowa.edu.
Tee copies stdin to stdout without buffering and also makes a copy Tee copies stdin to stdout, by default without buffering. It also makes
of the data to a specified file(s). It is useful when you want to watch a copy of the data to a specified file(s). It is useful when you want to
the output of a process, but also save it. watch the output of a process, but also save it.

View File

@ -1,13 +1,16 @@
/* /*
* tee - send a copy of stdin to a file as well as stdout. * tee - send a copy of stdin to a file as well as stdout.
* *
* Version 1.1 by Devin Reade <gdr@myrias.ab.ca> * Version 1.1 and later by Devin Reade <gdr@myrias.ab.ca>
* *
* tee originally appeared with Gno v1.x, but was fully buffered. * tee originally appeared with Gno v1.x, but was fully buffered.
* This is a complete re-write which uses full buffering for the * This is a complete re-write which uses full buffering for the
* output file, but _no_ buffering on stdin and stdout. * output file, but _no_ buffering on stdin and stdout.
*
* $Id: tee.c,v 1.2 1996/09/03 03:56:07 gdr Exp $
*/ */
#include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
@ -16,125 +19,170 @@
#include "getopt.h" #include "getopt.h"
#ifdef CHECK_STACK #ifdef CHECK_STACK
void begin_stack_check(void); void begin_stack_check(void);
int end_stack_check(void); int end_stack_check(void);
# define STACKSTART begin_stack_check()
# define STACKEND(n) { \ #define STACKSTART begin_stack_check()
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check()); \ #define STACKEND(n) { \
return n; \ fprintf(stderr,"stack usage: %d bytes\n",end_stack_check()); \
} return n; \
}
#else #else
# define STACKSTART #define STACKSTART
# define STACKEND(n) return n #define STACKEND(n) return n
#endif #endif
#define BUFFERSIZE 512 #define BUFFERSIZE 512
#define USAGE { \ #define USAGE { \
fprintf(stderr,"%s %s\nUsage:\t%s %s\n",argv[0],versionstr,argv[0], \ fprintf(stderr,"%s %s\nUsage:\t%s %s\n",argv[0],versionstr,argv[0], \
usagestr); \ usagestr); \
STACKEND(-1); \ STACKEND(-1); \
} }
char *versionstr="version 1.1 by Devin Reade"; char *versionstr = "version 1.2 by Devin Reade";
char *usagestr="[ -ai ] filename\n\ char *usagestr = "[ -abiV ] filename\n\
\t-a\tappend to filename\n\ \t-a\tappend to filename\n\
\t-i\tignore SIGINT\n"; \t-i\tignore SIGINT\n";
char buf2[BUFFERSIZE]; char buf2[BUFFERSIZE];
int main (int argc, char **argv) { int
int c; main(int argc, char **argv)
char *mode, buf; {
FILE *fp, *fp2; int c, b_flag;
extern int optind; char *mode, buf;
FILE *fp, *fp2;
extern int optind;
/* initialization */ /*
STACKSTART; * initialization
mode = "w+"; */
STACKSTART;
mode = "w+";
b_flag = 0;
/* parse the command line */ /*
while ((c = getopt(argc, argv, "aiV")) != EOF) * parse the command line
switch (c) { */
case 'a': while ((c = getopt(argc, argv, "abiV")) != EOF) {
/* append to instead of truncate output file*/ switch (c) {
mode = "a+"; case 'a':
break; /* append to instead of truncate output file */
case 'i': mode = "a+";
/* ignore SIGINT */ break;
signal(SIGINT,SIG_IGN);
break; case 'b':
case 'V': /*FALLTHROUGH*/ /* do line buffering */
default: b_flag++;
USAGE; break;
/*NOTREACHED*/
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 */ while (!done) {
if ((fp = fopen(argv[optind],mode)) == NULL) { switch (read(STDIN_FILENO, &buf, 1)) {
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: case -1:
fclose(fp); fclose(fp);
STACKEND(1); STACKEND(1);
/*NOTREACHED*/ /* NOTREACHED */
case 0: case 0:
done=1; done = 1;
break; break;
default: default:
write(STDOUT_FILENO,&buf,1); write(STDOUT_FILENO, &buf, 1);
fputc(buf,fp); fputc(buf, fp);
break; break;
} }
if (done) break; }
} }
/* make additional copies if necessary */ /*
optind++; * make additional copies if necessary
if (argc<=optind) { */
fclose(fp); optind++;
STACKEND(0); if (argc <= optind) {
} fclose(fp);
while (argc>optind) { STACKEND(0);
size_t count; }
while (argc > optind) {
size_t count;
/* rewind the master file */ /* rewind the master file */
rewind(fp); rewind(fp);
/* open the new file */ /* open the new file */
if ((fp2 = fopen(argv[optind],mode)) == NULL) { if ((fp2 = fopen(argv[optind], mode)) == NULL) {
perror("opening duplicate file"); perror("opening duplicate file");
fclose(fp); fclose(fp);
STACKEND(1); STACKEND(1);
} }
/* make the copy */
while (!feof(fp) && !(ferror(fp))) {
count = fread(buf2, sizeof(char), BUFFERSIZE, fp);
/* make the copy */ if (count > 0) {
while (!feof(fp) && !(ferror(fp))) { fwrite(buf2, sizeof(char), count, fp2);
count = fread(buf2,sizeof(char),BUFFERSIZE,fp);
if (count>0) { if (ferror(fp2)) {
fwrite(buf2,sizeof(char),count,fp2); perror("writing duplicate file");
if (ferror(fp2)) { fclose(fp);
perror("writing duplicate file"); fclose(fp2);
fclose(fp); STACKEND(1);
fclose(fp2); }
STACKEND(1);
}
}
} }
fclose(fp2); }
if (ferror(fp)) { fclose(fp2);
perror("reading master file"); if (ferror(fp)) {
fclose(fp); perror("reading master file");
STACKEND(1); fclose(fp);
} STACKEND(1);
optind++; }
} optind++;
fclose(fp); }
STACKEND(0); fclose(fp);
STACKEND(0);
} }

18
bin/tee/tee.rez Normal file
View File

@ -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 <gdr@myrias.com>\n"
"Canada"
};