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:
gdr 1996-09-09 06:12:16 +00:00
parent 4329ce7e29
commit 2f69a2a3db
6 changed files with 85 additions and 61 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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;
}