diff options
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 368 |
1 files changed, 189 insertions, 179 deletions
diff --git a/src/usocket.c b/src/usocket.c index 4e73a96..4d4f092 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -14,6 +14,63 @@ | |||
14 | #include "socket.h" | 14 | #include "socket.h" |
15 | 15 | ||
16 | /*-------------------------------------------------------------------------*\ | 16 | /*-------------------------------------------------------------------------*\ |
17 | * Wait for readable/writable/connected socket with timeout | ||
18 | \*-------------------------------------------------------------------------*/ | ||
19 | #ifdef SOCK_POLL | ||
20 | #include <sys/poll.h> | ||
21 | |||
22 | #define WAITFD_R POLLIN | ||
23 | #define WAITFD_W POLLOUT | ||
24 | #define WAITFD_C (POLLIN|POLLOUT) | ||
25 | static int sock_waitfd(int fd, int sw, p_tm tm) { | ||
26 | int ret; | ||
27 | struct pollfd pfd; | ||
28 | pfd.fd = fd; | ||
29 | pfd.events = sw; | ||
30 | pfd.revents = 0; | ||
31 | if (tm_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ | ||
32 | do ret = poll(&pfd, 1, (int)(tm_getretry(tm)*1e3)); | ||
33 | while (ret == -1 && errno == EINTR); | ||
34 | if (ret == -1) return errno; | ||
35 | if (ret == 0) return IO_TIMEOUT; | ||
36 | if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED; | ||
37 | return IO_DONE; | ||
38 | } | ||
39 | #else | ||
40 | |||
41 | #define WAITFD_R 1 | ||
42 | #define WAITFD_W 2 | ||
43 | #define WAITFD_C (WAITFD_R|WAITFD_W) | ||
44 | |||
45 | static int sock_waitfd(int fd, int sw, p_tm tm) { | ||
46 | int ret; | ||
47 | fd_set rfds, wfds, *rp, *wp; | ||
48 | struct timeval tv, *tp; | ||
49 | double t; | ||
50 | if (tm_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ | ||
51 | do { | ||
52 | /* must set bits within loop, because select may have modifed them */ | ||
53 | rp = wp = NULL; | ||
54 | if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(fd, &rfds); rp = &rfds; } | ||
55 | if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(fd, &wfds); wp = &wfds; } | ||
56 | t = tm_getretry(tm); | ||
57 | tp = NULL; | ||
58 | if (t >= 0.0) { | ||
59 | tv.tv_sec = (int)t; | ||
60 | tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6); | ||
61 | tp = &tv; | ||
62 | } | ||
63 | ret = select(fd+1, rp, wp, NULL, tp); | ||
64 | } while (ret == -1 && errno == EINTR); | ||
65 | if (ret == -1) return errno; | ||
66 | if (ret == 0) return IO_TIMEOUT; | ||
67 | if (sw == WAITFD_C && FD_ISSET(fd, &rfds)) return IO_CLOSED; | ||
68 | return IO_DONE; | ||
69 | } | ||
70 | #endif | ||
71 | |||
72 | |||
73 | /*-------------------------------------------------------------------------*\ | ||
17 | * Initializes module | 74 | * Initializes module |
18 | \*-------------------------------------------------------------------------*/ | 75 | \*-------------------------------------------------------------------------*/ |
19 | int sock_open(void) { | 76 | int sock_open(void) { |
@@ -58,59 +115,19 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_tm tm) { | |||
58 | /*-------------------------------------------------------------------------*\ | 115 | /*-------------------------------------------------------------------------*\ |
59 | * Creates and sets up a socket | 116 | * Creates and sets up a socket |
60 | \*-------------------------------------------------------------------------*/ | 117 | \*-------------------------------------------------------------------------*/ |
61 | const char *sock_create(p_sock ps, int domain, int type, int protocol) { | 118 | int sock_create(p_sock ps, int domain, int type, int protocol) { |
62 | t_sock sock = socket(domain, type, protocol); | 119 | *ps = socket(domain, type, protocol); |
63 | if (sock == SOCK_INVALID) return sock_strerror(); | 120 | if (*ps != SOCK_INVALID) return IO_DONE; |
64 | *ps = sock; | 121 | else return errno; |
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | /*-------------------------------------------------------------------------*\ | ||
69 | * Connects or returns error message | ||
70 | \*-------------------------------------------------------------------------*/ | ||
71 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) { | ||
72 | t_sock sock = *ps; | ||
73 | int err; | ||
74 | /* don't call on closed socket */ | ||
75 | if (sock == SOCK_INVALID) return io_strerror(IO_CLOSED); | ||
76 | /* ask system to connect */ | ||
77 | do err = connect(sock, addr, addr_len); | ||
78 | while (err < 0 && errno == EINTR); | ||
79 | /* if no error, we're done */ | ||
80 | if (err == 0) return NULL; | ||
81 | /* make sure the system is trying to connect */ | ||
82 | if (errno != EINPROGRESS) return sock_strerror(); | ||
83 | /* optimize for timeout = 0 */ | ||
84 | if (tm_get(tm) == 0.0) return io_strerror(IO_TIMEOUT); | ||
85 | /* wait for a timeout or for the system's answer */ | ||
86 | for ( ;; ) { | ||
87 | fd_set rfds, wfds; | ||
88 | FD_ZERO(&rfds); FD_SET(sock, &rfds); | ||
89 | FD_ZERO(&wfds); FD_SET(sock, &wfds); | ||
90 | /* we run select to avoid busy waiting */ | ||
91 | err = sock_select(sock+1, &rfds, &wfds, NULL, tm); | ||
92 | /* if there was an event, check what happened */ | ||
93 | if (err > 0) { | ||
94 | char dummy; | ||
95 | /* recv will set errno to the value a blocking connect would set */ | ||
96 | if (err > 1 && FD_ISSET(sock, &rfds) && | ||
97 | recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN) | ||
98 | return sock_strerror(); | ||
99 | else | ||
100 | return NULL; | ||
101 | /* if no event happened, there was a timeout */ | ||
102 | } else if (err == 0) return io_strerror(IO_TIMEOUT); | ||
103 | } | ||
104 | return sock_strerror(); | ||
105 | } | 122 | } |
106 | 123 | ||
107 | /*-------------------------------------------------------------------------*\ | 124 | /*-------------------------------------------------------------------------*\ |
108 | * Binds or returns error message | 125 | * Binds or returns error message |
109 | \*-------------------------------------------------------------------------*/ | 126 | \*-------------------------------------------------------------------------*/ |
110 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) { | 127 | int sock_bind(p_sock ps, SA *addr, socklen_t len) { |
111 | const char *err = NULL; | 128 | int err = IO_DONE; |
112 | sock_setblocking(ps); | 129 | sock_setblocking(ps); |
113 | if (bind(*ps, addr, addr_len) < 0) err = sock_strerror(); | 130 | if (bind(*ps, addr, len) < 0) err = errno; |
114 | sock_setnonblocking(ps); | 131 | sock_setnonblocking(ps); |
115 | return err; | 132 | return err; |
116 | } | 133 | } |
@@ -118,10 +135,10 @@ const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) { | |||
118 | /*-------------------------------------------------------------------------*\ | 135 | /*-------------------------------------------------------------------------*\ |
119 | * | 136 | * |
120 | \*-------------------------------------------------------------------------*/ | 137 | \*-------------------------------------------------------------------------*/ |
121 | const char* sock_listen(p_sock ps, int backlog) { | 138 | int sock_listen(p_sock ps, int backlog) { |
122 | const char *err = NULL; | 139 | int err = IO_DONE; |
123 | sock_setblocking(ps); | 140 | sock_setblocking(ps); |
124 | if (listen(*ps, backlog)) err = sock_strerror(); | 141 | if (listen(*ps, backlog)) err = errno; |
125 | sock_setnonblocking(ps); | 142 | sock_setnonblocking(ps); |
126 | return err; | 143 | return err; |
127 | } | 144 | } |
@@ -136,37 +153,45 @@ void sock_shutdown(p_sock ps, int how) { | |||
136 | } | 153 | } |
137 | 154 | ||
138 | /*-------------------------------------------------------------------------*\ | 155 | /*-------------------------------------------------------------------------*\ |
156 | * Connects or returns error message | ||
157 | \*-------------------------------------------------------------------------*/ | ||
158 | int sock_connect(p_sock ps, SA *addr, socklen_t len, p_tm tm) { | ||
159 | int err; | ||
160 | /* avoid calling on closed sockets */ | ||
161 | if (*ps == SOCK_INVALID) return IO_CLOSED; | ||
162 | /* call connect until done or failed without being interrupted */ | ||
163 | do if (connect(*ps, addr, len) == 0) return IO_DONE; | ||
164 | while ((err = errno) == EINTR); | ||
165 | /* if connection failed immediately, return error code */ | ||
166 | if (err != EINPROGRESS && err != EAGAIN) return err; | ||
167 | /* wait until we have the result of the connection attempt or timeout */ | ||
168 | if ((err = sock_waitfd(*ps, WAITFD_C, tm)) == IO_CLOSED) { | ||
169 | /* finaly find out if we succeeded connecting */ | ||
170 | if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; | ||
171 | else return errno; | ||
172 | /* timed out or some weirder error */ | ||
173 | } else return err; | ||
174 | } | ||
175 | |||
176 | /*-------------------------------------------------------------------------*\ | ||
139 | * Accept with timeout | 177 | * Accept with timeout |
140 | \*-------------------------------------------------------------------------*/ | 178 | \*-------------------------------------------------------------------------*/ |
141 | const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | 179 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *len, p_tm tm) { |
142 | socklen_t *addr_len, p_tm tm) { | 180 | SA daddr; |
143 | t_sock sock = *ps; | 181 | socklen_t dlen = sizeof(daddr); |
144 | SA dummy_addr; | 182 | int err; |
145 | socklen_t dummy_len = sizeof(dummy_addr); | 183 | if (*ps == SOCK_INVALID) return IO_CLOSED; |
146 | if (sock == SOCK_INVALID) return io_strerror(IO_CLOSED); | 184 | if (!addr) addr = &daddr; |
147 | if (!addr) addr = &dummy_addr; | 185 | if (!len) len = &dlen; |
148 | if (!addr_len) addr_len = &dummy_len; | 186 | for ( ;; ) { |
149 | for (;;) { | 187 | if ((*pa = accept(*ps, addr, len)) != SOCK_INVALID) return IO_DONE; |
150 | int err; | 188 | err = errno; |
151 | fd_set fds; | 189 | if (err == EINTR) continue; |
152 | /* try to accept */ | 190 | if (err != EAGAIN && err != ECONNABORTED) return err; |
153 | do *pa = accept(sock, addr, addr_len); | 191 | if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; |
154 | while (*pa < 0 && errno == EINTR); | 192 | } |
155 | /* if result is valid, we are done */ | 193 | /* can't reach here */ |
156 | if (*pa != SOCK_INVALID) return NULL; | 194 | return err; |
157 | /* find out if we failed for a fatal reason */ | ||
158 | /* if connection was aborted, we can try again if we have time */ | ||
159 | if (errno != EAGAIN && errno != ECONNABORTED) return sock_strerror(); | ||
160 | /* optimize for timeout = 0 case */ | ||
161 | if (tm_get(tm) == 0.0) return io_strerror(IO_TIMEOUT); | ||
162 | /* call select to avoid busy-wait. */ | ||
163 | FD_ZERO(&fds); | ||
164 | FD_SET(sock, &fds); | ||
165 | err = sock_select(sock+1, &fds, NULL, NULL, tm); | ||
166 | if (err == 0) return io_strerror(IO_TIMEOUT); | ||
167 | else if (err < 0) break; | ||
168 | } | ||
169 | return sock_strerror(); | ||
170 | } | 195 | } |
171 | 196 | ||
172 | /*-------------------------------------------------------------------------*\ | 197 | /*-------------------------------------------------------------------------*\ |
@@ -174,132 +199,100 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | |||
174 | \*-------------------------------------------------------------------------*/ | 199 | \*-------------------------------------------------------------------------*/ |
175 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) | 200 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, p_tm tm) |
176 | { | 201 | { |
177 | t_sock sock = *ps; | 202 | int err; |
178 | /* avoid making system calls on closed sockets */ | 203 | /* avoid making system calls on closed sockets */ |
179 | if (sock == SOCK_INVALID) return IO_CLOSED; | 204 | if (*ps == SOCK_INVALID) return IO_CLOSED; |
180 | /* loop until we send something or we give up on error */ | 205 | /* loop until we send something or we give up on error */ |
206 | *sent = 0; | ||
181 | for ( ;; ) { | 207 | for ( ;; ) { |
182 | int ret; | 208 | ssize_t put = send(*ps, data, count, 0); |
183 | fd_set fds; | 209 | /* if we sent anything, we are done */ |
184 | ssize_t put; | 210 | if (put > 0) { |
185 | /* make sure we repeat in case the call was interrupted */ | ||
186 | do put = send(sock, data, count, 0); | ||
187 | while (put < 0 && errno == EINTR); | ||
188 | /* if we sent something, get out */ | ||
189 | if (put > 0) { | ||
190 | *sent = put; | 211 | *sent = put; |
191 | return IO_DONE; | 212 | return IO_DONE; |
192 | } | 213 | } |
193 | /* deal with failure */ | 214 | err = errno; |
194 | *sent = 0; | 215 | /* send can't really return 0, but EPIPE means the connection was |
195 | /* here we know the connection has been closed */ | 216 | closed */ |
196 | if (put < 0 && errno == EPIPE) return IO_CLOSED; | 217 | if (put == 0 || err == EPIPE) return IO_CLOSED; |
197 | /* send shouldn't return zero and we can only proceed if | 218 | /* we call was interrupted, just try again */ |
198 | * there was no serious error */ | 219 | if (err == EINTR) continue; |
199 | if (put == 0 || errno != EAGAIN) return IO_USER; | 220 | /* if failed fatal reason, report error */ |
200 | /* optimize for the timeout = 0 case */ | 221 | if (err != EAGAIN) return err; |
201 | if (tm_get(tm) == 0.0) return IO_TIMEOUT; | 222 | /* wait until we can send something or we timeout */ |
202 | /* run select to avoid busy wait */ | 223 | if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; |
203 | FD_ZERO(&fds); | 224 | } |
204 | FD_SET(sock, &fds); | 225 | /* can't reach here */ |
205 | ret = sock_select(sock+1, NULL, &fds, NULL, tm); | 226 | return err; |
206 | if (ret == 0) return IO_TIMEOUT; | ||
207 | else if (ret < 0) break; | ||
208 | /* otherwise, try sending again */ | ||
209 | } | ||
210 | return IO_USER; | ||
211 | } | 227 | } |
212 | 228 | ||
213 | /*-------------------------------------------------------------------------*\ | 229 | /*-------------------------------------------------------------------------*\ |
214 | * Sendto with timeout | 230 | * Sendto with timeout |
215 | \*-------------------------------------------------------------------------*/ | 231 | \*-------------------------------------------------------------------------*/ |
216 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | 232 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, |
217 | SA *addr, socklen_t addr_len, p_tm tm) | 233 | SA *addr, socklen_t len, p_tm tm) |
218 | { | 234 | { |
219 | t_sock sock = *ps; | 235 | int err; |
220 | /* avoid making system calls on closed sockets */ | 236 | if (*ps == SOCK_INVALID) return IO_CLOSED; |
221 | if (sock == SOCK_INVALID) return IO_CLOSED; | 237 | *sent = 0; |
222 | /* loop until we send something or we give up on error */ | ||
223 | for ( ;; ) { | 238 | for ( ;; ) { |
224 | int ret; | 239 | ssize_t put = sendto(*ps, data, count, 0, addr, len); |
225 | fd_set fds; | 240 | if (put > 0) { |
226 | ssize_t put; | ||
227 | do put = sendto(sock, data, count, 0, addr, addr_len); | ||
228 | while (put < 0 && errno == EINTR); | ||
229 | if (put > 0) { | ||
230 | *sent = put; | 241 | *sent = put; |
231 | return IO_DONE; | 242 | return IO_DONE; |
232 | } | 243 | } |
233 | *sent = 0; | 244 | err = errno; |
234 | if (put < 0 && errno == EPIPE) return IO_CLOSED; | 245 | if (put == 0 || err == EPIPE) return IO_CLOSED; |
235 | if (put == 0 || errno != EAGAIN) return IO_USER; | 246 | if (err == EINTR) continue; |
236 | if (tm_get(tm) == 0.0) return IO_TIMEOUT; | 247 | if (err != EAGAIN) return err; |
237 | FD_ZERO(&fds); | 248 | if ((err = sock_waitfd(*ps, WAITFD_W, tm)) != IO_DONE) return err; |
238 | FD_SET(sock, &fds); | 249 | } |
239 | ret = sock_select(sock+1, NULL, &fds, NULL, tm); | 250 | return err; |
240 | if (ret == 0) return IO_TIMEOUT; | ||
241 | else if (ret < 0) break; | ||
242 | } | ||
243 | return IO_USER; | ||
244 | } | 251 | } |
245 | 252 | ||
246 | /*-------------------------------------------------------------------------*\ | 253 | /*-------------------------------------------------------------------------*\ |
247 | * Receive with timeout | 254 | * Receive with timeout |
248 | \*-------------------------------------------------------------------------*/ | 255 | \*-------------------------------------------------------------------------*/ |
249 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, p_tm tm) { | 256 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, p_tm tm) { |
250 | t_sock sock = *ps; | 257 | int err; |
251 | if (sock == SOCK_INVALID) return IO_CLOSED; | 258 | if (*ps == SOCK_INVALID) return IO_CLOSED; |
252 | for ( ;; ) { | 259 | for ( ;; ) { |
253 | fd_set fds; | 260 | ssize_t taken = recv(*ps, data, count, 0); |
254 | int ret; | ||
255 | ssize_t taken; | ||
256 | do taken = read(sock, data, count); | ||
257 | while (taken < 0 && errno == EINTR); | ||
258 | if (taken > 0) { | 261 | if (taken > 0) { |
259 | *got = taken; | 262 | *got = taken; |
260 | return IO_DONE; | 263 | return IO_DONE; |
261 | } | 264 | } |
265 | err = errno; | ||
262 | *got = 0; | 266 | *got = 0; |
263 | if (taken == 0) return IO_CLOSED; | 267 | if (taken == 0) return IO_CLOSED; |
264 | if (errno != EAGAIN) return IO_USER; | 268 | if (err == EINTR) continue; |
265 | if (tm_get(tm) == 0.0) return IO_TIMEOUT; | 269 | if (err != EAGAIN) return err; |
266 | FD_ZERO(&fds); | 270 | if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; |
267 | FD_SET(sock, &fds); | 271 | } |
268 | ret = sock_select(sock+1, &fds, NULL, NULL, tm); | 272 | return err; |
269 | if (ret == 0) return IO_TIMEOUT; | ||
270 | else if (ret < 0) break; | ||
271 | } | ||
272 | return IO_USER; | ||
273 | } | 273 | } |
274 | 274 | ||
275 | /*-------------------------------------------------------------------------*\ | 275 | /*-------------------------------------------------------------------------*\ |
276 | * Recvfrom with timeout | 276 | * Recvfrom with timeout |
277 | \*-------------------------------------------------------------------------*/ | 277 | \*-------------------------------------------------------------------------*/ |
278 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | 278 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, |
279 | SA *addr, socklen_t *addr_len, p_tm tm) { | 279 | SA *addr, socklen_t *len, p_tm tm) { |
280 | t_sock sock = *ps; | 280 | int err; |
281 | if (sock == SOCK_INVALID) return IO_CLOSED; | 281 | if (*ps == SOCK_INVALID) return IO_CLOSED; |
282 | for ( ;; ) { | 282 | for ( ;; ) { |
283 | fd_set fds; | 283 | ssize_t taken = recvfrom(*ps, data, count, 0, addr, len); |
284 | int ret; | ||
285 | ssize_t taken; | ||
286 | do taken = recvfrom(sock, data, count, 0, addr, addr_len); | ||
287 | while (taken < 0 && errno == EINTR); | ||
288 | if (taken > 0) { | 284 | if (taken > 0) { |
289 | *got = taken; | 285 | *got = taken; |
290 | return IO_DONE; | 286 | return IO_DONE; |
291 | } | 287 | } |
288 | err = errno; | ||
292 | *got = 0; | 289 | *got = 0; |
293 | if (taken == 0) return IO_CLOSED; | 290 | if (taken == 0) return IO_CLOSED; |
294 | if (errno != EAGAIN) return IO_USER; | 291 | if (err == EINTR) continue; |
295 | if (tm_get(tm) == 0.0) return IO_TIMEOUT; | 292 | if (err != EAGAIN) return err; |
296 | FD_ZERO(&fds); | 293 | if ((err = sock_waitfd(*ps, WAITFD_R, tm)) != IO_DONE) return err; |
297 | FD_SET(sock, &fds); | 294 | } |
298 | ret = sock_select(sock+1, &fds, NULL, NULL, tm); | 295 | return err; |
299 | if (ret == 0) return IO_TIMEOUT; | ||
300 | else if (ret < 0) break; | ||
301 | } | ||
302 | return IO_USER; | ||
303 | } | 296 | } |
304 | 297 | ||
305 | /*-------------------------------------------------------------------------*\ | 298 | /*-------------------------------------------------------------------------*\ |
@@ -321,29 +314,46 @@ void sock_setnonblocking(p_sock ps) { | |||
321 | } | 314 | } |
322 | 315 | ||
323 | /*-------------------------------------------------------------------------*\ | 316 | /*-------------------------------------------------------------------------*\ |
317 | * DNS helpers | ||
318 | \*-------------------------------------------------------------------------*/ | ||
319 | int sock_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | ||
320 | *hp = gethostbyaddr(addr, len, AF_INET); | ||
321 | if (*hp) return IO_DONE; | ||
322 | else return h_errno; | ||
323 | } | ||
324 | |||
325 | int sock_gethostbyname(const char *addr, struct hostent **hp) { | ||
326 | *hp = gethostbyname(addr); | ||
327 | if (*hp) return IO_DONE; | ||
328 | else return h_errno; | ||
329 | } | ||
330 | |||
331 | /*-------------------------------------------------------------------------*\ | ||
324 | * Error translation functions | 332 | * Error translation functions |
333 | * Make sure important error messages are standard | ||
325 | \*-------------------------------------------------------------------------*/ | 334 | \*-------------------------------------------------------------------------*/ |
326 | const char *sock_hoststrerror(void) { | 335 | const char *sock_hoststrerror(int err) { |
327 | switch (h_errno) { | 336 | if (err <= 0) return io_strerror(err); |
328 | case HOST_NOT_FOUND: | 337 | switch (err) { |
329 | return "host not found"; | 338 | case HOST_NOT_FOUND: return "host_not_found"; |
330 | default: | 339 | default: return hstrerror(err); |
331 | return hstrerror(h_errno); | ||
332 | } | 340 | } |
333 | } | 341 | } |
334 | 342 | ||
335 | /* make sure important error messages are standard */ | 343 | const char *sock_strerror(int err) { |
336 | const char *sock_strerror(void) { | 344 | if (err <= 0) return io_strerror(err); |
337 | switch (errno) { | 345 | switch (err) { |
338 | case EADDRINUSE: | 346 | case EADDRINUSE: return "eaddrinuse"; |
339 | return "address already in use"; | 347 | case EACCES: return "eaccess"; |
340 | default: | 348 | case ECONNABORTED: return "econnaborted"; |
341 | return strerror(errno); | 349 | case ECONNREFUSED: return "econnrefused"; |
350 | case ECONNRESET: return "econnreset"; | ||
351 | case ETIMEDOUT: return "etimedout"; | ||
352 | default: return strerror(errno); | ||
342 | } | 353 | } |
343 | } | 354 | } |
344 | 355 | ||
345 | const char *sock_geterr(p_sock ps, int code) { | 356 | const char *sock_ioerror(p_sock ps, int err) { |
346 | (void) ps; | 357 | (void) ps; |
347 | (void) code; | 358 | return sock_strerror(err); |
348 | return sock_strerror(); | 359 | } |
349 | } | ||