aboutsummaryrefslogtreecommitdiff
path: root/src/usocket.c
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-09 18:23:40 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-09 18:23:40 +0000
commit58bdb658aaa1c30a8f3bed46eef880d308fae582 (patch)
tree5bf880c715daff79c1a2062f2f3ae8336858c83f /src/usocket.c
parentb2724ad2d1cc3768a04270ed3f8014ec65ad133b (diff)
downloadluasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.tar.gz
luasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.tar.bz2
luasocket-58bdb658aaa1c30a8f3bed46eef880d308fae582.zip
Select re-implemented in a nicer way.
Few changes in internal class and group registration. Lua modules are compiled and built into library. Dynamic library tested in Linux and Mac OS X.
Diffstat (limited to 'src/usocket.c')
-rw-r--r--src/usocket.c119
1 files changed, 16 insertions, 103 deletions
diff --git a/src/usocket.c b/src/usocket.c
index b4b8d5a..062a0ff 100644
--- a/src/usocket.c
+++ b/src/usocket.c
@@ -1,24 +1,8 @@
1/*=========================================================================*\
2* Socket compatibilization module for Unix
3*
4* RCS ID: $Id$
5\*=========================================================================*/
6#include <lua.h>
7#include <lauxlib.h>
8#include <string.h> 1#include <string.h>
9 2
10#include "sock.h" 3#include "socket.h"
11 4
12/*=========================================================================*\ 5int sock_open(void)
13* Internal function prototypes
14\*=========================================================================*/
15static const char *try_setoption(lua_State *L, p_sock ps);
16static const char *try_setbooloption(lua_State *L, p_sock ps, int name);
17
18/*=========================================================================*\
19* Exported functions.
20\*=========================================================================*/
21int sock_open(lua_State *L)
22{ 6{
23 /* instals a handler to ignore sigpipe. */ 7 /* instals a handler to ignore sigpipe. */
24 struct sigaction new; 8 struct sigaction new;
@@ -43,13 +27,13 @@ const char *sock_create(p_sock ps, int domain, int type, int protocol)
43 return NULL; 27 return NULL;
44} 28}
45 29
46const char *sock_connect(p_sock ps, SA *addr, size_t addr_len) 30const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len)
47{ 31{
48 if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror(); 32 if (connect(*ps, addr, addr_len) < 0) return sock_connectstrerror();
49 else return NULL; 33 else return NULL;
50} 34}
51 35
52const char *sock_bind(p_sock ps, SA *addr, size_t addr_len) 36const char *sock_bind(p_sock ps, SA *addr, socklen_t addr_len)
53{ 37{
54 if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror(); 38 if (bind(*ps, addr, addr_len) < 0) return sock_bindstrerror();
55 else return NULL; 39 else return NULL;
@@ -60,17 +44,25 @@ void sock_listen(p_sock ps, int backlog)
60 listen(*ps, backlog); 44 listen(*ps, backlog);
61} 45}
62 46
63void sock_accept(p_sock ps, p_sock pa, SA *addr, size_t *addr_len, int timeout) 47int sock_accept(p_sock ps, p_sock pa, SA *addr, socklen_t *addr_len,
48 int timeout)
64{ 49{
65 t_sock sock = *ps; 50 t_sock sock = *ps;
66 struct timeval tv; 51 struct timeval tv;
52 SA dummy_addr;
53 socklen_t dummy_len;
67 fd_set fds; 54 fd_set fds;
68 tv.tv_sec = timeout / 1000; 55 tv.tv_sec = timeout / 1000;
69 tv.tv_usec = (timeout % 1000) * 1000; 56 tv.tv_usec = (timeout % 1000) * 1000;
70 FD_ZERO(&fds); 57 FD_ZERO(&fds);
71 FD_SET(sock, &fds); 58 FD_SET(sock, &fds);
72 select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL); 59 if (select(sock+1, &fds, NULL, NULL, timeout >= 0 ? &tv : NULL) <= 0)
60 return IO_TIMEOUT;
61 if (!addr) addr = &dummy_addr;
62 if (!addr_len) addr_len = &dummy_len;
73 *pa = accept(sock, addr, addr_len); 63 *pa = accept(sock, addr, addr_len);
64 if (*pa == SOCK_INVALID) return IO_ERROR;
65 else return IO_DONE;
74} 66}
75 67
76int sock_send(p_sock ps, const char *data, size_t count, size_t *sent, 68int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
@@ -108,7 +100,7 @@ int sock_send(p_sock ps, const char *data, size_t count, size_t *sent,
108} 100}
109 101
110int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent, 102int sock_sendto(p_sock ps, const char *data, size_t count, size_t *sent,
111 SA *addr, size_t addr_len, int timeout) 103 SA *addr, socklen_t addr_len, int timeout)
112{ 104{
113 t_sock sock = *ps; 105 t_sock sock = *ps;
114 struct timeval tv; 106 struct timeval tv;
@@ -169,7 +161,7 @@ int sock_recv(p_sock ps, char *data, size_t count, size_t *got, int timeout)
169} 161}
170 162
171int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got, 163int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
172 SA *addr, size_t *addr_len, int timeout) 164 SA *addr, socklen_t *addr_len, int timeout)
173{ 165{
174 t_sock sock = *ps; 166 t_sock sock = *ps;
175 struct timeval tv; 167 struct timeval tv;
@@ -196,9 +188,6 @@ int sock_recvfrom(p_sock ps, char *data, size_t count, size_t *got,
196 } 188 }
197} 189}
198 190
199/*-------------------------------------------------------------------------*\
200* Returns a string describing the last host manipulation error.
201\*-------------------------------------------------------------------------*/
202const char *sock_hoststrerror(void) 191const char *sock_hoststrerror(void)
203{ 192{
204 switch (h_errno) { 193 switch (h_errno) {
@@ -210,9 +199,6 @@ const char *sock_hoststrerror(void)
210 } 199 }
211} 200}
212 201
213/*-------------------------------------------------------------------------*\
214* Returns a string describing the last socket manipulation error.
215\*-------------------------------------------------------------------------*/
216const char *sock_createstrerror(void) 202const char *sock_createstrerror(void)
217{ 203{
218 switch (errno) { 204 switch (errno) {
@@ -224,9 +210,6 @@ const char *sock_createstrerror(void)
224 } 210 }
225} 211}
226 212
227/*-------------------------------------------------------------------------*\
228* Returns a string describing the last bind command error.
229\*-------------------------------------------------------------------------*/
230const char *sock_bindstrerror(void) 213const char *sock_bindstrerror(void)
231{ 214{
232 switch (errno) { 215 switch (errno) {
@@ -241,9 +224,6 @@ const char *sock_bindstrerror(void)
241 } 224 }
242} 225}
243 226
244/*-------------------------------------------------------------------------*\
245* Returns a string describing the last connect error.
246\*-------------------------------------------------------------------------*/
247const char *sock_connectstrerror(void) 227const char *sock_connectstrerror(void)
248{ 228{
249 switch (errno) { 229 switch (errno) {
@@ -259,20 +239,12 @@ const char *sock_connectstrerror(void)
259 } 239 }
260} 240}
261 241
262/*-------------------------------------------------------------------------*\
263* Sets the SO_REUSEADDR socket option
264* Input
265* sock: socket descriptor
266\*-------------------------------------------------------------------------*/
267void sock_setreuseaddr(p_sock ps) 242void sock_setreuseaddr(p_sock ps)
268{ 243{
269 int val = 1; 244 int val = 1;
270 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); 245 setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
271} 246}
272 247
273/*-------------------------------------------------------------------------*\
274* Put socket into blocking mode.
275\*-------------------------------------------------------------------------*/
276void sock_setblocking(p_sock ps) 248void sock_setblocking(p_sock ps)
277{ 249{
278 int flags = fcntl(*ps, F_GETFL, 0); 250 int flags = fcntl(*ps, F_GETFL, 0);
@@ -280,68 +252,9 @@ void sock_setblocking(p_sock ps)
280 fcntl(*ps, F_SETFL, flags); 252 fcntl(*ps, F_SETFL, flags);
281} 253}
282 254
283/*-------------------------------------------------------------------------*\
284* Put socket into non-blocking mode.
285\*-------------------------------------------------------------------------*/
286void sock_setnonblocking(p_sock ps) 255void sock_setnonblocking(p_sock ps)
287{ 256{
288 int flags = fcntl(*ps, F_GETFL, 0); 257 int flags = fcntl(*ps, F_GETFL, 0);
289 flags |= O_NONBLOCK; 258 flags |= O_NONBLOCK;
290 fcntl(*ps, F_SETFL, flags); 259 fcntl(*ps, F_SETFL, flags);
291} 260}
292
293/*-------------------------------------------------------------------------*\
294* Tries to set extended udp socket options
295* Input
296* udp: udp structure
297* oldtop: top of stack
298* Returns
299* NULL if successfull, error message on error
300\*-------------------------------------------------------------------------*/
301const char *sock_trysetoptions(lua_State *L, p_sock ps)
302{
303 if (!lua_istable(L, 1)) luaL_argerror(L, 1, "invalid options table");
304 lua_pushnil(L);
305 while (lua_next(L, 1)) {
306 const char *err = try_setoption(L, ps);
307 lua_pop(L, 1);
308 if (err) return err;
309 }
310 return NULL;
311}
312
313/*-------------------------------------------------------------------------*\
314* Set socket options from a table on top of Lua stack.
315* Supports SO_KEEPALIVE, SO_DONTROUTE, and SO_BROADCAST options.
316* Input
317* sock: socket
318* Returns
319* 1 if successful, 0 otherwise
320\*-------------------------------------------------------------------------*/
321static const char *try_setoption(lua_State *L, p_sock ps)
322{
323 static const char *options[] = {
324 "SO_KEEPALIVE", "SO_DONTROUTE", "SO_BROADCAST", NULL
325 };
326 const char *option = lua_tostring(L, -2);
327 if (!lua_isstring(L, -2)) return "invalid option";
328 switch (luaL_findstring(option, options)) {
329 case 0: return try_setbooloption(L, ps, SO_KEEPALIVE);
330 case 1: return try_setbooloption(L, ps, SO_DONTROUTE);
331 case 2: return try_setbooloption(L, ps, SO_BROADCAST);
332 default: return "unsupported option";
333 }
334}
335
336/*=========================================================================*\
337* Internal functions.
338\*=========================================================================*/
339static const char *try_setbooloption(lua_State *L, p_sock ps, int name)
340{
341 int bool, res;
342 if (!lua_isnumber(L, -1)) luaL_error(L, "invalid option value");
343 bool = (int) lua_tonumber(L, -1);
344 res = setsockopt(*ps, SOL_SOCKET, name, (char *) &bool, sizeof(bool));
345 if (res < 0) return "error setting option";
346 else return NULL;
347}