This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

piped stdout and O_NONBLOCK


Hi all,

In short: Does it work?
I wanted a program to write its debug messages to a pipe, data flowing
into "faucet" of "netpipes" and over a network connection.
But that did not work, because faucet blocks on a connect() from the
other side and meanwhile does not read any data from the pipe. So the
first program blocks in writing its output after a while, even if the
output stream is set to O_NONBLOCK.

For testing purposes I wrote a program "blocktest":

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>

int main(void)
{
	char    buffer[4096];
	fd_set  input_set;
	int     read_bytes;
	int     remaining_bytes;
	char   *p;
	int     written_bytes;

	if (fcntl(0,F_SETFL,O_NONBLOCK)<0)
	{
		perror("input stream can not be set to nonblocking mode");
		exit(EXIT_FAILURE);
	}
	if (fcntl(1,F_SETFL,O_NONBLOCK)<0)
	{
		perror("output stream can not be set to nonblocking mode");
		exit(EXIT_FAILURE);
	}

	FD_ZERO(&input_set);
	FD_SET(0,&input_set);

	for(;;)
	{
		// Try to read.
		if ((read_bytes=read(0,&buffer,sizeof(buffer)))<0)
		{
			if (errno!=EAGAIN)
			{
				perror("read failed");
				exit(EXIT_FAILURE);
			}
		}
		else
		{
			// Nothing to read. Try to write.
			remaining_bytes=read_bytes;
			p=(char*)&buffer;
			while (remaining_bytes>0)
			{
				if
((written_bytes=write(1,&p,remaining_bytes))<0)
				{
					if (errno==EAGAIN) break;

					perror("write failed");
					exit(EXIT_FAILURE);
				}
				remaining_bytes-=written_bytes;
				p+=written_bytes;
			}			

			// Write would block. Wait for new data to read.
			select(1,&input_set,NULL,NULL,NULL);
		}
	}
}

Then I put it into a pipeline

cat /dev/zero | ./blocktest | sleep 1000

With Linux this works as expected, with a "cat" using nearly all cpu time.
With Cygwin, "blocktest" blocks in the write call after writing 12288 bytes,
causing "cat" to block.
I tested this with Cygwin-1.3.9 and 1.3.12-2.

Did I miss something?

	Jan

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]