aboutsummaryrefslogtreecommitdiff
path: root/src/usocket.c
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-01-17 00:17:46 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-01-17 00:17:46 +0000
commit076451c75336b30e6152bd5c02f355db39107f7d (patch)
tree785a6c71ca1e5246f2ce09a9b91f98eb902ac2a0 /src/usocket.c
parent89f3ecf7820857f91c4039536d2bbe3cf12d5f95 (diff)
downloadluasocket-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.c92
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