diff options
Diffstat (limited to 'src/tcp.c')
-rw-r--r-- | src/tcp.c | 54 |
1 files changed, 41 insertions, 13 deletions
@@ -22,6 +22,7 @@ | |||
22 | \*=========================================================================*/ | 22 | \*=========================================================================*/ |
23 | static int global_create(lua_State *L); | 23 | static int global_create(lua_State *L); |
24 | static int meth_connect(lua_State *L); | 24 | static int meth_connect(lua_State *L); |
25 | static int meth_listen(lua_State *L); | ||
25 | static int meth_bind(lua_State *L); | 26 | static int meth_bind(lua_State *L); |
26 | static int meth_send(lua_State *L); | 27 | static int meth_send(lua_State *L); |
27 | static int meth_getsockname(lua_State *L); | 28 | static int meth_getsockname(lua_State *L); |
@@ -32,7 +33,8 @@ static int meth_accept(lua_State *L); | |||
32 | static int meth_close(lua_State *L); | 33 | static int meth_close(lua_State *L); |
33 | static int meth_setoption(lua_State *L); | 34 | static int meth_setoption(lua_State *L); |
34 | static int meth_settimeout(lua_State *L); | 35 | static int meth_settimeout(lua_State *L); |
35 | static int meth_fd(lua_State *L); | 36 | static int meth_getfd(lua_State *L); |
37 | static int meth_setfd(lua_State *L); | ||
36 | static int meth_dirty(lua_State *L); | 38 | static int meth_dirty(lua_State *L); |
37 | 39 | ||
38 | /* tcp object methods */ | 40 | /* tcp object methods */ |
@@ -41,6 +43,7 @@ static luaL_reg tcp[] = { | |||
41 | {"send", meth_send}, | 43 | {"send", meth_send}, |
42 | {"receive", meth_receive}, | 44 | {"receive", meth_receive}, |
43 | {"bind", meth_bind}, | 45 | {"bind", meth_bind}, |
46 | {"listen", meth_listen}, | ||
44 | {"accept", meth_accept}, | 47 | {"accept", meth_accept}, |
45 | {"setpeername", meth_connect}, | 48 | {"setpeername", meth_connect}, |
46 | {"setsockname", meth_bind}, | 49 | {"setsockname", meth_bind}, |
@@ -51,7 +54,8 @@ static luaL_reg tcp[] = { | |||
51 | {"shutdown", meth_shutdown}, | 54 | {"shutdown", meth_shutdown}, |
52 | {"setoption", meth_setoption}, | 55 | {"setoption", meth_setoption}, |
53 | {"__gc", meth_close}, | 56 | {"__gc", meth_close}, |
54 | {"fd", meth_fd}, | 57 | {"getfd", meth_getfd}, |
58 | {"setfd", meth_setfd}, | ||
55 | {"dirty", meth_dirty}, | 59 | {"dirty", meth_dirty}, |
56 | {NULL, NULL} | 60 | {NULL, NULL} |
57 | }; | 61 | }; |
@@ -124,16 +128,24 @@ static int meth_setoption(lua_State *L) | |||
124 | /*-------------------------------------------------------------------------*\ | 128 | /*-------------------------------------------------------------------------*\ |
125 | * Select support methods | 129 | * Select support methods |
126 | \*-------------------------------------------------------------------------*/ | 130 | \*-------------------------------------------------------------------------*/ |
127 | static int meth_fd(lua_State *L) | 131 | static int meth_getfd(lua_State *L) |
128 | { | 132 | { |
129 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); | 133 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); |
130 | lua_pushnumber(L, tcp->sock); | 134 | lua_pushnumber(L, tcp->sock); |
131 | return 1; | 135 | return 1; |
132 | } | 136 | } |
133 | 137 | ||
138 | /* this is very dangerous, but can be handy for those that are brave enough */ | ||
139 | static int meth_setfd(lua_State *L) | ||
140 | { | ||
141 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | ||
142 | tcp->sock = (t_sock) luaL_checknumber(L, 2); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
134 | static int meth_dirty(lua_State *L) | 146 | static int meth_dirty(lua_State *L) |
135 | { | 147 | { |
136 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client,server}", 1); | 148 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); |
137 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); | 149 | lua_pushboolean(L, !buf_isempty(&tcp->buf)); |
138 | return 1; | 150 | return 1; |
139 | } | 151 | } |
@@ -147,9 +159,9 @@ static int meth_accept(lua_State *L) | |||
147 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); | 159 | p_tcp server = (p_tcp) aux_checkclass(L, "tcp{server}", 1); |
148 | p_tm tm = tm_markstart(&server->tm); | 160 | p_tm tm = tm_markstart(&server->tm); |
149 | t_sock sock; | 161 | t_sock sock; |
150 | int err = sock_accept(&server->sock, &sock, NULL, NULL, tm); | 162 | const char *err = sock_accept(&server->sock, &sock, NULL, NULL, tm); |
151 | /* if successful, push client socket */ | 163 | /* if successful, push client socket */ |
152 | if (err == IO_DONE) { | 164 | if (!err) { |
153 | p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp)); | 165 | p_tcp clnt = lua_newuserdata(L, sizeof(t_tcp)); |
154 | aux_setclass(L, "tcp{client}", -1); | 166 | aux_setclass(L, "tcp{client}", -1); |
155 | /* initialize structure fields */ | 167 | /* initialize structure fields */ |
@@ -160,28 +172,25 @@ static int meth_accept(lua_State *L) | |||
160 | return 1; | 172 | return 1; |
161 | } else { | 173 | } else { |
162 | lua_pushnil(L); | 174 | lua_pushnil(L); |
163 | io_pusherror(L, err); | 175 | lua_pushstring(L, err); |
164 | return 2; | 176 | return 2; |
165 | } | 177 | } |
166 | } | 178 | } |
167 | 179 | ||
168 | /*-------------------------------------------------------------------------*\ | 180 | /*-------------------------------------------------------------------------*\ |
169 | * Turns a master object into a server object | 181 | * Binds an object to an address |
170 | \*-------------------------------------------------------------------------*/ | 182 | \*-------------------------------------------------------------------------*/ |
171 | static int meth_bind(lua_State *L) | 183 | static int meth_bind(lua_State *L) |
172 | { | 184 | { |
173 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | 185 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); |
174 | const char *address = luaL_checkstring(L, 2); | 186 | const char *address = luaL_checkstring(L, 2); |
175 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 187 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); |
176 | int backlog = (int) luaL_optnumber(L, 4, 1); | 188 | const char *err = inet_trybind(&tcp->sock, address, port); |
177 | const char *err = inet_trybind(&tcp->sock, address, port, backlog); | ||
178 | if (err) { | 189 | if (err) { |
179 | lua_pushnil(L); | 190 | lua_pushnil(L); |
180 | lua_pushstring(L, err); | 191 | lua_pushstring(L, err); |
181 | return 2; | 192 | return 2; |
182 | } | 193 | } |
183 | /* turn master object into a server object if there was a listen */ | ||
184 | if (backlog >= 0) aux_setclass(L, "tcp{server}", 1); | ||
185 | lua_pushnumber(L, 1); | 194 | lua_pushnumber(L, 1); |
186 | return 1; | 195 | return 1; |
187 | } | 196 | } |
@@ -218,6 +227,25 @@ static int meth_close(lua_State *L) | |||
218 | } | 227 | } |
219 | 228 | ||
220 | /*-------------------------------------------------------------------------*\ | 229 | /*-------------------------------------------------------------------------*\ |
230 | * Puts the sockt in listen mode | ||
231 | \*-------------------------------------------------------------------------*/ | ||
232 | static int meth_listen(lua_State *L) | ||
233 | { | ||
234 | p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{master}", 1); | ||
235 | int backlog = (int) luaL_checknumber(L, 2); | ||
236 | const char *err = sock_listen(&tcp->sock, backlog); | ||
237 | if (err) { | ||
238 | lua_pushnil(L); | ||
239 | lua_pushstring(L, err); | ||
240 | return 2; | ||
241 | } | ||
242 | /* turn master object into a server object */ | ||
243 | aux_setclass(L, "tcp{server}", 1); | ||
244 | lua_pushnumber(L, 1); | ||
245 | return 1; | ||
246 | } | ||
247 | |||
248 | /*-------------------------------------------------------------------------*\ | ||
221 | * Shuts the connection down partially | 249 | * Shuts the connection down partially |
222 | \*-------------------------------------------------------------------------*/ | 250 | \*-------------------------------------------------------------------------*/ |
223 | static int meth_shutdown(lua_State *L) | 251 | static int meth_shutdown(lua_State *L) |