aboutsummaryrefslogtreecommitdiff
path: root/src/usocket.c
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2004-01-21 18:40:52 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2004-01-21 18:40:52 +0000
commit195069cf5f929f445b0ce20e531cd482d2559083 (patch)
tree6444d37c4ce32395428ba26ee0d16c0c372bd9da /src/usocket.c
parente63f500d24ff0238425c9e13f220daf09a277ef5 (diff)
downloadluasocket-195069cf5f929f445b0ce20e531cd482d2559083.tar.gz
luasocket-195069cf5f929f445b0ce20e531cd482d2559083.tar.bz2
luasocket-195069cf5f929f445b0ce20e531cd482d2559083.zip
Fixed functions that return messages in ?socket.c.
Moved complexity of connect and accept there. Created a new options.c module to take care of options. Auxiliar.c is now cleaner.
Diffstat (limited to 'src/usocket.c')
-rw-r--r--src/usocket.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/src/usocket.c b/src/usocket.c
index f5939a9..54f203b 100644
--- a/src/usocket.c
+++ b/src/usocket.c
@@ -20,6 +20,10 @@
20 20
21#include "socket.h" 21#include "socket.h"
22 22
23static const char *sock_createstrerror(void);
24static const char *sock_bindstrerror(void);
25static const char *sock_connectstrerror(void);
26
23/*-------------------------------------------------------------------------*\ 27/*-------------------------------------------------------------------------*\
24* Initializes module 28* Initializes module
25\*-------------------------------------------------------------------------*/ 29\*-------------------------------------------------------------------------*/
@@ -50,31 +54,37 @@ void sock_destroy(p_sock ps)
50/*-------------------------------------------------------------------------*\ 54/*-------------------------------------------------------------------------*\
51* Creates and sets up a socket 55* Creates and sets up a socket
52\*-------------------------------------------------------------------------*/ 56\*-------------------------------------------------------------------------*/
53int sock_create(p_sock ps, int domain, int type, int protocol) 57const char *sock_create(p_sock ps, int domain, int type, int protocol)
54{ 58{
55 int val = 1; 59 int val = 1;
56 t_sock sock = socket(domain, type, protocol); 60 t_sock sock = socket(domain, type, protocol);
57 if (sock == SOCK_INVALID) return IO_ERROR; 61 if (sock == SOCK_INVALID) return sock_createstrerror();
58 *ps = sock; 62 *ps = sock;
59 sock_setnonblocking(ps); 63 sock_setnonblocking(ps);
60 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); 64 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val));
61 return IO_DONE; 65 return NULL;
62} 66}
63 67
64/*-------------------------------------------------------------------------*\ 68/*-------------------------------------------------------------------------*\
65* Connects or returns error message 69* Connects or returns error message
66\*-------------------------------------------------------------------------*/ 70\*-------------------------------------------------------------------------*/
67int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, int timeout) 71const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm)
68{ 72{
69 t_sock sock = *ps; 73 t_sock sock = *ps;
70 if (sock == SOCK_INVALID) return IO_CLOSED; 74 int err;
71 /* if connect fails, we have to find out why */ 75 /* don't call on closed socket */
72 if (connect(sock, addr, addr_len) < 0) { 76 if (sock == SOCK_INVALID) return io_strerror(IO_CLOSED);
77 /* ask system to connect */
78 err = connect(sock, addr, addr_len);
79 /* if no error, we're done */
80 if (err == 0) return NULL;
81 /* make sure the system is trying to connect */
82 if (errno != EINPROGRESS) return io_strerror(IO_ERROR);
83 /* wait for a timeout or for the system's answer */
84 for ( ;; ) {
73 struct timeval tv; 85 struct timeval tv;
74 fd_set rfds, efds, wfds; 86 fd_set rfds, wfds, efds;
75 int err; 87 int timeout = tm_getretry(tm);
76 /* make sure the system is trying to connect */
77 if (errno != EINPROGRESS) return IO_ERROR;
78 tv.tv_sec = timeout / 1000; 88 tv.tv_sec = timeout / 1000;
79 tv.tv_usec = (timeout % 1000) * 1000; 89 tv.tv_usec = (timeout % 1000) * 1000;
80 FD_ZERO(&rfds); FD_SET(sock, &rfds); 90 FD_ZERO(&rfds); FD_SET(sock, &rfds);
@@ -82,28 +92,29 @@ int sock_connect(p_sock ps, SA *addr, socklen_t addr_len, int timeout)
82 FD_ZERO(&efds); FD_SET(sock, &efds); 92 FD_ZERO(&efds); FD_SET(sock, &efds);
83 /* we run select to avoid busy waiting */ 93 /* we run select to avoid busy waiting */
84 err = select(sock+1, &rfds, &wfds, &efds, timeout >= 0? &tv: NULL); 94 err = select(sock+1, &rfds, &wfds, &efds, timeout >= 0? &tv: NULL);
85 /* if select was interrupted, ask the user to retry */ 95 /* if select was interrupted, try again */
86 if (err < 0 && errno == EINTR) return IO_RETRY; 96 if (err < 0 && errno == EINTR) continue;
87 /* if selects readable, try reading */ 97 /* if selects readable, try reading */
88 if (err > 0) { 98 if (err > 0) {
89 char dummy; 99 char dummy;
90 /* try reading so that errno is set */ 100 /* recv will set errno to the value a blocking connect would set */
91 if (recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN) 101 if (recv(sock, &dummy, 0, 0) < 0 && errno != EAGAIN)
92 return IO_ERROR; 102 return sock_connectstrerror();
93 else return IO_DONE; 103 else
104 return NULL;
94 /* if no event happened, there was a timeout */ 105 /* if no event happened, there was a timeout */
95 } else return IO_TIMEOUT; 106 } else return io_strerror(IO_TIMEOUT);
96 /* otherwise connection succeeded */ 107 }
97 } else return IO_DONE; 108 return io_strerror(IO_TIMEOUT); /* can't get here */
98} 109}
99 110
100/*-------------------------------------------------------------------------*\ 111/*-------------------------------------------------------------------------*\
101* Binds or returns error message 112* Binds or returns error message
102\*-------------------------------------------------------------------------*/ 113\*-------------------------------------------------------------------------*/
103int sock_bind(p_sock ps, SA *addr, socklen_t addr_len) 114const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
104{ 115{
105 if (bind(*ps, addr, addr_len) < 0) return IO_ERROR; 116 if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
106 else return IO_DONE; 117 else return NULL;
107} 118}
108 119
109/*-------------------------------------------------------------------------*\ 120/*-------------------------------------------------------------------------*\
@@ -125,8 +136,7 @@ void sock_shutdown(p_sock ps, int how)
125/*-------------------------------------------------------------------------*\ 136/*-------------------------------------------------------------------------*\
126* Accept with timeout 137* Accept with timeout
127\*-------------------------------------------------------------------------*/ 138\*-------------------------------------------------------------------------*/
128int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, 139int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, p_tm tm)
129 int timeout)
130{ 140{
131 t_sock sock = *ps; 141 t_sock sock = *ps;
132 SA dummy_addr; 142 SA dummy_addr;
@@ -134,19 +144,21 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
134 if (sock == SOCK_INVALID) return IO_CLOSED; 144 if (sock == SOCK_INVALID) return IO_CLOSED;
135 if (!addr) addr = &dummy_addr; 145 if (!addr) addr = &dummy_addr;
136 if (!addr_len) addr_len = &dummy_len; 146 if (!addr_len) addr_len = &dummy_len;
137 *pa = accept(sock, addr, addr_len); 147 for (;;) {
138 if (*pa == SOCK_INVALID) { 148 int timeout = tm_getretry(tm);
139 struct timeval tv; 149 struct timeval tv;
140 fd_set fds; 150 fd_set fds;
151 *pa = accept(sock, addr, addr_len);
152 if (*pa != SOCK_INVALID) return IO_DONE;
153 if (timeout == 0) return IO_TIMEOUT;
141 tv.tv_sec = timeout / 1000; 154 tv.tv_sec = timeout / 1000;
142 tv.tv_usec = (timeout % 1000) * 1000; 155 tv.tv_usec = (timeout % 1000) * 1000;
143 FD_ZERO(&fds); 156 FD_ZERO(&fds);
144 FD_SET(sock, &fds); 157 FD_SET(sock, &fds);
145 /* just call select to avoid busy-wait. doesn't really matter 158 /* call select just to avoid busy-wait. */
146 * what happens. the caller will choose to retry or not */
147 select(sock+1, &fds, NULL, NULL, timeout >= 0? &tv: NULL); 159 select(sock+1, &fds, NULL, NULL, timeout >= 0? &tv: NULL);
148 return IO_RETRY; 160 }
149 } else return IO_DONE; 161 return IO_TIMEOUT; /* can't get here */
150} 162}
151 163
152/*-------------------------------------------------------------------------*\ 164/*-------------------------------------------------------------------------*\
@@ -314,7 +326,7 @@ const char *sock_hoststrerror(void)
314 } 326 }
315} 327}
316 328
317const char *sock_createstrerror(void) 329static const char *sock_createstrerror(void)
318{ 330{
319 switch (errno) { 331 switch (errno) {
320 case EACCES: return "access denied"; 332 case EACCES: return "access denied";
@@ -325,7 +337,7 @@ const char *sock_createstrerror(void)
325 } 337 }
326} 338}
327 339
328const char *sock_bindstrerror(void) 340static const char *sock_bindstrerror(void)
329{ 341{
330 switch (errno) { 342 switch (errno) {
331 case EBADF: return "invalid descriptor"; 343 case EBADF: return "invalid descriptor";
@@ -339,7 +351,7 @@ const char *sock_bindstrerror(void)
339 } 351 }
340} 352}
341 353
342const char *sock_connectstrerror(void) 354static const char *sock_connectstrerror(void)
343{ 355{
344 switch (errno) { 356 switch (errno) {
345 case EBADF: return "invalid descriptor"; 357 case EBADF: return "invalid descriptor";