From seva@p1.f434.n5020.z2.fidonet.org Thu Nov 18 08:02:58 1999
Return-Path: <seva@p1.f434.n5020.z2.fidonet.org>
Received: from f434.n5020.z2.fidonet.org (host5.mtelecom.ru [212.44.147.5])
	by hub.freebsd.org (Postfix) with ESMTP id B2C0E15441
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 18 Nov 1999 08:02:33 -0800 (PST)
	(envelope-from seva@p1.f434.n5020.z2.fidonet.org)
Received: from p1.f434.n5020.z2.fidonet.org (p1 [192.168.44.37])
	by f434.n5020.z2.fidonet.org (8.8.8/8.8.8) with ESMTP id TAA24809
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 18 Nov 1999 19:00:18 +0300 (MSK)
	(envelope-from seva@p1.f434.n5020.z2.fidonet.org)
Received: (from seva@localhost)
	by p1.f434.n5020.z2.fidonet.org (8.9.3/8.9.3) id TAA22164;
	Thu, 18 Nov 1999 19:14:35 +0300 (MSK)
	(envelope-from seva)
Message-Id: <199911181614.TAA22164@p1.f434.n5020.z2.fidonet.org>
Date: Thu, 18 Nov 1999 19:14:35 +0300 (MSK)
From: seva@mtelecom.ru
Sender: seva@p1.f434.n5020.z2.fidonet.org
Reply-To: seva@mtelecom.ru
To: FreeBSD-gnats-submit@freebsd.org
Subject: select/poll handler for fifo is broken in FreeBSD-3.X
X-Send-Pr-Version: 3.2

>Number:         14979
>Category:       kern
>Synopsis:       fifo's select(2)/poll(2) handler is broken in FreeBSD-3.X
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 18 08:10:00 PST 1999
>Closed-Date:    Sat Nov 20 05:15:02 PST 1999
>Last-Modified:  Sat Nov 20 05:17:10 PST 1999
>Originator:     Seva Semenov
>Release:        FreeBSD 3.2-RELEASE i386
>Organization:
Seva's Bedroom
>Environment:

	FreeBSD 3.3 RELEASE and FreeBSD 3.2 RELEASE

>Description:

	when fifo (maden by mkfifo(1)) has select(2)ed or poll(2)ed
	select(2) and poll(2) returns without timeout even
	fifo has no bytes to read.
	
	In FreeBSD 2.X and NetBSD 1.4.1 there is timeout as expected.

>How-To-Repeat:

# mkfifo fifo
# cat readfifo.select.c

#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int
main(int argc,char **argv)
{
	int fd;
	char *fn="fifo";
	
	if(argc>1)
		fn=*(argv+1);
	

	if((fd=open(fn,O_RDONLY|O_NONBLOCK))<0)
		err(errno,"can't open %s",fn);

	for(;;){
		fd_set fds;
		int r;
		struct timeval tv;
		size_t sz;
		char b[64];
	
		tv.tv_sec=5;
		tv.tv_usec=0;
		FD_ZERO(&fds);
		FD_SET(fd,&fds);
		r=select(FD_SETSIZE,&fds,NULL,NULL,&tv);
		if(r<0)
			err(errno,"select return %d ",r);
		if(r==0){
			fputs("timeout\n",stderr);
			continue;
		}
		sz=read(fd,b,63);
		if(sz<0)
			err(errno,"read fifo return %d",sz);
		if(!sz){
			fputs("read null bites\n",stderr);
			continue;
		}
		b[sz]='\0';
		puts(b);
		fflush(stdout);
	}
}

# cat readfifo.poll.c

#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <poll.h>
#include <stdio.h>

int
main(int argc,char **argv)
{
     int fd;
     char *fn="fifo";

     if(argc>1)
	  fn=*(argv+1);

     fd=open(fn,O_RDONLY|O_NONBLOCK);
     if(fd<0)
	  err(errno,"cannot open %s",fn);

     for(;;){
	  struct pollfd pfd;
	  int pr;
	  size_t sz;
	  char b[64];

	  pfd.fd=fd;
	  /*pfd.events=POLLRDNORM;*/
	  pfd.events=POLLIN;
	  pr=poll(&pfd,1,5000);
	  if(pr==-1)
	       err(errno,"error in poll");
	  if(!pr){
	       fputs("timeout\n",stderr);
	       continue;
	  }
	  puts("reading");fflush(stdout);
	  sz=read(fd,b,63);
	  if(sz<0)
	       err(errno,"cannot read");
	  if(!sz){
	       fputs("read null bytes\n",stderr);
	       continue;
	  }
	  b[sz]='\0';
	  puts(b);
	  fflush(stdout);
     }
}

# make readfifo.select
# make readfifo.poll
# ./readfifo.select 


	

>Fix:
	
	I don't know.


>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: seva@mtelecom.ru
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/14979: select/poll handler for fifo is broken in FreeBSD-3.X
Date: Fri, 19 Nov 1999 05:26:42 +1100 (EST)

 > >Description:
 > 
 > 	when fifo (maden by mkfifo(1)) has select(2)ed or poll(2)ed
 > 	select(2) and poll(2) returns without timeout even
 > 	fifo has no bytes to read.
 > 	
 > 	In FreeBSD 2.X and NetBSD 1.4.1 there is timeout as expected.
 
 I think the timeout is unexpected.  read() on a fifo with no writers
 was broken in FreeBSD-2.x.  I fixed this, and the select() and poll()
 behaviour changed automatically to match the read() behaviour.
 
 Some details: POSIX.1 requires read() on a fifo with no writers to
 return 0 without blocking.  FreeBSD-2.x did extra work to break this
 in some cases.  IIRC, the only broken case was for fifos that never
 had a writer.  POSIX doesn't distinguish this case.  Sockets have
 flags to control the behaviour precisely, but these are not available
 for fifos.
 
 select() and poll() return immediately because there is an interesting
 state to read, namely EOF.
 
 At least some versions of Linux and Sunos have special handling for
 select() on fifos.  I think they break select() to do what you want.
 
 Bruce
 
 
State-Changed-From-To: open->closed 
State-Changed-By: bde 
State-Changed-When: Sat Nov 20 05:15:02 PST 1999 
State-Changed-Why:  
The submitter agrees with me the bug is in the bug report. 
>Unformatted:
