diff --git a/src/pierror.h b/src/pierror.h new file mode 100644 index 0000000..cb773ab --- /dev/null +++ b/src/pierror.h @@ -0,0 +1,28 @@ +#ifndef PIERROR_H +#define PIERROR_H +/*=========================================================================*\ +* Error messages +* Defines platform independent error messages +\*=========================================================================*/ + +#define PIE_HOST_NOT_FOUND "host not found" +#define PIE_ADDRINUSE "address already in use" +#define PIE_ISCONN "already connected" +#define PIE_ACCESS "permission denied" +#define PIE_CONNREFUSED "connection refused" +#define PIE_CONNABORTED "closed" +#define PIE_CONNRESET "closed" +#define PIE_TIMEDOUT "timeout" +#define PIE_AGAIN "temporary failure in name resolution" +#define PIE_BADFLAGS "invalid value for ai_flags" +#define PIE_BADHINTS "invalid value for hints" +#define PIE_FAIL "non-recoverable failure in name resolution" +#define PIE_FAMILY "ai_family not supported" +#define PIE_MEMORY "memory allocation failure" +#define PIE_NONAME "host or service not provided, or not known" +#define PIE_OVERFLOW "argument buffer overflow" +#define PIE_PROTOCOL "resolved protocol is unknown" +#define PIE_SERVICE "service not supported for socket type" +#define PIE_SOCKTYPE "ai_socktype not supported" + +#endif diff --git a/src/usocket.c b/src/usocket.c index 89f774d..99e551b 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -4,12 +4,13 @@ * * The code is now interrupt-safe. * The penalty of calling select to avoid busy-wait is only paid when -* the I/O call fail in the first place. +* the I/O call fail in the first place. \*=========================================================================*/ -#include +#include #include #include "socket.h" +#include "pierror.h" /*-------------------------------------------------------------------------*\ * Wait for readable/writable/connected socket with timeout @@ -72,7 +73,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { /*-------------------------------------------------------------------------*\ -* Initializes module +* Initializes module \*-------------------------------------------------------------------------*/ int socket_open(void) { /* instals a handler to ignore sigpipe or it will crash us */ @@ -81,7 +82,7 @@ int socket_open(void) { } /*-------------------------------------------------------------------------*\ -* Close module +* Close module \*-------------------------------------------------------------------------*/ int socket_close(void) { return 1; @@ -100,7 +101,7 @@ void socket_destroy(p_socket ps) { /*-------------------------------------------------------------------------*\ * Select with timeout control \*-------------------------------------------------------------------------*/ -int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm) { int ret; do { @@ -119,8 +120,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, \*-------------------------------------------------------------------------*/ int socket_create(p_socket ps, int domain, int type, int protocol) { *ps = socket(domain, type, protocol); - if (*ps != SOCKET_INVALID) return IO_DONE; - else return errno; + if (*ps != SOCKET_INVALID) return IO_DONE; + else return errno; } /*-------------------------------------------------------------------------*\ @@ -129,22 +130,22 @@ int socket_create(p_socket ps, int domain, int type, int protocol) { int socket_bind(p_socket ps, SA *addr, socklen_t len) { int err = IO_DONE; socket_setblocking(ps); - if (bind(*ps, addr, len) < 0) err = errno; + if (bind(*ps, addr, len) < 0) err = errno; socket_setnonblocking(ps); return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ int socket_listen(p_socket ps, int backlog) { - int err = IO_DONE; - if (listen(*ps, backlog)) err = errno; + int err = IO_DONE; + if (listen(*ps, backlog)) err = errno; return err; } /*-------------------------------------------------------------------------*\ -* +* \*-------------------------------------------------------------------------*/ void socket_shutdown(p_socket ps, int how) { shutdown(*ps, how); @@ -161,7 +162,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { do if (connect(*ps, addr, len) == 0) return IO_DONE; while ((err = errno) == EINTR); /* if connection failed immediately, return error code */ - if (err != EINPROGRESS && err != EAGAIN) return err; + if (err != EINPROGRESS && err != EAGAIN) return err; /* zero timeout case optimization */ if (timeout_iszero(tm)) return IO_TIMEOUT; /* wait until we have the result of the connection attempt or timeout */ @@ -176,7 +177,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { * Accept with timeout \*-------------------------------------------------------------------------*/ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { - if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { int err; if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; @@ -192,7 +193,7 @@ int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout /*-------------------------------------------------------------------------*\ * Send with timeout \*-------------------------------------------------------------------------*/ -int socket_send(p_socket ps, const char *data, size_t count, +int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -224,14 +225,14 @@ int socket_send(p_socket ps, const char *data, size_t count, /*-------------------------------------------------------------------------*\ * Sendto with timeout \*-------------------------------------------------------------------------*/ -int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t len, p_timeout tm) { int err; *sent = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { - long put = (long) sendto(*ps, data, count, 0, addr, len); + long put = (long) sendto(*ps, data, count, 0, addr, len); if (put >= 0) { *sent = put; return IO_DONE; @@ -261,8 +262,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -270,7 +271,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm /*-------------------------------------------------------------------------*\ * Recvfrom with timeout \*-------------------------------------------------------------------------*/ -int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *len, p_timeout tm) { int err; *got = 0; @@ -284,8 +285,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -298,7 +299,7 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, * with send/recv replaced with write/read. We can't just use write/read * in the socket version, because behaviour when size is zero is different. \*-------------------------------------------------------------------------*/ -int socket_write(p_socket ps, const char *data, size_t count, +int socket_write(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm) { int err; @@ -344,8 +345,8 @@ int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm err = errno; if (taken == 0) return IO_CLOSED; if (err == EINTR) continue; - if (err != EAGAIN) return err; - if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } return IO_UNKNOWN; } @@ -369,7 +370,7 @@ void socket_setnonblocking(p_socket ps) { } /*-------------------------------------------------------------------------*\ -* DNS helpers +* DNS helpers \*-------------------------------------------------------------------------*/ int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { *hp = gethostbyaddr(addr, len, AF_INET); @@ -394,7 +395,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case HOST_NOT_FOUND: return "host not found"; + case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return hstrerror(err); } } @@ -402,13 +403,13 @@ const char *socket_hoststrerror(int err) { const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case EADDRINUSE: return "address already in use"; - case EISCONN: return "already connected"; - case EACCES: return "permission denied"; - case ECONNREFUSED: return "connection refused"; - case ECONNABORTED: return "closed"; - case ECONNRESET: return "closed"; - case ETIMEDOUT: return "timeout"; + case EADDRINUSE: return PIE_ADDRINUSE; + case EISCONN: return PIE_ISCONN; + case EACCES: return PIE_ACCESS; + case ECONNREFUSED: return PIE_CONNREFUSED; + case ECONNABORTED: return PIE_CONNABORTED; + case ECONNRESET: return PIE_CONNRESET; + case ETIMEDOUT: return PIE_TIMEDOUT; default: return strerror(err); } } @@ -416,28 +417,27 @@ const char *socket_strerror(int err) { const char *socket_ioerror(p_socket ps, int err) { (void) ps; return socket_strerror(err); -} +} const char *socket_gaistrerror(int err) { - if (err == 0) return NULL; + if (err == 0) return NULL; switch (err) { - case EAI_AGAIN: return "temporary failure in name resolution"; - case EAI_BADFLAGS: return "invalid value for ai_flags"; + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; #ifdef EAI_BADHINTS - case EAI_BADHINTS: return "invalid value for hints"; + case EAI_BADHINTS: return PIE_BADHINTS; #endif - case EAI_FAIL: return "non-recoverable failure in name resolution"; - case EAI_FAMILY: return "ai_family not supported"; - case EAI_MEMORY: return "memory allocation failure"; - case EAI_NONAME: - return "host or service not provided, or not known"; - case EAI_OVERFLOW: return "argument buffer overflow"; + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; + case EAI_OVERFLOW: return PIE_OVERFLOW; #ifdef EAI_PROTOCOL - case EAI_PROTOCOL: return "resolved protocol is unknown"; + case EAI_PROTOCOL: return PIE_PROTOCOL; #endif - case EAI_SERVICE: return "service not supported for socket type"; - case EAI_SOCKTYPE: return "ai_socktype not supported"; - case EAI_SYSTEM: return strerror(errno); + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; + case EAI_SYSTEM: return strerror(errno); default: return gai_strerror(err); } } diff --git a/src/wsocket.c b/src/wsocket.c index b4a4384..10800e3 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -8,6 +8,7 @@ #include #include "socket.h" +#include "pierror.h" /* WinSock doesn't have a strerror... */ static const char *wstrerror(int err); @@ -330,7 +331,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAHOST_NOT_FOUND: return "host not found"; + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return wstrerror(err); } } @@ -338,13 +339,13 @@ const char *socket_hoststrerror(int err) { const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { - case WSAEADDRINUSE: return "address already in use"; - case WSAECONNREFUSED: return "connection refused"; - case WSAEISCONN: return "already connected"; - case WSAEACCES: return "permission denied"; - case WSAECONNABORTED: return "closed"; - case WSAECONNRESET: return "closed"; - case WSAETIMEDOUT: return "timeout"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; + case WSAECONNREFUSED : return PIE_CONNREFUSED; + case WSAEISCONN: return PIE_ISCONN; + case WSAEACCES: return PIE_ACCESS; + case WSAECONNABORTED: return PIE_CONNABORTED; + case WSAECONNRESET: return PIE_CONNRESET; + case WSAETIMEDOUT: return PIE_TIMEDOUT; default: return wstrerror(err); } } @@ -357,7 +358,7 @@ const char *socket_ioerror(p_socket ps, int err) { static const char *wstrerror(int err) { switch (err) { case WSAEINTR: return "Interrupted function call"; - case WSAEACCES: return "Permission denied"; + case WSAEACCES: return PIE_ACCESS; // "Permission denied"; case WSAEFAULT: return "Bad address"; case WSAEINVAL: return "Invalid argument"; case WSAEMFILE: return "Too many open files"; @@ -370,24 +371,23 @@ static const char *wstrerror(int err) { case WSAEPROTOTYPE: return "Protocol wrong type for socket"; case WSAENOPROTOOPT: return "Bad protocol option"; case WSAEPROTONOSUPPORT: return "Protocol not supported"; - case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; // "Socket type not supported"; case WSAEOPNOTSUPP: return "Operation not supported"; case WSAEPFNOSUPPORT: return "Protocol family not supported"; - case WSAEAFNOSUPPORT: - return "Address family not supported by protocol family"; - case WSAEADDRINUSE: return "Address already in use"; + case WSAEAFNOSUPPORT: return PIE_FAMILY; // "Address family not supported by protocol family"; + case WSAEADDRINUSE: return PIE_ADDRINUSE; // "Address already in use"; case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; case WSAENETDOWN: return "Network is down"; case WSAENETUNREACH: return "Network is unreachable"; case WSAENETRESET: return "Network dropped connection on reset"; case WSAECONNABORTED: return "Software caused connection abort"; - case WSAECONNRESET: return "Connection reset by peer"; + case WSAECONNRESET: return PIE_CONNRESET; // "Connection reset by peer"; case WSAENOBUFS: return "No buffer space available"; - case WSAEISCONN: return "Socket is already connected"; + case WSAEISCONN: return PIE_ISCONN; // "Socket is already connected"; case WSAENOTCONN: return "Socket is not connected"; case WSAESHUTDOWN: return "Cannot send after socket shutdown"; - case WSAETIMEDOUT: return "Connection timed out"; - case WSAECONNREFUSED: return "Connection refused"; + case WSAETIMEDOUT: return PIE_TIMEDOUT; // "Connection timed out"; + case WSAECONNREFUSED: return PIE_CONNREFUSED; // "Connection refused"; case WSAEHOSTDOWN: return "Host is down"; case WSAEHOSTUNREACH: return "No route to host"; case WSAEPROCLIM: return "Too many processes"; @@ -396,9 +396,9 @@ static const char *wstrerror(int err) { case WSANOTINITIALISED: return "Successful WSAStartup not yet performed"; case WSAEDISCON: return "Graceful shutdown in progress"; - case WSAHOST_NOT_FOUND: return "Host not found"; + case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; // "Host not found"; case WSATRY_AGAIN: return "Nonauthoritative host not found"; - case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; + case WSANO_RECOVERY: return PIE_FAIL; // "Nonrecoverable name lookup error"; case WSANO_DATA: return "Valid name, no data record of requested type"; default: return "Unknown error"; } @@ -407,24 +407,23 @@ static const char *wstrerror(int err) { const char *socket_gaistrerror(int err) { if (err == 0) return NULL; switch (err) { - case EAI_AGAIN: return "temporary failure in name resolution"; - case EAI_BADFLAGS: return "invalid value for ai_flags"; + case EAI_AGAIN: return PIE_AGAIN; + case EAI_BADFLAGS: return PIE_BADFLAGS; #ifdef EAI_BADHINTS - case EAI_BADHINTS: return "invalid value for hints"; + case EAI_BADHINTS: return PIE_BADHINTS; #endif - case EAI_FAIL: return "non-recoverable failure in name resolution"; - case EAI_FAMILY: return "ai_family not supported"; - case EAI_MEMORY: return "memory allocation failure"; - case EAI_NONAME: - return "host or service not provided, or not known"; + case EAI_FAIL: return PIE_FAIL; + case EAI_FAMILY: return PIE_FAMILY; + case EAI_MEMORY: return PIE_MEMORY; + case EAI_NONAME: return PIE_NONAME; #ifdef EAI_OVERFLOW - case EAI_OVERFLOW: return "argument buffer overflow"; + case EAI_OVERFLOW: return PIE_OVERFLOW; #endif #ifdef EAI_PROTOCOL - case EAI_PROTOCOL: return "resolved protocol is unknown"; + case EAI_PROTOCOL: return PIE_PROTOCOL; #endif - case EAI_SERVICE: return "service not supported for socket type"; - case EAI_SOCKTYPE: return "ai_socktype not supported"; + case EAI_SERVICE: return PIE_SERVICE; + case EAI_SOCKTYPE: return PIE_SOCKTYPE; #ifdef EAI_SYSTEM case EAI_SYSTEM: return strerror(errno); #endif