Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Feb 2002 12:00:14 -0800 (PST)
From:      "Ronald F. Guilmette" <rfg@monkeys.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/35396: poll(2) doesn't set POLLERR for failed connect(2) attempts 
Message-ID:  <200202282000.g1SK0ER09161@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/35396; it has been noted by GNATS.

From: "Ronald F. Guilmette" <rfg@monkeys.com>
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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <poll.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 
 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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202282000.g1SK0ER09161>