diff options
| author | Diego Nehab <diego@impa.br> | 2015-03-03 19:20:44 -0300 |
|---|---|---|
| committer | Diego Nehab <diego@impa.br> | 2015-03-03 19:20:44 -0300 |
| commit | 321c0c9b1f7b6b83cd83b58e7e259f53eca69373 (patch) | |
| tree | 9fbab852261ef92747bbd6dfcad9f39e9ca59bbe /src/usocket.c | |
| parent | 8066a90e87efd50db43cba7d76b3c700bea8aa84 (diff) | |
| parent | 863a54cbaf7f9ca4ceb4cdcc7f99f18713fa5199 (diff) | |
| download | luasocket-321c0c9b1f7b6b83cd83b58e7e259f53eca69373.tar.gz luasocket-321c0c9b1f7b6b83cd83b58e7e259f53eca69373.tar.bz2 luasocket-321c0c9b1f7b6b83cd83b58e7e259f53eca69373.zip | |
Merge branch 'Tieske-errormsg'
Diffstat (limited to 'src/usocket.c')
| -rw-r--r-- | src/usocket.c | 98 |
1 files changed, 49 insertions, 49 deletions
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 @@ | |||
| 4 | * | 4 | * |
| 5 | * The code is now interrupt-safe. | 5 | * The code is now interrupt-safe. |
| 6 | * The penalty of calling select to avoid busy-wait is only paid when | 6 | * The penalty of calling select to avoid busy-wait is only paid when |
| 7 | * the I/O call fail in the first place. | 7 | * the I/O call fail in the first place. |
| 8 | \*=========================================================================*/ | 8 | \*=========================================================================*/ |
| 9 | #include <string.h> | 9 | #include <string.h> |
| 10 | #include <signal.h> | 10 | #include <signal.h> |
| 11 | 11 | ||
| 12 | #include "socket.h" | 12 | #include "socket.h" |
| 13 | #include "pierror.h" | ||
| 13 | 14 | ||
| 14 | /*-------------------------------------------------------------------------*\ | 15 | /*-------------------------------------------------------------------------*\ |
| 15 | * Wait for readable/writable/connected socket with timeout | 16 | * Wait for readable/writable/connected socket with timeout |
| @@ -72,7 +73,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) { | |||
| 72 | 73 | ||
| 73 | 74 | ||
| 74 | /*-------------------------------------------------------------------------*\ | 75 | /*-------------------------------------------------------------------------*\ |
| 75 | * Initializes module | 76 | * Initializes module |
| 76 | \*-------------------------------------------------------------------------*/ | 77 | \*-------------------------------------------------------------------------*/ |
| 77 | int socket_open(void) { | 78 | int socket_open(void) { |
| 78 | /* instals a handler to ignore sigpipe or it will crash us */ | 79 | /* instals a handler to ignore sigpipe or it will crash us */ |
| @@ -81,7 +82,7 @@ int socket_open(void) { | |||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | /*-------------------------------------------------------------------------*\ | 84 | /*-------------------------------------------------------------------------*\ |
| 84 | * Close module | 85 | * Close module |
| 85 | \*-------------------------------------------------------------------------*/ | 86 | \*-------------------------------------------------------------------------*/ |
| 86 | int socket_close(void) { | 87 | int socket_close(void) { |
| 87 | return 1; | 88 | return 1; |
| @@ -100,7 +101,7 @@ void socket_destroy(p_socket ps) { | |||
| 100 | /*-------------------------------------------------------------------------*\ | 101 | /*-------------------------------------------------------------------------*\ |
| 101 | * Select with timeout control | 102 | * Select with timeout control |
| 102 | \*-------------------------------------------------------------------------*/ | 103 | \*-------------------------------------------------------------------------*/ |
| 103 | int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, | 104 | int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, |
| 104 | p_timeout tm) { | 105 | p_timeout tm) { |
| 105 | int ret; | 106 | int ret; |
| 106 | do { | 107 | do { |
| @@ -119,8 +120,8 @@ int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 119 | \*-------------------------------------------------------------------------*/ | 120 | \*-------------------------------------------------------------------------*/ |
| 120 | int socket_create(p_socket ps, int domain, int type, int protocol) { | 121 | int socket_create(p_socket ps, int domain, int type, int protocol) { |
| 121 | *ps = socket(domain, type, protocol); | 122 | *ps = socket(domain, type, protocol); |
| 122 | if (*ps != SOCKET_INVALID) return IO_DONE; | 123 | if (*ps != SOCKET_INVALID) return IO_DONE; |
| 123 | else return errno; | 124 | else return errno; |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | /*-------------------------------------------------------------------------*\ | 127 | /*-------------------------------------------------------------------------*\ |
| @@ -129,22 +130,22 @@ int socket_create(p_socket ps, int domain, int type, int protocol) { | |||
| 129 | int socket_bind(p_socket ps, SA *addr, socklen_t len) { | 130 | int socket_bind(p_socket ps, SA *addr, socklen_t len) { |
| 130 | int err = IO_DONE; | 131 | int err = IO_DONE; |
| 131 | socket_setblocking(ps); | 132 | socket_setblocking(ps); |
| 132 | if (bind(*ps, addr, len) < 0) err = errno; | 133 | if (bind(*ps, addr, len) < 0) err = errno; |
| 133 | socket_setnonblocking(ps); | 134 | socket_setnonblocking(ps); |
| 134 | return err; | 135 | return err; |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | /*-------------------------------------------------------------------------*\ | 138 | /*-------------------------------------------------------------------------*\ |
| 138 | * | 139 | * |
| 139 | \*-------------------------------------------------------------------------*/ | 140 | \*-------------------------------------------------------------------------*/ |
| 140 | int socket_listen(p_socket ps, int backlog) { | 141 | int socket_listen(p_socket ps, int backlog) { |
| 141 | int err = IO_DONE; | 142 | int err = IO_DONE; |
| 142 | if (listen(*ps, backlog)) err = errno; | 143 | if (listen(*ps, backlog)) err = errno; |
| 143 | return err; | 144 | return err; |
| 144 | } | 145 | } |
| 145 | 146 | ||
| 146 | /*-------------------------------------------------------------------------*\ | 147 | /*-------------------------------------------------------------------------*\ |
| 147 | * | 148 | * |
| 148 | \*-------------------------------------------------------------------------*/ | 149 | \*-------------------------------------------------------------------------*/ |
| 149 | void socket_shutdown(p_socket ps, int how) { | 150 | void socket_shutdown(p_socket ps, int how) { |
| 150 | shutdown(*ps, how); | 151 | shutdown(*ps, how); |
| @@ -161,7 +162,7 @@ int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { | |||
| 161 | do if (connect(*ps, addr, len) == 0) return IO_DONE; | 162 | do if (connect(*ps, addr, len) == 0) return IO_DONE; |
| 162 | while ((err = errno) == EINTR); | 163 | while ((err = errno) == EINTR); |
| 163 | /* if connection failed immediately, return error code */ | 164 | /* if connection failed immediately, return error code */ |
| 164 | if (err != EINPROGRESS && err != EAGAIN) return err; | 165 | if (err != EINPROGRESS && err != EAGAIN) return err; |
| 165 | /* zero timeout case optimization */ | 166 | /* zero timeout case optimization */ |
| 166 | if (timeout_iszero(tm)) return IO_TIMEOUT; | 167 | if (timeout_iszero(tm)) return IO_TIMEOUT; |
| 167 | /* wait until we have the result of the connection attempt or timeout */ | 168 | /* 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) { | |||
| 176 | * Accept with timeout | 177 | * Accept with timeout |
| 177 | \*-------------------------------------------------------------------------*/ | 178 | \*-------------------------------------------------------------------------*/ |
| 178 | int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { | 179 | int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { |
| 179 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 180 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 180 | for ( ;; ) { | 181 | for ( ;; ) { |
| 181 | int err; | 182 | int err; |
| 182 | if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; | 183 | 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 | |||
| 192 | /*-------------------------------------------------------------------------*\ | 193 | /*-------------------------------------------------------------------------*\ |
| 193 | * Send with timeout | 194 | * Send with timeout |
| 194 | \*-------------------------------------------------------------------------*/ | 195 | \*-------------------------------------------------------------------------*/ |
| 195 | int socket_send(p_socket ps, const char *data, size_t count, | 196 | int socket_send(p_socket ps, const char *data, size_t count, |
| 196 | size_t *sent, p_timeout tm) | 197 | size_t *sent, p_timeout tm) |
| 197 | { | 198 | { |
| 198 | int err; | 199 | int err; |
| @@ -224,14 +225,14 @@ int socket_send(p_socket ps, const char *data, size_t count, | |||
| 224 | /*-------------------------------------------------------------------------*\ | 225 | /*-------------------------------------------------------------------------*\ |
| 225 | * Sendto with timeout | 226 | * Sendto with timeout |
| 226 | \*-------------------------------------------------------------------------*/ | 227 | \*-------------------------------------------------------------------------*/ |
| 227 | int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, | 228 | int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, |
| 228 | SA *addr, socklen_t len, p_timeout tm) | 229 | SA *addr, socklen_t len, p_timeout tm) |
| 229 | { | 230 | { |
| 230 | int err; | 231 | int err; |
| 231 | *sent = 0; | 232 | *sent = 0; |
| 232 | if (*ps == SOCKET_INVALID) return IO_CLOSED; | 233 | if (*ps == SOCKET_INVALID) return IO_CLOSED; |
| 233 | for ( ;; ) { | 234 | for ( ;; ) { |
| 234 | long put = (long) sendto(*ps, data, count, 0, addr, len); | 235 | long put = (long) sendto(*ps, data, count, 0, addr, len); |
| 235 | if (put >= 0) { | 236 | if (put >= 0) { |
| 236 | *sent = put; | 237 | *sent = put; |
| 237 | return IO_DONE; | 238 | return IO_DONE; |
| @@ -261,8 +262,8 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 261 | err = errno; | 262 | err = errno; |
| 262 | if (taken == 0) return IO_CLOSED; | 263 | if (taken == 0) return IO_CLOSED; |
| 263 | if (err == EINTR) continue; | 264 | if (err == EINTR) continue; |
| 264 | if (err != EAGAIN) return err; | 265 | if (err != EAGAIN) return err; |
| 265 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | 266 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; |
| 266 | } | 267 | } |
| 267 | return IO_UNKNOWN; | 268 | return IO_UNKNOWN; |
| 268 | } | 269 | } |
| @@ -270,7 +271,7 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 270 | /*-------------------------------------------------------------------------*\ | 271 | /*-------------------------------------------------------------------------*\ |
| 271 | * Recvfrom with timeout | 272 | * Recvfrom with timeout |
| 272 | \*-------------------------------------------------------------------------*/ | 273 | \*-------------------------------------------------------------------------*/ |
| 273 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | 274 | int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, |
| 274 | SA *addr, socklen_t *len, p_timeout tm) { | 275 | SA *addr, socklen_t *len, p_timeout tm) { |
| 275 | int err; | 276 | int err; |
| 276 | *got = 0; | 277 | *got = 0; |
| @@ -284,8 +285,8 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | |||
| 284 | err = errno; | 285 | err = errno; |
| 285 | if (taken == 0) return IO_CLOSED; | 286 | if (taken == 0) return IO_CLOSED; |
| 286 | if (err == EINTR) continue; | 287 | if (err == EINTR) continue; |
| 287 | if (err != EAGAIN) return err; | 288 | if (err != EAGAIN) return err; |
| 288 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | 289 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; |
| 289 | } | 290 | } |
| 290 | return IO_UNKNOWN; | 291 | return IO_UNKNOWN; |
| 291 | } | 292 | } |
| @@ -298,7 +299,7 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, | |||
| 298 | * with send/recv replaced with write/read. We can't just use write/read | 299 | * with send/recv replaced with write/read. We can't just use write/read |
| 299 | * in the socket version, because behaviour when size is zero is different. | 300 | * in the socket version, because behaviour when size is zero is different. |
| 300 | \*-------------------------------------------------------------------------*/ | 301 | \*-------------------------------------------------------------------------*/ |
| 301 | int socket_write(p_socket ps, const char *data, size_t count, | 302 | int socket_write(p_socket ps, const char *data, size_t count, |
| 302 | size_t *sent, p_timeout tm) | 303 | size_t *sent, p_timeout tm) |
| 303 | { | 304 | { |
| 304 | int err; | 305 | int err; |
| @@ -344,8 +345,8 @@ int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm | |||
| 344 | err = errno; | 345 | err = errno; |
| 345 | if (taken == 0) return IO_CLOSED; | 346 | if (taken == 0) return IO_CLOSED; |
| 346 | if (err == EINTR) continue; | 347 | if (err == EINTR) continue; |
| 347 | if (err != EAGAIN) return err; | 348 | if (err != EAGAIN) return err; |
| 348 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | 349 | if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; |
| 349 | } | 350 | } |
| 350 | return IO_UNKNOWN; | 351 | return IO_UNKNOWN; |
| 351 | } | 352 | } |
| @@ -369,7 +370,7 @@ void socket_setnonblocking(p_socket ps) { | |||
| 369 | } | 370 | } |
| 370 | 371 | ||
| 371 | /*-------------------------------------------------------------------------*\ | 372 | /*-------------------------------------------------------------------------*\ |
| 372 | * DNS helpers | 373 | * DNS helpers |
| 373 | \*-------------------------------------------------------------------------*/ | 374 | \*-------------------------------------------------------------------------*/ |
| 374 | int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | 375 | int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { |
| 375 | *hp = gethostbyaddr(addr, len, AF_INET); | 376 | *hp = gethostbyaddr(addr, len, AF_INET); |
| @@ -394,7 +395,7 @@ int socket_gethostbyname(const char *addr, struct hostent **hp) { | |||
| 394 | const char *socket_hoststrerror(int err) { | 395 | const char *socket_hoststrerror(int err) { |
| 395 | if (err <= 0) return io_strerror(err); | 396 | if (err <= 0) return io_strerror(err); |
| 396 | switch (err) { | 397 | switch (err) { |
| 397 | case HOST_NOT_FOUND: return "host not found"; | 398 | case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; |
| 398 | default: return hstrerror(err); | 399 | default: return hstrerror(err); |
| 399 | } | 400 | } |
| 400 | } | 401 | } |
| @@ -402,13 +403,13 @@ const char *socket_hoststrerror(int err) { | |||
| 402 | const char *socket_strerror(int err) { | 403 | const char *socket_strerror(int err) { |
| 403 | if (err <= 0) return io_strerror(err); | 404 | if (err <= 0) return io_strerror(err); |
| 404 | switch (err) { | 405 | switch (err) { |
| 405 | case EADDRINUSE: return "address already in use"; | 406 | case EADDRINUSE: return PIE_ADDRINUSE; |
| 406 | case EISCONN: return "already connected"; | 407 | case EISCONN: return PIE_ISCONN; |
| 407 | case EACCES: return "permission denied"; | 408 | case EACCES: return PIE_ACCESS; |
| 408 | case ECONNREFUSED: return "connection refused"; | 409 | case ECONNREFUSED: return PIE_CONNREFUSED; |
| 409 | case ECONNABORTED: return "closed"; | 410 | case ECONNABORTED: return PIE_CONNABORTED; |
| 410 | case ECONNRESET: return "closed"; | 411 | case ECONNRESET: return PIE_CONNRESET; |
| 411 | case ETIMEDOUT: return "timeout"; | 412 | case ETIMEDOUT: return PIE_TIMEDOUT; |
| 412 | default: return strerror(err); | 413 | default: return strerror(err); |
| 413 | } | 414 | } |
| 414 | } | 415 | } |
| @@ -416,28 +417,27 @@ const char *socket_strerror(int err) { | |||
| 416 | const char *socket_ioerror(p_socket ps, int err) { | 417 | const char *socket_ioerror(p_socket ps, int err) { |
| 417 | (void) ps; | 418 | (void) ps; |
| 418 | return socket_strerror(err); | 419 | return socket_strerror(err); |
| 419 | } | 420 | } |
| 420 | 421 | ||
| 421 | const char *socket_gaistrerror(int err) { | 422 | const char *socket_gaistrerror(int err) { |
| 422 | if (err == 0) return NULL; | 423 | if (err == 0) return NULL; |
| 423 | switch (err) { | 424 | switch (err) { |
| 424 | case EAI_AGAIN: return "temporary failure in name resolution"; | 425 | case EAI_AGAIN: return PIE_AGAIN; |
| 425 | case EAI_BADFLAGS: return "invalid value for ai_flags"; | 426 | case EAI_BADFLAGS: return PIE_BADFLAGS; |
| 426 | #ifdef EAI_BADHINTS | 427 | #ifdef EAI_BADHINTS |
| 427 | case EAI_BADHINTS: return "invalid value for hints"; | 428 | case EAI_BADHINTS: return PIE_BADHINTS; |
| 428 | #endif | 429 | #endif |
| 429 | case EAI_FAIL: return "non-recoverable failure in name resolution"; | 430 | case EAI_FAIL: return PIE_FAIL; |
| 430 | case EAI_FAMILY: return "ai_family not supported"; | 431 | case EAI_FAMILY: return PIE_FAMILY; |
| 431 | case EAI_MEMORY: return "memory allocation failure"; | 432 | case EAI_MEMORY: return PIE_MEMORY; |
| 432 | case EAI_NONAME: | 433 | case EAI_NONAME: return PIE_NONAME; |
| 433 | return "host or service not provided, or not known"; | 434 | case EAI_OVERFLOW: return PIE_OVERFLOW; |
| 434 | case EAI_OVERFLOW: return "argument buffer overflow"; | ||
| 435 | #ifdef EAI_PROTOCOL | 435 | #ifdef EAI_PROTOCOL |
| 436 | case EAI_PROTOCOL: return "resolved protocol is unknown"; | 436 | case EAI_PROTOCOL: return PIE_PROTOCOL; |
| 437 | #endif | 437 | #endif |
| 438 | case EAI_SERVICE: return "service not supported for socket type"; | 438 | case EAI_SERVICE: return PIE_SERVICE; |
| 439 | case EAI_SOCKTYPE: return "ai_socktype not supported"; | 439 | case EAI_SOCKTYPE: return PIE_SOCKTYPE; |
| 440 | case EAI_SYSTEM: return strerror(errno); | 440 | case EAI_SYSTEM: return strerror(errno); |
| 441 | default: return gai_strerror(err); | 441 | default: return gai_strerror(err); |
| 442 | } | 442 | } |
| 443 | } | 443 | } |
