Add os_socketpair() function; clean up blocking tests.
authorMichael Poole <mdpoole@troilus.org>
Thu, 16 Feb 2006 03:22:28 +0000 (03:22 +0000)
committerMichael Poole <mdpoole@troilus.org>
Thu, 16 Feb 2006 03:22:28 +0000 (03:22 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1617 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/ircd_osdep.h
ircd/os_generic.c

index 49fcc262f7d656e42e421ec449286d43225c12bd..e1094add3a3baf96500f56d0dc5321a5b80887b0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-02-15  Michael Poole <mdpoole@troilus.org>
+
+       * include/ircd_osdep.h (os_socketpair): Declare.
+
+       * ircd/os_generic.c (is_blocked): New local function.
+       (os_*): Use is_blocked() instead of cut-and-pasted code.
+       (os_socketpair): New function.
+
 2006-02-15  Michael Poole <mdpoole@troilus.org>
 
        * ircd/match.c (match): Fix backtracking bug after an escape
index 4eeb66f2298260820c43f053dd722eaed032bff5..6e53fc95e3f237f9a45c16cff9b308b3087f15f6 100644 (file)
@@ -53,6 +53,7 @@ extern int os_set_nonblocking(int fd);
 extern int os_set_reuseaddr(int fd);
 extern int os_set_sockbufs(int fd, unsigned int ssize, unsigned int rsize);
 extern int os_set_tos(int fd,int tos);
+extern int os_socketpair(int sv[2]);
 
 #endif /* INCLUDED_ircd_osdep_h */
 
index ff56fce7f263bddbdfa06d62ca44e109a2b388d1..c4622094ebd6a65e9cca9a2588781e49baf1cd06 100644 (file)
 #define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
 #endif
 
+static int is_blocked(int error)
+{
+  return EWOULDBLOCK == error
+#ifdef ENOMEM
+    || ENOMEM == error
+#endif
+#ifdef ENOBUFS
+    || ENOBUFS == error
+#endif
+    || EAGAIN == error;
+}
 
 static void sockaddr_in_to_irc(const struct sockaddr_in *v4,
                                struct irc_sockaddr *irc)
@@ -428,31 +439,14 @@ IOResult os_recv_nonb(int fd, char* buf, unsigned int length,
   int res;
   assert(0 != buf);
   assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
 
   if (0 < (res = recv(fd, buf, length, 0))) {
     *count_out = (unsigned) res;
     return IO_SUCCESS;
+  } else {
+    *count_out = 0;
+    return (res < 0) && is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
-  else if (res < 0) {
-    if (EWOULDBLOCK == errno || EAGAIN == errno
-#ifdef ENOMEM
-       || ENOMEM == errno
-#endif
-#ifdef ENOBUFS
-       || ENOBUFS == errno
-#endif
-       )
-      return IO_BLOCKED;
-    else
-      return IO_FAILURE;
-  }
-  /*
-   * 0   == client closed the connection
-   * < 1 == error
-   */
-  return IO_FAILURE;
 }
 
 /** Attempt to read from a non-blocking UDP socket.
@@ -473,25 +467,16 @@ IOResult os_recvfrom_nonb(int fd, char* buf, unsigned int length,
   assert(0 != buf);
   assert(0 != length_out);
   assert(0 != addr_out);
-  errno = 0;
-  *length_out = 0;
 
   res = recvfrom(fd, buf, length, 0, (struct sockaddr*) &addr, &len);
-  if (-1 == res) {
-    if (EWOULDBLOCK == errno || ENOMEM == errno
-#ifdef ENOMEM
-       || ENOMEM == errno
-#endif
-#ifdef ENOBUFS
-       || ENOBUFS == errno
-#endif
-       )
-      return IO_BLOCKED;
-    return IO_FAILURE;
+  if (-1 < res) {
+    sockaddr_to_irc(&addr, addr_out);
+    *length_out = res;
+    return IO_SUCCESS;
+  } else {
+    *length_out = 0;
+    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
-  sockaddr_to_irc(&addr, addr_out);
-  *length_out = res;
-  return IO_SUCCESS;
 }
 
 /** Attempt to write on a non-blocking UDP socket.
@@ -510,9 +495,6 @@ IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
   struct sockaddr_native addr;
   int res, size;
   assert(0 != buf);
-  if (count_out)
-    *count_out = 0;
-  errno = 0;
 
   size = sockaddr_from_irc(&addr, peer, fd);
   assert((addr.sn_family == AF_INET) == irc_in_addr_is_ipv4(&peer->addr));
@@ -520,17 +502,11 @@ IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
     if (count_out)
       *count_out = (unsigned) res;
     return IO_SUCCESS;
+  } else {
+    if (count_out)
+      *count_out = 0;
+    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno
-#ifdef ENOMEM
-          || ENOMEM == errno
-#endif
-#ifdef ENOBUFS
-          || ENOBUFS == errno
-#endif
-      )
-    return IO_BLOCKED;
-  return IO_FAILURE;
 }
 
 /** Attempt to write on a connected socket.
@@ -546,23 +522,14 @@ IOResult os_send_nonb(int fd, const char* buf, unsigned int length,
   int res;
   assert(0 != buf);
   assert(0 != count_out);
-  *count_out = 0;
-  errno = 0;
 
   if (-1 < (res = send(fd, buf, length, 0))) {
     *count_out = (unsigned) res;
     return IO_SUCCESS;
+  } else {
+    *count_out = 0;
+    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno
-#ifdef ENOMEM
-          || ENOMEM == errno
-#endif
-#ifdef ENOBUFS
-          || ENOBUFS == errno
-#endif
-      )
-    return IO_BLOCKED;
-  return IO_FAILURE;
 }
 
 /** Attempt a vectored write on a connected socket.
@@ -584,26 +551,15 @@ IOResult os_sendv_nonb(int fd, struct MsgQ* buf, unsigned int* count_in,
   assert(0 != count_out);
 
   *count_in = 0;
-  *count_out = 0;
-  errno = 0;
-
   count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
 
   if (-1 < (res = writev(fd, iov, count))) {
     *count_out = (unsigned) res;
     return IO_SUCCESS;
+  } else {
+    *count_out = 0;
+    return is_blocked(errno) ? IO_BLOCKED : IO_FAILURE;
   }
-  else if (EWOULDBLOCK == errno || EAGAIN == errno
-#ifdef ENOMEM
-          || ENOMEM == errno
-#endif
-#ifdef ENOBUFS
-          || ENOBUFS == errno
-#endif
-      )
-    return IO_BLOCKED;
-
-  return IO_FAILURE;
 }
 
 /** Open a TCP or UDP socket on a particular address.
@@ -680,9 +636,12 @@ IOResult os_connect_nonb(int fd, const struct irc_sockaddr* sin)
   int size;
 
   size = sockaddr_from_irc(&addr, sin, fd);
-  if (connect(fd, (struct sockaddr*) &addr, size))
-    return (errno == EINPROGRESS) ? IO_BLOCKED : IO_FAILURE;
-  return IO_SUCCESS;
+  if (0 == connect(fd, (struct sockaddr*) &addr, size))
+    return IO_SUCCESS;
+  else if (errno == EINPROGRESS)
+    return IO_BLOCKED;
+  else
+    return IO_FAILURE;
 }
 
 /** Get local address of a socket.
@@ -728,3 +687,12 @@ int os_set_listen(int fd, int backlog)
 {
   return (0 == listen(fd, backlog));
 }
+
+/** Allocate a connected pair of local sockets.
+ * @param[out] sv Array of two file descriptors.
+ * @return Zero on success; non-zero number on error.
+ */
+int os_socketpair(int sv[2])
+{
+    return socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+}