select() and named pipes
Enrico Forestieri
forenr@lyx.org
Tue Feb 16 01:21:00 GMT 2010
On Sun, Feb 14, 2010 at 08:54:27PM -0500, Christopher Faylor wrote:
> I just checked in YA in my series of attempts to get this working right.
> It will behave marginally better now but there are still problems if you
> attempt to write to a fifo before anything is reading it and then try to
> do a non-blocking read.
Thank you for your efforts. It indeed works better with the 2010-02-15
snapshot.
In order to help you pinpointing another glitch, I attach here a slightly
slightly modified version of the original test case and a shell script.
Launching the program in a terminal and then the shell script in another
one, it seems that the program hangs on the write() call.
Apparently, the problem is the O_RDWR flag, as replacing it with O_WRONLY,
everything works. The test case works with O_RDWR both in cygwin 1.5 and
linux.
--
Enrico
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FIFO_IN "/tmp/pipe.in"
#define FIFO_OUT "/tmp/pipe.out"
#define ACK "Message received\n"
int main(void)
{
int infd;
int outfd;
int nsel;
fd_set readfds;
FD_ZERO(&readfds);
if (mkfifo(FIFO_IN, 0600) < 0 || mkfifo(FIFO_OUT, 0600) < 0) {
perror("mkfifo");
remove(FIFO_IN);
remove(FIFO_OUT);
exit(1);
}
infd = open(FIFO_IN, O_RDONLY | O_NONBLOCK);
outfd = open(FIFO_OUT, O_RDWR);
if (infd < 0 || outfd < 0) {
perror("open");
if (infd >= 0)
close(infd);
if (outfd >= 0)
close(outfd);
remove(FIFO_IN);
remove(FIFO_OUT);
exit(2);
}
FD_SET(infd, &readfds);
do {
nsel = select(infd + 1, &readfds, 0, 0, 0);
} while (nsel == -1 && (errno == EINTR || errno == EAGAIN));
if (nsel == -1) {
perror("select");
exit(3);
}
if (FD_ISSET(infd, &readfds)) {
char buf[100];
int status;
while ((status = read(infd, buf, sizeof(buf) - 1))) {
if (status > 0) {
buf[status] = '\0';
printf("%s", buf);
} else {
printf("\n");
if (errno != EAGAIN)
perror("read");
break;
}
}
}
if (write(outfd, ACK, strlen(ACK)) < 0)
perror("write");
sleep(1);
close(infd);
close(outfd);
remove(FIFO_IN);
remove(FIFO_OUT);
return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fifotest.sh
Type: application/x-sh
Size: 55 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20100216/83c56f7c/attachment.sh>
-------------- next part --------------
--
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
More information about the Cygwin
mailing list