From owner-freebsd-bugs@FreeBSD.ORG Sun Sep 30 21:20:04 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EA44D16A421 for ; Sun, 30 Sep 2007 21:20:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id AFFAC13C45D for ; Sun, 30 Sep 2007 21:20:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l8ULK3nP009695 for ; Sun, 30 Sep 2007 21:20:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l8ULK38f009694; Sun, 30 Sep 2007 21:20:03 GMT (envelope-from gnats) Resent-Date: Sun, 30 Sep 2007 21:20:03 GMT Resent-Message-Id: <200709302120.l8ULK38f009694@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, Bo Lindbergh Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 78DCE16A418 for ; Sun, 30 Sep 2007 21:17:01 +0000 (UTC) (envelope-from blgl@stacken.kth.se) Received: from brev.stacken.kth.se (brev.stacken.kth.se [130.237.234.84]) by mx1.freebsd.org (Postfix) with ESMTP id DD09013C447 for ; Sun, 30 Sep 2007 21:17:00 +0000 (UTC) (envelope-from blgl@stacken.kth.se) Received: from igloo.stacken.kth.se (igloo.stacken.kth.se [130.237.234.40]) by brev.stacken.kth.se (8.12.10/8.12.10) with ESMTP id l8UKtQhe015378 for ; Sun, 30 Sep 2007 22:55:26 +0200 (MET DST) Received: from igloo.stacken.kth.se (localhost [127.0.0.1]) by igloo.stacken.kth.se (8.13.3/8.13.3) with ESMTP id l8UKtQnb071625 for ; Sun, 30 Sep 2007 22:55:26 +0200 (CEST) (envelope-from blgl@igloo.stacken.kth.se) Received: (from blgl@localhost) by igloo.stacken.kth.se (8.13.3/8.13.3/Submit) id l8UKtOUQ071624; Sun, 30 Sep 2007 22:55:24 +0200 (CEST) (envelope-from blgl) Message-Id: <200709302055.l8UKtOUQ071624@igloo.stacken.kth.se> Date: Sun, 30 Sep 2007 22:55:24 +0200 (CEST) From: Bo Lindbergh To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/116770: Unfortunate fifo/O_NONBLOCK/kevent interaction X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Sep 2007 21:20:04 -0000 >Number: 116770 >Category: kern >Synopsis: Unfortunate fifo/O_NONBLOCK/kevent interaction >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Sep 30 21:20:03 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Bo Lindbergh >Release: FreeBSD 5.4-RELEASE-p6 i386 >Organization: >Environment: System: FreeBSD igloo.stacken.kth.se 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #1: Thu Jul 28 19:42:42 CEST 2005 root@igloo.stacken.kth.se:/usr/obj/usr/src/sys/IGLOO i386 >Description: When a fifo with no writers is opened nonblockingly for reading and the resulting file descriptor is added to a kqueue, kevent will immediately report an EOF condition. This is less than useful. The useful behaviour would be for kevent not to report EOF until at least one writer has come and gone. This matches how similar mechanisms in other operating systems work (e.g. epoll in Linux, /dev/poll in Solaris). >How-To-Repeat: #include #include #include #include #include #include #include int main(void) { int rfd,wfd,qfd,n; static struct timespec zero; struct kevent kev; char fifopath[64]; sprintf(fifopath,"/tmp/less-than-useful.%ld",(long)getpid()); if (mkfifo(fifopath,S_IRUSR|S_IWUSR)==-1) { perror("mkfifo"); return 1; } rfd=open(fifopath,O_RDONLY|O_NONBLOCK); if (rfd==-1) { perror("open 1"); goto cleanup; } qfd=kqueue(); if (qfd==-1) { perror("kqueue"); goto cleanup; } EV_SET(&kev,rfd,EVFILT_READ,EV_ADD,0,0,NULL); n=kevent(qfd,&kev,1,NULL,0,&zero); if (n==-1) { perror("kevent 1"); goto cleanup; } n=kevent(qfd,NULL,0,&kev,1,&zero); if (n==-1) { perror("kevent 2"); goto cleanup; } if (n==1 && (kev.flags & EV_EOF)) { fputs("Immediate EOF (not useful)\n",stderr); } wfd=open(fifopath,O_WRONLY); if (wfd==-1) { perror("open 2"); goto cleanup; } n=kevent(qfd,NULL,0,&kev,1,&zero); if (n==-1) { perror("kevent 3"); goto cleanup; } if (n==1 && (kev.flags & EV_EOF)) { fputs("EOF while there's still a writer (BUG!)\n",stderr); } close(wfd); n=kevent(qfd,NULL,0,&kev,1,&zero); if (n==-1) { perror("kevent 4"); goto cleanup; } if (n==1 && (kev.flags & EV_EOF)) { fputs("EOF after the last writer went away (useful)\n",stderr); } close(qfd); close(rfd); unlink(fifopath); return 0; cleanup: unlink(fifopath); return 1; } >Fix: Don't CANTRCVMORE the socketpair immediately after creating it. Add code to fifo_read_f to avoid calling soreceive blockingly when there are zero writers. Or just add a fi_seen_at_least_one_writer flag to struct fifoinfo... >Release-Note: >Audit-Trail: >Unformatted: