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/wsocket.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/wsocket.c')
| -rw-r--r-- | src/wsocket.c | 180 |
1 files changed, 88 insertions, 92 deletions
diff --git a/src/wsocket.c b/src/wsocket.c index 59d88df..30208b9 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -100,7 +100,7 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | |||
| 100 | FD_ZERO(&fds); | 100 | FD_ZERO(&fds); |
| 101 | FD_SET(sock, &fds); | 101 | FD_SET(sock, &fds); |
| 102 | *pa = SOCK_INVALID; | 102 | *pa = SOCK_INVALID; |
| 103 | if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0) | 103 | if (select(0, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0) |
| 104 | return IO_TIMEOUT; | 104 | return IO_TIMEOUT; |
| 105 | if (!addr) addr = &dummy_addr; | 105 | if (!addr) addr = &dummy_addr; |
| 106 | if (!addr_len) addr_len = &dummy_len; | 106 | if (!addr_len) addr_len = &dummy_len; |
| @@ -116,34 +116,35 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 116 | int timeout) | 116 | int timeout) |
| 117 | { | 117 | { |
| 118 | t_sock sock = *ps; | 118 | t_sock sock = *ps; |
| 119 | struct timeval tv; | 119 | ssize_t put; |
| 120 | fd_set fds; | ||
| 121 | ssize_t put = 0; | ||
| 122 | if (sock == SOCK_INVALID) return IO_CLOSED; | ||
| 123 | int err; | ||
| 124 | int ret; | 120 | int ret; |
| 125 | tv.tv_sec = timeout / 1000; | 121 | /* avoid making system calls on closed sockets */ |
| 126 | tv.tv_usec = (timeout % 1000) * 1000; | 122 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 127 | FD_ZERO(&fds); | 123 | /* try to send something */ |
| 128 | FD_SET(sock, &fds); | 124 | put = send(sock, data, (int) count, 0); |
| 129 | ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | 125 | /* deal with failure */ |
| 130 | if (ret > 0) { | 126 | if (put <= 0) { |
| 131 | put = send(sock, data, count, 0); | 127 | /* in any case, nothing has been sent */ |
| 132 | if (put <= 0) { | ||
| 133 | /* a bug in WinSock forces us to do a busy wait until we manage | ||
| 134 | ** to write, because select returns immediately even though it | ||
| 135 | ** should have blocked us until we could write... */ | ||
| 136 | if (WSAGetLastError() == WSAEWOULDBLOCK) err = IO_DONE; | ||
| 137 | else err = IO_CLOSED; | ||
| 138 | *sent = 0; | ||
| 139 | } else { | ||
| 140 | *sent = put; | ||
| 141 | err = IO_DONE; | ||
| 142 | } | ||
| 143 | return err; | ||
| 144 | } else { | ||
| 145 | *sent = 0; | 128 | *sent = 0; |
| 146 | return IO_TIMEOUT; | 129 | /* run select to avoid busy wait */ |
| 130 | if (WSAGetLastError() == WSAEWOULDBLOCK) { | ||
| 131 | struct timeval tv; | ||
| 132 | fd_set fds; | ||
| 133 | tv.tv_sec = timeout / 1000; | ||
| 134 | tv.tv_usec = (timeout % 1000) * 1000; | ||
| 135 | FD_ZERO(&fds); | ||
| 136 | FD_SET(sock, &fds); | ||
| 137 | ret = select(0, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | ||
| 138 | /* tell the caller to call us again because there is more data */ | ||
| 139 | if (ret > 0) return IO_DONE; | ||
| 140 | /* tell the caller there was no data before timeout */ | ||
| 141 | else return IO_TIMEOUT; | ||
| 142 | /* here we know the connection has been closed */ | ||
| 143 | } else return IO_CLOSED; | ||
| 144 | /* here we successfully sent something */ | ||
| 145 | } else { | ||
| 146 | *sent = put; | ||
| 147 | return IO_DONE; | ||
| 147 | } | 148 | } |
| 148 | } | 149 | } |
| 149 | 150 | ||
| @@ -154,34 +155,35 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 154 | SA *addr, socklen_t addr_len, int timeout) | 155 | SA *addr, socklen_t addr_len, int timeout) |
| 155 | { | 156 | { |
| 156 | t_sock sock = *ps; | 157 | t_sock sock = *ps; |
| 157 | struct timeval tv; | 158 | ssize_t put; |
| 158 | fd_set fds; | ||
| 159 | ssize_t put = 0; | ||
| 160 | int err; | ||
| 161 | int ret; | 159 | int ret; |
| 160 | /* avoid making system calls on closed sockets */ | ||
| 162 | if (sock == SOCK_INVALID) return IO_CLOSED; | 161 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 163 | tv.tv_sec = timeout / 1000; | 162 | /* try to send something */ |
| 164 | tv.tv_usec = (timeout % 1000) * 1000; | 163 | put = sendto(sock, data, (int) count, 0, addr, addr_len); |
| 165 | FD_ZERO(&fds); | 164 | /* deal with failure */ |
| 166 | FD_SET(sock, &fds); | 165 | if (put <= 0) { |
| 167 | ret = select(sock+1, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | 166 | /* in any case, nothing has been sent */ |
| 168 | if (ret > 0) { | ||
| 169 | put = sendto(sock, data, count, 0, addr, addr_len); | ||
| 170 | if (put <= 0) { | ||
| 171 | /* a bug in WinSock forces us to do a busy wait until we manage | ||
| 172 | ** to write, because select returns immediately even though it | ||
| 173 | ** should have blocked us until we could write... */ | ||
| 174 | if (WSAGetLastError() == WSAEWOULDBLOCK) err = IO_DONE; | ||
| 175 | else err = IO_CLOSED; | ||
| 176 | *sent = 0; | ||
| 177 | } else { | ||
| 178 | *sent = put; | ||
| 179 | err = IO_DONE; | ||
| 180 | } | ||
| 181 | return err; | ||
| 182 | } else { | ||
| 183 | *sent = 0; | 167 | *sent = 0; |
| 184 | return IO_TIMEOUT; | 168 | /* run select to avoid busy wait */ |
| 169 | if (WSAGetLastError() == WSAEWOULDBLOCK) { | ||
| 170 | struct timeval tv; | ||
| 171 | fd_set fds; | ||
| 172 | tv.tv_sec = timeout / 1000; | ||
| 173 | tv.tv_usec = (timeout % 1000) * 1000; | ||
| 174 | FD_ZERO(&fds); | ||
| 175 | FD_SET(sock, &fds); | ||
| 176 | ret = select(0, NULL, &fds, NULL, timeout >= 0 ? &tv : NULL); | ||
| 177 | /* tell the caller to call us again because there is more data */ | ||
| 178 | if (ret > 0) return IO_DONE; | ||
| 179 | /* tell the caller there was no data before timeout */ | ||
| 180 | else return IO_TIMEOUT; | ||
| 181 | /* here we know the connection has been closed */ | ||
| 182 | } else return IO_CLOSED; | ||
| 183 | /* here we successfully sent something */ | ||
| 184 | } else { | ||
| 185 | *sent = put; | ||
| 186 | return IO_DONE; | ||
| 185 | } | 187 | } |
| 186 | } | 188 | } |
| 187 | 189 | ||
| @@ -191,28 +193,25 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
| 191 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | 193 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) |
| 192 | { | 194 | { |
| 193 | t_sock sock = *ps; | 195 | t_sock sock = *ps; |
| 194 | struct timeval tv; | 196 | ssize_t taken; |
| 195 | fd_set fds; | ||
| 196 | int ret; | ||
| 197 | ssize_t taken = 0; | ||
| 198 | if (sock == SOCK_INVALID) return IO_CLOSED; | 197 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 199 | tv.tv_sec = timeout / 1000; | 198 | taken = recv(sock, data, (int) count, 0); |
| 200 | tv.tv_usec = (timeout % 1000) * 1000; | 199 | if (taken <= 0) { |
| 201 | FD_ZERO(&fds); | 200 | struct timeval tv; |
| 202 | FD_SET(sock, &fds); | 201 | fd_set fds; |
| 203 | ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | 202 | int ret; |
| 204 | if (ret > 0) { | ||
| 205 | taken = recv(sock, data, count, 0); | ||
| 206 | if (taken <= 0) { | ||
| 207 | *got = 0; | ||
| 208 | return IO_CLOSED; | ||
| 209 | } else { | ||
| 210 | *got = taken; | ||
| 211 | return IO_DONE; | ||
| 212 | } | ||
| 213 | } else { | ||
| 214 | *got = 0; | 203 | *got = 0; |
| 215 | return IO_TIMEOUT; | 204 | if (taken == 0) return IO_CLOSED; |
| 205 | tv.tv_sec = timeout / 1000; | ||
| 206 | tv.tv_usec = (timeout % 1000) * 1000; | ||
| 207 | FD_ZERO(&fds); | ||
| 208 | FD_SET(sock, &fds); | ||
| 209 | ret = select(0, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | ||
| 210 | if (ret > 0) return IO_DONE; | ||
| 211 | else return IO_TIMEOUT; | ||
| 212 | } else { | ||
| 213 | *got = taken; | ||
| 214 | return IO_DONE; | ||
| 216 | } | 215 | } |
| 217 | } | 216 | } |
| 218 | 217 | ||
| @@ -223,28 +222,25 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
| 223 | SA *addr, socklen_t *addr_len, int timeout) | 222 | SA *addr, socklen_t *addr_len, int timeout) |
| 224 | { | 223 | { |
| 225 | t_sock sock = *ps; | 224 | t_sock sock = *ps; |
| 226 | struct timeval tv; | 225 | ssize_t taken; |
| 227 | fd_set fds; | ||
| 228 | int ret; | ||
| 229 | ssize_t taken = 0; | ||
| 230 | if (sock == SOCK_INVALID) return IO_CLOSED; | 226 | if (sock == SOCK_INVALID) return IO_CLOSED; |
| 231 | tv.tv_sec = timeout / 1000; | 227 | taken = recvfrom(sock, data, (int) count, 0, addr, addr_len); |
| 232 | tv.tv_usec = (timeout % 1000) * 1000; | 228 | if (taken <= 0) { |
| 233 | FD_ZERO(&fds); | 229 | struct timeval tv; |
| 234 | FD_SET(sock, &fds); | 230 | fd_set fds; |
| 235 | ret = select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | 231 | int ret; |
| 236 | if (ret > 0) { | ||
| 237 | taken = recvfrom(sock, data, count, 0, addr, addr_len); | ||
| 238 | if (taken <= 0) { | ||
| 239 | *got = 0; | ||
| 240 | return IO_CLOSED; | ||
| 241 | } else { | ||
| 242 | *got = taken; | ||
| 243 | return IO_DONE; | ||
| 244 | } | ||
| 245 | } else { | ||
| 246 | *got = 0; | 232 | *got = 0; |
| 247 | return IO_TIMEOUT; | 233 | if (taken == 0) return IO_CLOSED; |
| 234 | tv.tv_sec = timeout / 1000; | ||
| 235 | tv.tv_usec = (timeout % 1000) * 1000; | ||
| 236 | FD_ZERO(&fds); | ||
| 237 | FD_SET(sock, &fds); | ||
| 238 | ret = select(0, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); | ||
| 239 | if (ret > 0) return IO_DONE; | ||
| 240 | else return IO_TIMEOUT; | ||
| 241 | } else { | ||
| 242 | *got = taken; | ||
| 243 | return IO_DONE; | ||
| 248 | } | 244 | } |
| 249 | } | 245 | } |
| 250 | 246 | ||
