From 0352eb99c9bf8112d3bdbe1bc90fea0837708197 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Thu, 16 Feb 2006 03:22:28 +0000 Subject: [PATCH] Add os_socketpair() function; clean up blocking tests. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1617 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 8 +++ include/ircd_osdep.h | 1 + ircd/os_generic.c | 124 ++++++++++++++++--------------------------- 3 files changed, 55 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49fcc26..e1094ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-15 Michael Poole + + * 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 * ircd/match.c (match): Fix backtracking bug after an escape diff --git a/include/ircd_osdep.h b/include/ircd_osdep.h index 4eeb66f..6e53fc9 100644 --- a/include/ircd_osdep.h +++ b/include/ircd_osdep.h @@ -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 */ diff --git a/ircd/os_generic.c b/ircd/os_generic.c index ff56fce..c462209 100644 --- a/ircd/os_generic.c +++ b/ircd/os_generic.c @@ -81,6 +81,17 @@ #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); +} -- 2.20.1