From owner-freebsd-bugs Thu Feb 28 12: 1:10 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id C639737B400 for ; Thu, 28 Feb 2002 12:00:14 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g1SK0ER09161; Thu, 28 Feb 2002 12:00:14 -0800 (PST) (envelope-from gnats) Date: Thu, 28 Feb 2002 12:00:14 -0800 (PST) Message-Id: <200202282000.g1SK0ER09161@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: "Ronald F. Guilmette" Subject: Re: kern/35396: poll(2) doesn't set POLLERR for failed connect(2) attempts Reply-To: "Ronald F. Guilmette" Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR kern/35396; it has been noted by GNATS. From: "Ronald F. Guilmette" To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: kern/35396: poll(2) doesn't set POLLERR for failed connect(2) attempts Date: Thu, 28 Feb 2002 11:56:15 -0800 There was a small programming error in the example program that I originally submitted with this bug report. The server process called listen(2) twice, rather than calling listen(2) and then accept(2), as it should have done. This programming error doesn't really affect the validity of the bug report, and the original example program still does illustrate (with its client process) the bug I was reporting adequately well, however for the sake of complete clarity, and to insure there are no misunderstandings, I am attaching a corrected example program for this bug report below. cut here for corrected example program ======================================================================== /* poll(2) error test #2 - corrected */ #include #include #include #include #include #include #include #include #include #include #include #include static struct protoent *tcp_proto; static void fatal (register char const *const fmt, register char const *const arg) { fprintf (stderr, fmt, arg); putc ('\n', stderr); exit (1); } static void do_poll (register int const fd) { auto struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN | POLLHUP | POLLERR; pfd.revents = 0; if (poll (&pfd, 1, -1) == -1) fatal ("Error in poll: %s", strerror (errno)); fprintf (stderr, "poll(2) did return\n"); if (pfd.revents & POLLHUP) fatal ("poll(2) indicates hangup", NULL); if (pfd.revents & POLLIN) fatal ("poll(2) indicates input waiting", NULL); } static void do_connect_and_poll (struct in_addr addr, unsigned short port) { auto struct sockaddr_in sin; register int fd; if ((fd = socket (PF_INET, SOCK_STREAM, tcp_proto->p_proto)) == -1) fatal ("Error creating socket: %s", strerror (errno)); memset (&sin, 0, sizeof sin); sin.sin_family = AF_INET; sin.sin_addr = addr; sin.sin_port = htons (port); if (connect (fd, (struct sockaddr *) &sin, sizeof sin) == -1) fatal ("Error in connect: %s", strerror (errno)); fprintf (stderr, "Client connected to server\n"); do_poll (fd); } static void do_listen_sleep_and_die (struct in_addr addr, unsigned short port) { auto int one = 1; auto struct sockaddr_in sin; auto struct sockaddr_in sin2; auto socklen_t sin2_size = sizeof sin2; register int listen_fd; register int client_fd; if ((listen_fd = socket (PF_INET, SOCK_STREAM, tcp_proto->p_proto)) == -1) fatal ("Error creating socket: %s", strerror (errno)); memset (&sin, 0, sizeof sin); sin.sin_family = AF_INET; sin.sin_addr = addr; sin.sin_port = htons (port); if (bind (listen_fd, (struct sockaddr *) &sin, sizeof sin) == -1) fatal ("Error in bind: %s", strerror (errno)); if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one) == -1) fatal ("Error in setsockopt: %s", strerror (errno)); if (listen (listen_fd, 1) == -1) fatal ("Error in listen: %s", strerror (errno)); client_fd = accept (listen_fd, (struct sockaddr *) &sin2, &sin2_size); if (client_fd == -1) fatal ("Error in accept: %s", strerror (errno)); fprintf (stderr, "Server accepted connection from client\n"); sleep (1); close (client_fd); /* Shut it down. */ fprintf (stderr, "Server closed connection\n"); } int main (void) { static char const protocol_name[] = "tcp"; auto struct in_addr addr; register int const port = 32767; register int pid; if ((tcp_proto = getprotobyname (protocol_name)) == NULL) fatal ("Cannot find number for protocol: %s", protocol_name); inet_aton ("127.0.0.1", &addr); if ((pid = fork ()) == -1) fatal ("Error in fork: %s", strerror (errno)); if (pid) { sleep (1); /* Give server time to start up. */ do_connect_and_poll (addr, port); /* Child process does this. */ } else do_listen_sleep_and_die (addr, port); /* Parent process does this. */ return 0; } ======================================================================== To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message