diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-01-17 00:17:46 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-01-17 00:17:46 +0000 |
commit | 076451c75336b30e6152bd5c02f355db39107f7d (patch) | |
tree | 785a6c71ca1e5246f2ce09a9b91f98eb902ac2a0 /src/usocket.c | |
parent | 89f3ecf7820857f91c4039536d2bbe3cf12d5f95 (diff) | |
download | luasocket-076451c75336b30e6152bd5c02f355db39107f7d.tar.gz luasocket-076451c75336b30e6152bd5c02f355db39107f7d.tar.bz2 luasocket-076451c75336b30e6152bd5c02f355db39107f7d.zip |
Tested in windows. Still needs more testing, but progress has been made.
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/src/usocket.c b/src/usocket.c index f2d9f01..89be85e 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -145,7 +145,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
145 | else return IO_TIMEOUT; | 145 | else return IO_TIMEOUT; |
146 | /* here we know the connection has been closed */ | 146 | /* here we know the connection has been closed */ |
147 | } else return IO_CLOSED; | 147 | } else return IO_CLOSED; |
148 | /* here we sent successfully sent something */ | 148 | /* here we successfully sent something */ |
149 | } else { | 149 | } else { |
150 | *sent = put; | 150 | *sent = put; |
151 | return IO_DONE; | 151 | return IO_DONE; |
@@ -159,34 +159,36 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
159 | SA *addr, socklen_t addr_len, int timeout) | 159 | SA *addr, socklen_t addr_len, int timeout) |
160 | { | 160 | { |
161 | t_sock sock = *ps; | 161 | t_sock sock = *ps; |
162 | struct timeval tv; | 162 | ssize_t put; |
163 | fd_set fds; | ||
164 | ssize_t put = 0; | ||
165 | int err; | ||
166 | int ret; | 163 | int ret; |
164 | /* avoid making system calls on closed sockets */ | ||
167 | if (sock == SOCK_INVALID) return IO_CLOSED; | 165 | if (sock == SOCK_INVALID) return IO_CLOSED; |
168 | tv.tv_sec = timeout / 1000; | 166 | /* make sure we repeat in case the call was interrupted */ |
169 | tv.tv_usec = (timeout % 1000) * 1000; | 167 | do put = sendto(sock, data, count, 0, addr, addr_len); |
170 | FD_ZERO(&fds); | 168 | while (put <= 0 && errno == EINTR); |
171 | FD_SET(sock, &fds); | 169 | /* deal with failure */ |
172 | ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | 170 | if (put <= 0) { |
173 | if (ret > 0) { | 171 | /* in any case, nothing has been sent */ |
174 | put = sendto(sock, data, count, 0, addr, addr_len); | ||
175 | if (put <= 0) { | ||
176 | err = IO_CLOSED; | ||
177 | #ifdef __CYGWIN__ | ||
178 | /* this is for CYGWIN, which is like Unix but has Win32 bugs */ | ||
179 | if (sent < 0 && errno == EWOULDBLOCK) err = IO_DONE; | ||
180 | #endif | ||
181 | *sent = 0; | ||
182 | } else { | ||
183 | *sent = put; | ||
184 | err = IO_DONE; | ||
185 | } | ||
186 | return err; | ||
187 | } else { | ||
188 | *sent = 0; | 172 | *sent = 0; |
189 | return IO_TIMEOUT; | 173 | /* run select to avoid busy wait */ |
174 | if (errno != EPIPE) { | ||
175 | struct timeval tv; | ||
176 | fd_set fds; | ||
177 | tv.tv_sec = timeout / 1000; | ||
178 | tv.tv_usec = (timeout % 1000) * 1000; | ||
179 | FD_ZERO(&fds); | ||
180 | FD_SET(sock, &fds); | ||
181 | ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | ||
182 | /* tell the caller to call us again because there is more data */ | ||
183 | if (ret > 0) return IO_DONE; | ||
184 | /* tell the caller there was no data before timeout */ | ||
185 | else return IO_TIMEOUT; | ||
186 | /* here we know the connection has been closed */ | ||
187 | } else return IO_CLOSED; | ||
188 | /* here we successfully sent something */ | ||
189 | } else { | ||
190 | *sent = put; | ||
191 | return IO_DONE; | ||
190 | } | 192 | } |
191 | } | 193 | } |
192 | 194 | ||
@@ -232,28 +234,26 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
232 | SA *addr, socklen_t *addr_len, int timeout) | 234 | SA *addr, socklen_t *addr_len, int timeout) |
233 | { | 235 | { |
234 | t_sock sock = *ps; | 236 | t_sock sock = *ps; |
235 | struct timeval tv; | 237 | ssize_t taken; |
236 | fd_set fds; | ||
237 | int ret; | ||
238 | if (sock == SOCK_INVALID) return IO_CLOSED; | 238 | if (sock == SOCK_INVALID) return IO_CLOSED; |
239 | ssize_t taken = 0; | 239 | do taken = recvfrom(sock, data, count, 0, addr, addr_len); |
240 | tv.tv_sec = timeout / 1000; | 240 | while (taken <= 0 && errno == EINTR); |
241 | tv.tv_usec = (timeout % 1000) * 1000; | 241 | if (taken <= 0) { |
242 | FD_ZERO(&fds); | 242 | struct timeval tv; |
243 | FD_SET(sock, &fds); | 243 | fd_set fds; |
244 | ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | 244 | int ret; |
245 | if (ret > 0) { | ||
246 | taken = recvfrom(sock, data, count, 0, addr, addr_len); | ||
247 | if (taken <= 0) { | ||
248 | *got = 0; | ||
249 | return IO_CLOSED; | ||
250 | } else { | ||
251 | *got = taken; | ||
252 | return IO_DONE; | ||
253 | } | ||
254 | } else { | ||
255 | *got = 0; | 245 | *got = 0; |
256 | return IO_TIMEOUT; | 246 | if (taken == 0) return IO_CLOSED; |
247 | tv.tv_sec = timeout / 1000; | ||
248 | tv.tv_usec = (timeout % 1000) * 1000; | ||
249 | FD_ZERO(&fds); | ||
250 | FD_SET(sock, &fds); | ||
251 | ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | ||
252 | if (ret > 0) return IO_DONE; | ||
253 | else return IO_TIMEOUT; | ||
254 | } else { | ||
255 | *got = taken; | ||
256 | return IO_DONE; | ||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||