Bug in file read/write with forked file-descriptors

Bakul Shah bvs at light.uucp
Sat Sep 23 02:08:06 AEST 1989


The attached program fails most of the time on V7, 4.3 BSD & Sun 3
systems; which seems to indicate the bug was inherited from V7.
(SVR3 seems to handle it right -- I haven't tried others).

Upon forking file-descriptors are shared by the parent & child.
But if a shared fd is to a regular file and both read from it at
the same time, they get the *same* data instead of serial pieces
of the file (also, the next few bytes are skipped).  There is a
similar problem with write.  The problem is where fp->f_offset is
updated once read/write is finished.  It should be updated while
the inode is locked.

-- Bakul Shah <..!{ames,sun,ucbvax,uunet}!amdcad!light!bvs>

#! /bin/sh
cat > x.c <<EOF
#include <stdio.h>

extern void * malloc();

main(argc, argv)
	int argc;
	char * * argv;
{
	char * buf;
	int count, f, g;
	unsigned int size;

	/* default to stdin if no argv[1] or it is "-" */
	f = (argc > 1 && strcmp(argv[1], "-")) ? open(argv[1]) : 0;
	if (f < 0) { perror(argv[1]); exit(1); }

	/* default to stdout if no argv[2] or it is "-" */
	g = (argc > 2 && strcmp(argv[2], "-")) ? creat(argv[2], 0666) : 1;
	if (g < 0) { perror(argv[2]); exit(1); }

	/* default to 1 byte buffer if no argv[3] */
	size = argc > 3 ? atoi(argv[3]) : 1;
	buf = (char *)malloc(size);
	if (!buf) { fprintf(stderr, "not enough space\n"); exit(1); }

	fork();
	while ((count = read(f, buf, size)) > 0)
		write(g, buf, count);
}
EOF

cc x.c

# The correct output of a.out will be a permutation of input.
# On a V7 system pipes seem to have the same bug.
a.out x.c



More information about the Comp.bugs.4bsd.ucb-fixes mailing list