Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2002 10:42:30 +0100
From:      clemensF <ino-e31cbe40@spotteswoode.dnsalias.org>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/34020: poll(2) on fifos is broken
Message-ID:  <20020118094230.GA968@spotteswoode.dnsalias.org>

next in thread | raw e-mail | index | archive | help

>Number:         34020
>Category:       kern
>Synopsis:       programs fail that poll(2) on fifos
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jan 18 01:50:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Tip Chap
>Release:        FreeBSD 4.3-RELEASE i386
>Organization:
no
>Environment:
>Description:

the programs below are meant to communicate a state change to multiple
processes.  the original idea is from paul jarc.  several variants of the
waiters were tested (selecting, blocking, polling).

what's needed is this:  readers on a fifo are supposed to wait until some
writer opens it.  this could be a portable, light-weight way of event-
notification, where an unspecified number of readers can be realiably
signalled, not loosing any signals even when they are not yet ready to
receive them.

it works in linux and openbsd.  POSIX doesn't specify the situation (nobody
does).  the only alternative would be heavy machinery using SYSV-IPC or
unix- signals, that would also put unbearable load on the system.

>How-To-Repeat:

0 p1 root #./pipe-wait pipe & ./pipe-wait pipe & ./pipe-wait pipe &
[1] 16768
[2] 16769
[3] 16770
[1]  16768 Running                 ./pipe-wait pipe &
[2]- 16769 Running                 ./pipe-wait pipe &
[3]+ 16770 Running                 ./pipe-wait pipe &

0 p1 root #
[1]  16768 Done                    ./pipe-wait pipe
[2]- 16769 Done                    ./pipe-wait pipe
[3]+ 16770 Done                    ./pipe-wait pipe

this behaviour is wrong, no matter which of the pipe-wait* programs is
used.  what i want to achieve is having any number of poll's wait until
pipe-signal is invoked.  this doesn't happen, as the waiters exit
immediately with no error, as if data was immediately available, which is
obviously wrong.

0 p1 root #ls -F pipe*
pipe|              pipe-wait*         pipe-wait-poll*
pipe-signal*       pipe-wait-block*   pipe-wait-poll.c*
pipe-signal.c*     pipe-wait-block.c* pipe-wait.c*

0 p1 root #ll pipe
29165 prw-r--r--  1 root  wheel  - 0 13 Jan 18:32 pipe|

0 p1 root #./pipe-signal

1 p1 root #./pipe-signal pipe

>Fix:

the kernel for version 4.3 needs fixing.  i am not sure if this issue has
been resolved in -current.

clemens fischer

-------------------- 8< -----------------------

/* pipe-wait.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
  int fd;
  fd_set set, empty;
  if (argc<2) return 1;
  fd=open(argv[1], O_RDONLY|O_NDELAY);
  if (fd<0) return 2;
  FD_ZERO(&empty);
  FD_ZERO(&set);
  FD_SET(fd, &set);
  if (select(fd+1, &set, &empty, &empty, NULL)!=1) return 3;
  return 0;
}

-------------------- 8< -----------------------
/* pipe-wait-block.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
  int fd;
  fd_set set, empty;
  if (argc<2) return 1;
  fd=open(argv[1], O_RDONLY|O_NDELAY);
  if (fd<0) return 2;
  if (fcntl(fd, F_SETFL, O_RDONLY)!=0) return 3;
  FD_ZERO(&empty);
  FD_ZERO(&set);
  FD_SET(fd, &set);
  if (select(fd+1, &set, &empty, &empty, NULL)!=1) return 4;
  return 0;
}

-------------------- 8< -----------------------
/* pipe-wait-poll.c */
#include <sys/types.h>
#include <poll.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
  int fd;
  struct pollfd x;
  if (argc<2) return 1;
  fd=open(argv[1], O_RDONLY|O_NDELAY);
  if (fd<0) return 2;
  if (fcntl(fd, F_SETFL, O_RDONLY)!=0) return 3;
  x.fd=fd;
  x.events=POLLIN;
  if (poll(&x, 1, -1)!=1) return 4;
  if (x.revents&POLLIN==0) return 5;
  return 0;
}

-------------------- 8< -----------------------
/* pipe-signal.c */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char* argv[]) {
  if (argc<2) return 1;
  if (open(argv[1], O_WRONLY|O_NDELAY)<0 && errno!=ENXIO) return 2;
  return 0;
}
>Release-Note:
>Audit-Trail:
>Unformatted:
 >System: FreeBSD spotteswoode.dnsalias.org 4.3-RELEASE FreeBSD 4.3-RELEASE #13: Sun Jan 13 11:53:26 CET 2002 root@spotteswoode.dnsalias.org:/usr/src/sys/compile/n1 i386
 
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020118094230.GA968>