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