Handling EINTR with connect(2) is tricky enough that I think it
deserves an example that people can copy & paste into their own
code.

Is it worth expanding the part before connect_wait()?

 - todd

Index: lib/libc/sys/connect.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/connect.2,v
retrieving revision 1.29
diff -u -p -u -r1.29 connect.2
--- lib/libc/sys/connect.2      9 Aug 2016 17:34:06 -0000       1.29
+++ lib/libc/sys/connect.2      18 Aug 2016 16:35:20 -0000
@@ -104,6 +104,52 @@ If the connection or binding succeeds, 0
 Otherwise a \-1 is returned, and a more specific error
 code is stored in
 .Va errno .
+.Sh EXAMPLES
+The following code connects to the host described by
+.Fa name
+and handles the case where
+.Fn connect
+is interrupted by a signal.
+.Bd -literal -offset indent
+#include <sys/socket.h>
+#include <poll.h>
+#include <errno.h>
+#include <err.h>
+
+int retcode;
+
+retcode = connect(s, name, namelen);
+if (retcode == -1) {
+       if (errno == EINTR)
+               retcode = connect_wait(s, name, namelen);
+       if (retcode == -1)
+               err(1, "connect");
+}
+
+int
+connect_wait(int s, const struct sockaddr *name, socklen_t namelen)
+{
+       struct pollfd pfd[1];
+       int error = 0;
+       socklen_t len = sizeof(error);
+
+       pfd[0].fd = s;
+       pfd[0].events = POLLOUT;
+       for (;;) {
+               if (poll(pfd, 1, -1) == -1) {
+                       if (errno != EINTR)
+                               return -1;
+                       continue;
+               }
+               if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+                       return -1;
+               if (error != 0)
+                       errno = error;
+               break;
+       }
+       return (error ? -1 : 0);
+}
+.Ed
 .Sh ERRORS
 The
 .Fn connect

Reply via email to