version 1.1 of tee for GNO. Version 1.0 was by another author.

This commit is contained in:
gdr 1996-01-28 00:53:44 +00:00
parent 5722e4fa7f
commit a40ac0f34c
5 changed files with 230 additions and 0 deletions

15
bin/tee/README Normal file
View File

@ -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
<gdr@myrias.ab.ca>

11
bin/tee/makefile.mk Normal file
View File

@ -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

54
bin/tee/tee.1 Normal file
View File

@ -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.

10
bin/tee/tee.DESCRIBE Normal file
View File

@ -0,0 +1,10 @@
Name: tee
Version: 1.1 (23 Nov 94)
Author: Devin Reade
Contact: <gdr@myrias.ab.ca>
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.

140
bin/tee/tee.c Normal file
View File

@ -0,0 +1,140 @@
/*
* tee - send a copy of stdin to a file as well as stdout.
*
* Version 1.1 by Devin Reade <gdr@myrias.ab.ca>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#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);
}