Mail Archives: cygwin/2010/01/03/11:59:50
--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Wed, Dec 23, 2009 at 03:12:19AM +0100, Enrico Forestieri wrote:
> On Tue, Dec 22, 2009 at 07:37:14PM -0500, Christopher Faylor wrote:
> > On Tue, Dec 22, 2009 at 11:43:09PM +0100, Enrico Forestieri wrote:
> > >I am experiencing a problem with select() and named pipes in cygwin
> > >1.7. The attached test case segfaults on the select() call, but works
> > >fine with both cygwin 1.5 and linux.
> >
> > Thanks for the test case. This should be fixed in the next Cygwin
> > snapshot but it will not be fixed (of course?) in 1.7.1 which is now
> > available from the Cygwin web site.
>
> I confirm that with the 20091222 snapshot the crash does not occur
> anymore. However, there's still something wrong. Indeed, running the
> test case in a terminal and issuing "echo foo > /tmp/pipe" from another
> one, the program exits without printing the expected "foo".
Apparently, the problem is due to the O_NONBLOCK flag used in the open()
call. Taking away O_NONBLOCK, everything works.
This bug is causing an infinite loop in an application. The loop can
be reproduced by the slightly modified test case attached here.
When O_NONBLOCK is used, after issuing "echo foo > /tmp/pipe", read()
always returns -1 and sets errno to EAGAIN. However, according to
http://www.opengroup.org/onlinepubs/009695399/functions/read.html
this should only occur when reading from an empty pipe or fifo
and some process has the pipe open for writing and O_NONBLOCK is set.
Here, the fifo is not empty (as reported by select), and thus that
should not happen.
--
Enrico
--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="readfifo.c"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FIFONAME "/tmp/pipe"
int main(void)
{
int fd;
int nsel;
fd_set readfds;
FD_ZERO(&readfds);
if (mkfifo(FIFONAME, 0600) < 0) {
perror("mkfifo");
exit(1);
}
fd = open(FIFONAME, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror("open");
remove(FIFONAME);
exit(2);
}
FD_SET(fd, &readfds);
do {
nsel = select(fd + 1, &readfds, 0, 0, 0);
} while (nsel == -1 && (errno == EINTR || errno == EAGAIN));
if (nsel == -1) {
perror("select");
exit(3);
}
if (FD_ISSET(fd, &readfds)) {
char buf[100];
int status;
int count = 0;
printf("%d: ", ++count);
while ((status = read(fd, buf, sizeof(buf) - 1))) {
if (status > 0) {
buf[status] = '\0';
printf("%s", buf);
} else if (errno == EAGAIN) {
printf("\n%d: ", ++count);
} else {
perror("read");
break;
}
}
}
close(fd);
remove(FIFONAME);
return 0;
}
--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
--opJtzjQTFsWo+cga--
- Raw text -