[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Different behavior of my code



On Thu, Sep 08, 2011 at 04:44:26PM +0100, Nicholas Marriott wrote:
<snip>
> It is a limitation of OS X. Every other platform with kqueue(2) and all
> I am aware of with poll(2) support it on all file descriptors. OS X
> doesn't support it on anything other than sockets - so not on ttys, not
> on files, not anything except sockets.

AFAIK OS X fixed this issue many years ago. In fact, I think it was an issue
that only cropped up for one or two releases. The following works for me on
Snow Leopard 10.6.8 (uname says "Darwin Kernel Version 10.8.0") regardless
of whether stdin is a fifo or pty. It does fail on /dev/zero and /dev/null,
however.


#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/stat.h>

#include <unistd.h>
#include <fcntl.h>

#include <err.h>


int main(void) {
	struct stat st;
	const char *type;
	struct kevent kv;
	int flags, kq;

	if (0 != fstat(STDIN_FILENO, &st))
		err(1, "stdin");

	switch (st.st_mode & S_IFMT) {
	case S_IFIFO:
		type = "fifo";
		break;
	case S_IFCHR:
		type = "device";
		break;
	case S_IFREG:
		type = "regular";
		break;
	case S_IFSOCK:
		type = "socket";
		break;
	default:
		type = "unknown";
		break;
	}

	fprintf(stderr, "stdin filetype: %s\n", type);

	if (-1 == (flags = fcntl(STDIN_FILENO, F_GETFL)))
		err(1, "stdin");

	if (0 != fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK))
		err(1, "stdin");

	if (-1 == (kq = kqueue()))
		err(1, "kqueue");

	EV_SET(&kv, STDIN_FILENO, EVFILT_READ, EV_ADD, 0, 0, 0);

	if (0 != kevent(kq, &kv, 1, 0, 0, 0))
		err(1, "kevent");

	while (-1 != kevent(kq, 0, 0, &kv, 1, 0)) {
		char data[512], *p, *pe;
		ssize_t count;

		while ((count = read(STDIN_FILENO, data, sizeof data)) > 0) {
			p = data;
			pe = &data[count];

			while (p < pe) {
				if (-1 == (count = write(STDOUT_FILENO, p, pe - p)))
					err(1, "stdout");

				p += count;
			}
		}

		if (count == -1 && errno != EAGAIN)
			err(1, "stdin");
		if (!count)
			break;
	}

	return 0;
} /* main() */


***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.