Path: utzoo!attcan!telly!lethe!torsqnt!jarvis.csri.toronto.edu!mailrus!ames!amdcad!light!bvs From: bvs@light.uucp (Bakul Shah) Newsgroups: comp.bugs.4bsd Subject: Bug in file read/write with forked file-descriptors Message-ID: <1989Sep22.160808.1407@light.uucp> Date: 22 Sep 89 16:08:06 GMT Reply-To: bvs@light.UUCP (Bakul Shah) Organization: - Lines: 52 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 < 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