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 | ||
