diff options
Diffstat (limited to 'src/usocket.c')
-rw-r--r-- | src/usocket.c | 96 |
1 files changed, 70 insertions, 26 deletions
diff --git a/src/usocket.c b/src/usocket.c index 062a0ff..cdd550c 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -1,49 +1,78 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * Socket compatibilization module for Unix | ||
3 | * LuaSocket toolkit | ||
4 | * | ||
5 | * RCS ID: $Id$ | ||
6 | \*=========================================================================*/ | ||
1 | #include <string.h> | 7 | #include <string.h> |
2 | 8 | ||
3 | #include "socket.h" | 9 | #include "socket.h" |
4 | 10 | ||
11 | /*-------------------------------------------------------------------------*\ | ||
12 | * Initializes module | ||
13 | \*-------------------------------------------------------------------------*/ | ||
5 | int sock_open(void) | 14 | int sock_open(void) |
6 | { | 15 | { |
7 | /* instals a handler to ignore sigpipe. */ | 16 | /* instals a handler to ignore sigpipe or it will crash us */ |
8 | struct sigaction new; | 17 | struct sigaction ignore; |
9 | memset(&new, 0, sizeof(new)); | 18 | memset(&ignore, 0, sizeof(ignore)); |
10 | new.sa_handler = SIG_IGN; | 19 | ignore.sa_handler = SIG_IGN; |
11 | sigaction(SIGPIPE, &new, NULL); | 20 | sigaction(SIGPIPE, &ignore, NULL); |
12 | return 1; | 21 | return 1; |
13 | } | 22 | } |
14 | 23 | ||
24 | /*-------------------------------------------------------------------------*\ | ||
25 | * Close and inutilize socket | ||
26 | \*-------------------------------------------------------------------------*/ | ||
15 | void sock_destroy(p_sock ps) | 27 | void sock_destroy(p_sock ps) |
16 | { | 28 | { |
17 | close(*ps); | 29 | close(*ps); |
30 | *ps = SOCK_INVALID; | ||
18 | } | 31 | } |
19 | 32 | ||
33 | /*-------------------------------------------------------------------------*\ | ||
34 | * Creates and sets up a socket | ||
35 | \*-------------------------------------------------------------------------*/ | ||
20 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 36 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
21 | { | 37 | { |
38 | int val = 1; | ||
22 | t_sock sock = socket(domain, type, protocol); | 39 | t_sock sock = socket(domain, type, protocol); |
23 | if (sock == SOCK_INVALID) return sock_createstrerror(); | 40 | if (sock == SOCK_INVALID) return sock_createstrerror(); |
24 | *ps = sock; | 41 | *ps = sock; |
25 | sock_setnonblocking(ps); | 42 | sock_setnonblocking(ps); |
26 | sock_setreuseaddr(ps); | 43 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); |
27 | return NULL; | 44 | return NULL; |
28 | } | 45 | } |
29 | 46 | ||
47 | /*-------------------------------------------------------------------------*\ | ||
48 | * Connects or returns error message | ||
49 | \*-------------------------------------------------------------------------*/ | ||
30 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) | 50 | const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len) |
31 | { | 51 | { |
32 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); | 52 | if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); |
33 | else return NULL; | 53 | else return NULL; |
34 | } | 54 | } |
35 | 55 | ||
56 | /*-------------------------------------------------------------------------*\ | ||
57 | * Binds or returns error message | ||
58 | \*-------------------------------------------------------------------------*/ | ||
36 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) | 59 | const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len) |
37 | { | 60 | { |
38 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); | 61 | if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); |
39 | else return NULL; | 62 | else return NULL; |
40 | } | 63 | } |
41 | 64 | ||
65 | /*-------------------------------------------------------------------------*\ | ||
66 | * | ||
67 | \*-------------------------------------------------------------------------*/ | ||
42 | void sock_listen(p_sock ps, int backlog) | 68 | void sock_listen(p_sock ps, int backlog) |
43 | { | 69 | { |
44 | listen(*ps, backlog); | 70 | listen(*ps, backlog); |
45 | } | 71 | } |
46 | 72 | ||
73 | /*-------------------------------------------------------------------------*\ | ||
74 | * Accept with timeout | ||
75 | \*-------------------------------------------------------------------------*/ | ||
47 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | 76 | int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, |
48 | int timeout) | 77 | int timeout) |
49 | { | 78 | { |
@@ -65,6 +94,9 @@ int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len, | |||
65 | else return IO_DONE; | 94 | else return IO_DONE; |
66 | } | 95 | } |
67 | 96 | ||
97 | /*-------------------------------------------------------------------------*\ | ||
98 | * Send with timeout | ||
99 | \*-------------------------------------------------------------------------*/ | ||
68 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | 100 | int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, |
69 | int timeout) | 101 | int timeout) |
70 | { | 102 | { |
@@ -99,6 +131,9 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, | |||
99 | } | 131 | } |
100 | } | 132 | } |
101 | 133 | ||
134 | /*-------------------------------------------------------------------------*\ | ||
135 | * Sendto with timeout | ||
136 | \*-------------------------------------------------------------------------*/ | ||
102 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | 137 | int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, |
103 | SA *addr, socklen_t addr_len, int timeout) | 138 | SA *addr, socklen_t addr_len, int timeout) |
104 | { | 139 | { |
@@ -133,6 +168,9 @@ int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, | |||
133 | } | 168 | } |
134 | } | 169 | } |
135 | 170 | ||
171 | /*-------------------------------------------------------------------------*\ | ||
172 | * Receive with timeout | ||
173 | \*-------------------------------------------------------------------------*/ | ||
136 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | 174 | int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) |
137 | { | 175 | { |
138 | t_sock sock = *ps; | 176 | t_sock sock = *ps; |
@@ -160,6 +198,9 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout) | |||
160 | } | 198 | } |
161 | } | 199 | } |
162 | 200 | ||
201 | /*-------------------------------------------------------------------------*\ | ||
202 | * Recvfrom with timeout | ||
203 | \*-------------------------------------------------------------------------*/ | ||
163 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | 204 | int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, |
164 | SA *addr, socklen_t *addr_len, int timeout) | 205 | SA *addr, socklen_t *addr_len, int timeout) |
165 | { | 206 | { |
@@ -188,6 +229,29 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, | |||
188 | } | 229 | } |
189 | } | 230 | } |
190 | 231 | ||
232 | /*-------------------------------------------------------------------------*\ | ||
233 | * Put socket into blocking mode | ||
234 | \*-------------------------------------------------------------------------*/ | ||
235 | void sock_setblocking(p_sock ps) | ||
236 | { | ||
237 | int flags = fcntl(*ps, F_GETFL, 0); | ||
238 | flags &= (~(O_NONBLOCK)); | ||
239 | fcntl(*ps, F_SETFL, flags); | ||
240 | } | ||
241 | |||
242 | /*-------------------------------------------------------------------------*\ | ||
243 | * Put socket into non-blocking mode | ||
244 | \*-------------------------------------------------------------------------*/ | ||
245 | void sock_setnonblocking(p_sock ps) | ||
246 | { | ||
247 | int flags = fcntl(*ps, F_GETFL, 0); | ||
248 | flags |= O_NONBLOCK; | ||
249 | fcntl(*ps, F_SETFL, flags); | ||
250 | } | ||
251 | |||
252 | /*-------------------------------------------------------------------------*\ | ||
253 | * Error translation functions | ||
254 | \*-------------------------------------------------------------------------*/ | ||
191 | const char *sock_hoststrerror(void) | 255 | const char *sock_hoststrerror(void) |
192 | { | 256 | { |
193 | switch (h_errno) { | 257 | switch (h_errno) { |
@@ -238,23 +302,3 @@ const char *sock_connectstrerror(void) | |||
238 | default: return "unknown error"; | 302 | default: return "unknown error"; |
239 | } | 303 | } |
240 | } | 304 | } |
241 | |||
242 | void sock_setreuseaddr(p_sock ps) | ||
243 | { | ||
244 | int val = 1; | ||
245 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); | ||
246 | } | ||
247 | |||
248 | void sock_setblocking(p_sock ps) | ||
249 | { | ||
250 | int flags = fcntl(*ps, F_GETFL, 0); | ||
251 | flags &= (~(O_NONBLOCK)); | ||
252 | fcntl(*ps, F_SETFL, flags); | ||
253 | } | ||
254 | |||
255 | void sock_setnonblocking(p_sock ps) | ||
256 | { | ||
257 | int flags = fcntl(*ps, F_GETFL, 0); | ||
258 | flags |= O_NONBLOCK; | ||
259 | fcntl(*ps, F_SETFL, flags); | ||
260 | } | ||