mirror of
https://github.com/GnoConsortium/gno.git
synced 2025-01-15 03:29:53 +00:00
Fixed buffered output: full buffering was being done rather than line
buffering. Added program 'testtee' to provide output for testing.
This commit is contained in:
parent
4329ce7e29
commit
2f69a2a3db
@ -15,7 +15,7 @@ copyright 1987-1994 by Byte Works, Inc. Used with Permission.
|
||||
Devin Reade
|
||||
<gdr@myrias.ab.ca>
|
||||
|
||||
$Id: README,v 1.2 1996/09/03 03:56:05 gdr Exp $
|
||||
$Id: README,v 1.3 1996/09/09 06:12:14 gdr Exp $
|
||||
|
||||
Change Log
|
||||
==========
|
||||
@ -26,4 +26,5 @@ 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.
|
||||
v1.2 Added -b (line buffering) option. STDIN_FILENO is no longer
|
||||
directly read; stdio is used.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# This makefile is intended for use with dmake(1)
|
||||
#
|
||||
# $Id: makefile.mk,v 1.2 1996/09/03 03:56:06 gdr Exp $
|
||||
# $Id: makefile.mk,v 1.3 1996/09/09 06:12:15 gdr Exp $
|
||||
#
|
||||
|
||||
INSTALL = /usr/bin/install
|
||||
@ -17,13 +17,18 @@ CFLAGS = -w -i -O -s768 $(DEFINES)
|
||||
LDFLAGS = -l/usr/lib/gnulib -s768
|
||||
|
||||
tee: tee.o tee.r
|
||||
@purge
|
||||
$(CC) $(LDFLAGS) tee.o $(LDLIBS) -o $@
|
||||
copyfork tee.r tee -r
|
||||
|
||||
testtee: testtee.c
|
||||
@purge
|
||||
$(CC) -v -w $< -o $@
|
||||
|
||||
install:
|
||||
$(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
|
||||
$(RM) -f tee.r tee.o tee.root testtee testtee.o testtee.root
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" $Id: tee.1,v 1.2 1996/09/03 03:56:06 gdr Exp $
|
||||
.\" $Id: tee.1,v 1.3 1996/09/09 06:12:15 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"
|
||||
.\" .TH TEE 1 "8 September 1996" "Version 1.2" "Commands and Applications"
|
||||
.TH TEE 1 "Commands and Applications" "8 September 1996" "Version 1.2"
|
||||
.SH NAME
|
||||
tee \- Pipe fitting.
|
||||
.SH SYNOPSIS
|
||||
|
@ -1,5 +1,5 @@
|
||||
Name: tee
|
||||
Version: 1.2 (2 Sep 96)
|
||||
Version: 1.2 (8 Sep 96)
|
||||
Author: Devin Reade
|
||||
Contact: <gdr@myrias.ab.ca>
|
||||
Where: /bin/tee
|
||||
|
@ -4,10 +4,11 @@
|
||||
* Version 1.1 and later 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.
|
||||
* This is a complete re-write which by default uses full buffering
|
||||
* for the output file, but _no_ buffering on stdin and stdout.
|
||||
* This buffering behavior can be changed slightly by the -b flag.
|
||||
*
|
||||
* $Id: tee.c,v 1.2 1996/09/03 03:56:07 gdr Exp $
|
||||
* $Id: tee.c,v 1.3 1996/09/09 06:12:16 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -50,17 +51,19 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int c, b_flag;
|
||||
char *mode, buf;
|
||||
char *mode;
|
||||
FILE *fp, *fp2;
|
||||
int characters;
|
||||
|
||||
extern int optind;
|
||||
|
||||
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
STACKSTART;
|
||||
mode = "w+";
|
||||
b_flag = 0;
|
||||
|
||||
|
||||
/*
|
||||
* parse the command line
|
||||
*/
|
||||
@ -70,17 +73,17 @@ main(int argc, char **argv)
|
||||
/* 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:
|
||||
@ -91,6 +94,7 @@ main(int argc, char **argv)
|
||||
if ((argc - optind) < 1) {
|
||||
USAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
* open the output file
|
||||
*/
|
||||
@ -98,48 +102,29 @@ main(int argc, char **argv)
|
||||
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;
|
||||
}
|
||||
fwrite(buf2, sizeof(char), c, stdout);
|
||||
fwrite(buf2, sizeof(char), c, fp);
|
||||
}
|
||||
setvbuf(stdin, NULL, _IOLBF, 1024);
|
||||
setvbuf(stdout, NULL, _IOLBF, 1024);
|
||||
characters = BUFFERSIZE;
|
||||
} else {
|
||||
/* no buffering */
|
||||
int done = 0;
|
||||
|
||||
while (!done) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
characters = 2; /* a value of 2 gives one character reads */
|
||||
}
|
||||
|
||||
/* poll until EOF seen on input or an error occurs */
|
||||
while (fgets(buf2, characters, stdin) != NULL &&
|
||||
fputs(buf2, stdout) != EOF &&
|
||||
fputs(buf2, fp) != EOF);
|
||||
fflush(fp);
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
* make additional copies if necessary
|
||||
*/
|
||||
@ -150,31 +135,33 @@ main(int argc, char **argv)
|
||||
}
|
||||
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);
|
||||
}
|
||||
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");
|
||||
|
31
bin/tee/testtee.c
Normal file
31
bin/tee/testtee.c
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This is a test for tee(1) buffering. It prints out LINES lines
|
||||
* of DIGITS digits each, sleeping for SLEEP seconds between digits.
|
||||
*
|
||||
* Usage: ./testtee | ./tee [-b]
|
||||
*
|
||||
* $Id: testtee.c,v 1.1 1996/09/09 06:12:16 gdr Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LINES 3 /* number of lines to print */
|
||||
#define DIGITS 4 /* digits per line */
|
||||
#define SLEEP 1 /* seconds to sleep between digits */
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
for (i=0; i<LINES; i++) {
|
||||
for (j=0; j<DIGITS; j++) {
|
||||
printf(" %d", j);
|
||||
sleep(SLEEP);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user