mirror of
https://github.com/GnoConsortium/gno.git
synced 2025-02-16 14:30:25 +00:00
version 1.1 of tee for GNO. Version 1.0 was by another author.
This commit is contained in:
parent
5722e4fa7f
commit
a40ac0f34c
15
bin/tee/README
Normal file
15
bin/tee/README
Normal 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
11
bin/tee/makefile.mk
Normal 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
54
bin/tee/tee.1
Normal 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
10
bin/tee/tee.DESCRIBE
Normal 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
140
bin/tee/tee.c
Normal 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user