From owner-freebsd-bugs@FreeBSD.ORG Fri Jan 21 05:40:16 2005 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 545E916A4CE for ; Fri, 21 Jan 2005 05:40:16 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 17CEB43D2D for ; Fri, 21 Jan 2005 05:40:16 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.1/8.13.1) with ESMTP id j0L5eF11032846 for ; Fri, 21 Jan 2005 05:40:15 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.1/8.13.1/Submit) id j0L5eFI1032845; Fri, 21 Jan 2005 05:40:15 GMT (envelope-from gnats) Resent-Date: Fri, 21 Jan 2005 05:40:15 GMT Resent-Message-Id: <200501210540.j0L5eFI1032845@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Daniel Fuller / Greg Ward Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 37D2216A4CE for ; Fri, 21 Jan 2005 05:32:13 +0000 (GMT) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 09F4743D31 for ; Fri, 21 Jan 2005 05:32:13 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id j0L5WCkI022859 for ; Fri, 21 Jan 2005 05:32:12 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id j0L5WC8r022857; Fri, 21 Jan 2005 05:32:12 GMT (envelope-from nobody) Message-Id: <200501210532.j0L5WC8r022857@www.freebsd.org> Date: Fri, 21 Jan 2005 05:32:12 GMT From: Daniel Fuller / Greg Ward To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Subject: kern/76525: Subsequent calls to select() a FIFO after a previous FIFO EOF causes calling process to hang X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Jan 2005 05:40:16 -0000 >Number: 76525 >Category: kern >Synopsis: Subsequent calls to select() a FIFO after a previous FIFO EOF causes calling process to hang >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Jan 21 05:40:15 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Daniel Fuller / Greg Ward >Release: 5.3 Release >Organization: Berkeley Lab >Environment: FreeBSD render08.lbl.gov 5.3-STABLE FreeBSD 5.3-STABLE #2: Tue Jan 18 15:11:54 PST 2005 root@render08.lbl.gov:/farm/FreeBSD/releases/amd64/RELENG_5/obj/farm/FreeBSD/releases/amd64/RELENG_5/src/sys/SMP amd64 >Description: (Taken from an email by Greg Ward gward@lmi.net) Hi Danny, Well, it only took me 8 hours, but I found the problem with the latest version of [Free]BSD. I tracked down several false leads before I got on the right track -- it's only named FIFO's that seem to exhibit this problem. I depend on them for the -P and -PP option of rtrace, which is needed for memory sharing as I've set it up in Radiance. I don't think named FIFO's are used very often, which might explain why this has gone undetected (or at least unfixed). There are two test programs that demonstrate the problem. The first is called pipe.c, and on OS X, it produces the following (correct) output: pipe available for read Read 4 bytes from pipe: 'TEST' pipe available for read Read 0 bytes from pipe: '' Under FreeBSD 5.3, for some reason I get an exception condition on my pipe every time, which is strange but not fatal: Exception on pipe pipe available for read Read 4 bytes from pipe: 'TEST' Exception on pipe pipe available for read Read 0 bytes from pipe: '' On FreeBSD 4.10, I only get an exception at EOF, which I might expect: pipe available for read Read 4 bytes from pipe: 'TEST' Exception on pipe pipe available for read Read 0 bytes from pipe: '' The real trouble begins with the second FIFO test in fifo.c. Under OS X, I get the correct output: FIFO available for read Read 4 bytes from FIFO: 'TEST' FIFO available for read Read 0 bytes from FIFO: '' Under FreeBSD 4.10, I get exactly the same output -- even the exception condition is gone: FIFO available for read Read 4 bytes from FIFO: 'TEST' FIFO available for read Read 0 bytes from FIFO: '' However, under FreeBSD 5.3-STABLE, the poor thing hangs at the EOF, and select(2) never returns: FIFO available for read Read 4 bytes from FIFO: 'TEST' (process hangs in second call to select) Keep in mind that there should be no difference in the behavior between a named FIFO and a pipe -- the only difference is how they are mechanically connected by the two processes. Having the select() call hang when an EOF condition exists is not acceptable. I hope you can forward this to the appropriate FreeBSD gurus. Thanks, -Greg >How-To-Repeat: source code for test programs described above: /* * Check pipe behavior * * Greg Ward * Compare also fifo.c */ #include #include #include #include #include #include look(int fd) { fd_set readfds, excepfds; FD_ZERO(&readfds); FD_ZERO(&excepfds); FD_SET(fd, &readfds); FD_SET(fd, &excepfds); if (select(fd+1, &readfds, NULL, &excepfds, NULL) < 0) { perror("select"); exit(1); } if (FD_ISSET(fd, &excepfds)) puts("Exception on pipe"); if (FD_ISSET(fd, &readfds)) puts("pipe available for read"); } void spit(int fd) { char buf[512]; int n = read(fd, buf, sizeof(buf)); buf[n] = '\0'; printf("Read %d bytes from pipe: '%s'\n", n, buf); } main() { int pp[2]; pipe(pp); if (fork() == 0) { close(pp[0]); write(pp[1], "TEST", 4); close(pp[1]); _exit(0); } close(pp[1]); look(pp[0]); spit(pp[0]); look(pp[0]); spit(pp[0]); return(0); } ..Next Test Program... /* * Reproduce bug in FreeBSD 5.3-STABLE * * Greg Ward * See also pipe.c for comparison. */ #include #include #include #include #include #include const char FIFO[] = "/tmp/fifo"; void look(int fd) { fd_set readfds, excepfds; FD_ZERO(&readfds); FD_ZERO(&excepfds); FD_SET(fd, &readfds); FD_SET(fd, &excepfds); if (select(fd+1, &readfds, NULL, &excepfds, NULL) < 0) { perror("select"); exit(1); } if (FD_ISSET(fd, &excepfds)) puts("Exception on FIFO"); if (FD_ISSET(fd, &readfds)) puts("FIFO available for read"); } void spit(int fd) { char buf[512]; int n = read(fd, buf, sizeof(buf)); buf[n] = '\0'; printf("Read %d bytes from FIFO: '%s'\n", n, buf); } main() { int fifo_fd; unlink(FIFO); mkfifo(FIFO, 0666); if (fork() == 0) { fifo_fd = open(FIFO, O_WRONLY); write(fifo_fd, "TEST", 4); close(fifo_fd); _exit(0); } fifo_fd = open(FIFO, O_RDONLY); look(fifo_fd); spit(fifo_fd); look(fifo_fd); spit(fifo_fd); return(0); } ..END... >Fix: None known for FreeBSD 5.3X. >Release-Note: >Audit-Trail: >Unformatted: