poll() can't count on MacOS 10.5.8-10.6.4 ?

The program below tries to connect to a port on the local host. That connection attempt fails. It listens for the failure via poll on a non-blocking socket. The poll signals when the connect attempt has failed. That's all good and well, and works as advertised.

Well, almost.

According to the manual page, poll should return 1 (the failed "connect" counts as being ready for I/O):

Poll() returns the number of descriptors that are ready for I/O, or -1 if an error occurred. If the time limit expires, poll() returns 0.

So, why does this program print i=2?


#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <poll.h>

#include <sys/fcntl.h>

#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

int main(void)
{
	/*  Make a TCP socket.
	 */
	int s = socket(PF_INET, SOCK_STREAM, 0);
	if (s == -1) { perror("socket"); return 1; }

	/*  Set the socket to non-blocking.
	 */
	int  flags;
	if ((flags = fcntl(s, F_GETFL, 0)) < 0)
		{ perror("fcntl-1"); exit(1); }
	if (fcntl(s, F_SETFL, flags | O_NONBLOCK) != 0)
		{ perror("fcntl-2"); exit(1); }

	/*  Get the address of some uninhabited port on localhost.
	 */
	struct sockaddr_in sin = { .sin_port = htons(1133) };
	inet_aton("127.0.0.1", &sin.sin_addr);

	/*  Asynchronous connect.  Will start out with EINPROGRESS,
	 *  then signal completion (and an error) via poll().
	 */
	if (  connect(s, (struct sockaddr *)&sin, sizeof(sin)) != 0
	   && errno != EINPROGRESS) { perror("connect"); return 1; }

	struct pollfd pfd = { .fd=s, .events=POLLIN|POLLOUT };
	int i = poll(&pfd, 1, -1);

	/*  MacOS 10.5.8-10.6.4: i=2.  WTF?
	 */
	printf("i=%d\n", i);

	return 0;
}

Clues welcome,

jutta@pobox.com, Feb 20 2010, last update Jul 18 2010.