diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-07-01 03:32:09 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-07-01 03:32:09 +0000 |
| commit | 7115c12fbc9aae1cd46fdf049697a27fb996181a (patch) | |
| tree | 2e918f54f729766701aabdef488a6461bc623da1 /src/udp.c | |
| parent | 7aaba59909e8527190694285f56ca68772c97f6a (diff) | |
| download | luasocket-7115c12fbc9aae1cd46fdf049697a27fb996181a.tar.gz luasocket-7115c12fbc9aae1cd46fdf049697a27fb996181a.tar.bz2 luasocket-7115c12fbc9aae1cd46fdf049697a27fb996181a.zip | |
Moving on to beta2.
Diffstat (limited to 'src/udp.c')
| -rw-r--r-- | src/udp.c | 105 |
1 files changed, 49 insertions, 56 deletions
| @@ -41,25 +41,26 @@ static int meth_settimeout(lua_State *L); | |||
| 41 | static int meth_getfd(lua_State *L); | 41 | static int meth_getfd(lua_State *L); |
| 42 | static int meth_setfd(lua_State *L); | 42 | static int meth_setfd(lua_State *L); |
| 43 | static int meth_dirty(lua_State *L); | 43 | static int meth_dirty(lua_State *L); |
| 44 | static void pusherror(lua_State *L, int code); | ||
| 44 | 45 | ||
| 45 | /* udp object methods */ | 46 | /* udp object methods */ |
| 46 | static luaL_reg udp[] = { | 47 | static luaL_reg udp[] = { |
| 47 | {"setpeername", meth_setpeername}, | ||
| 48 | {"setsockname", meth_setsockname}, | ||
| 49 | {"getsockname", meth_getsockname}, | ||
| 50 | {"getpeername", meth_getpeername}, | ||
| 51 | {"send", meth_send}, | ||
| 52 | {"sendto", meth_sendto}, | ||
| 53 | {"receive", meth_receive}, | ||
| 54 | {"receivefrom", meth_receivefrom}, | ||
| 55 | {"settimeout", meth_settimeout}, | ||
| 56 | {"close", meth_close}, | ||
| 57 | {"setoption", meth_setoption}, | ||
| 58 | {"__gc", meth_close}, | 48 | {"__gc", meth_close}, |
| 59 | {"__tostring", aux_tostring}, | 49 | {"__tostring", aux_tostring}, |
| 50 | {"close", meth_close}, | ||
| 51 | {"dirty", meth_dirty}, | ||
| 60 | {"getfd", meth_getfd}, | 52 | {"getfd", meth_getfd}, |
| 53 | {"getpeername", meth_getpeername}, | ||
| 54 | {"getsockname", meth_getsockname}, | ||
| 55 | {"receive", meth_receive}, | ||
| 56 | {"receivefrom", meth_receivefrom}, | ||
| 57 | {"send", meth_send}, | ||
| 58 | {"sendto", meth_sendto}, | ||
| 61 | {"setfd", meth_setfd}, | 59 | {"setfd", meth_setfd}, |
| 62 | {"dirty", meth_dirty}, | 60 | {"setoption", meth_setoption}, |
| 61 | {"setpeername", meth_setpeername}, | ||
| 62 | {"setsockname", meth_setsockname}, | ||
| 63 | {"settimeout", meth_settimeout}, | ||
| 63 | {NULL, NULL} | 64 | {NULL, NULL} |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| @@ -99,35 +100,43 @@ int udp_open(lua_State *L) | |||
| 99 | return 0; | 100 | return 0; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 103 | |||
| 102 | /*=========================================================================*\ | 104 | /*=========================================================================*\ |
| 103 | * Lua methods | 105 | * Lua methods |
| 104 | \*=========================================================================*/ | 106 | \*=========================================================================*/ |
| 105 | /*-------------------------------------------------------------------------*\ | 107 | /*-------------------------------------------------------------------------*\ |
| 108 | * Pushes the error message | ||
| 109 | \*-------------------------------------------------------------------------*/ | ||
| 110 | void pusherror(lua_State *L, int code) { | ||
| 111 | const char *err = code != IO_USER? io_strerror(code): "refused"; | ||
| 112 | err = err? err: sock_strerror(); | ||
| 113 | if (err) lua_pushstring(L, err); | ||
| 114 | else lua_pushnil(L); | ||
| 115 | } | ||
| 116 | |||
| 117 | /*-------------------------------------------------------------------------*\ | ||
| 106 | * Send data through connected udp socket | 118 | * Send data through connected udp socket |
| 107 | \*-------------------------------------------------------------------------*/ | 119 | \*-------------------------------------------------------------------------*/ |
| 108 | static int meth_send(lua_State *L) | 120 | static int meth_send(lua_State *L) { |
| 109 | { | ||
| 110 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); | 121 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
| 111 | p_tm tm = &udp->tm; | 122 | p_tm tm = &udp->tm; |
| 112 | size_t count, sent = 0; | 123 | size_t count, sent = 0; |
| 113 | int err; | 124 | int err; |
| 114 | const char *data = luaL_checklstring(L, 2, &count); | 125 | const char *data = luaL_checklstring(L, 2, &count); |
| 115 | tm_markstart(tm); | 126 | tm_markstart(tm); |
| 116 | do err = sock_send(&udp->sock, data, count, &sent, tm_getretry(tm)); | 127 | err = sock_send(&udp->sock, data, count, &sent, tm); |
| 117 | while (err == IO_RETRY); | ||
| 118 | if (err == IO_DONE) lua_pushnumber(L, sent); | 128 | if (err == IO_DONE) lua_pushnumber(L, sent); |
| 119 | else lua_pushnil(L); | 129 | else lua_pushnil(L); |
| 120 | /* a 'closed' error on an unconnected means the target address was not | 130 | /* a 'closed' error on an unconnected means the target address was not |
| 121 | * accepted by the transport layer */ | 131 | * accepted by the transport layer */ |
| 122 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | 132 | pusherror(L, err == IO_CLOSED ? IO_USER : err); |
| 123 | return 2; | 133 | return 2; |
| 124 | } | 134 | } |
| 125 | 135 | ||
| 126 | /*-------------------------------------------------------------------------*\ | 136 | /*-------------------------------------------------------------------------*\ |
| 127 | * Send data through unconnected udp socket | 137 | * Send data through unconnected udp socket |
| 128 | \*-------------------------------------------------------------------------*/ | 138 | \*-------------------------------------------------------------------------*/ |
| 129 | static int meth_sendto(lua_State *L) | 139 | static int meth_sendto(lua_State *L) { |
| 130 | { | ||
| 131 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 140 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
| 132 | size_t count, sent = 0; | 141 | size_t count, sent = 0; |
| 133 | const char *data = luaL_checklstring(L, 2, &count); | 142 | const char *data = luaL_checklstring(L, 2, &count); |
| @@ -142,22 +151,20 @@ static int meth_sendto(lua_State *L) | |||
| 142 | addr.sin_family = AF_INET; | 151 | addr.sin_family = AF_INET; |
| 143 | addr.sin_port = htons(port); | 152 | addr.sin_port = htons(port); |
| 144 | tm_markstart(tm); | 153 | tm_markstart(tm); |
| 145 | do err = sock_sendto(&udp->sock, data, count, &sent, | 154 | err = sock_sendto(&udp->sock, data, count, &sent, |
| 146 | (SA *) &addr, sizeof(addr), tm_get(tm)); | 155 | (SA *) &addr, sizeof(addr), tm); |
| 147 | while (err == IO_RETRY); | ||
| 148 | if (err == IO_DONE) lua_pushnumber(L, sent); | 156 | if (err == IO_DONE) lua_pushnumber(L, sent); |
| 149 | else lua_pushnil(L); | 157 | else lua_pushnil(L); |
| 150 | /* a 'closed' error on an unconnected means the target address was not | 158 | /* a 'closed' error on an unconnected means the target address was not |
| 151 | * accepted by the transport layer */ | 159 | * accepted by the transport layer */ |
| 152 | io_pusherror(L, err == IO_CLOSED ? IO_REFUSED : err); | 160 | pusherror(L, err == IO_CLOSED ? IO_USER : err); |
| 153 | return 2; | 161 | return 2; |
| 154 | } | 162 | } |
| 155 | 163 | ||
| 156 | /*-------------------------------------------------------------------------*\ | 164 | /*-------------------------------------------------------------------------*\ |
| 157 | * Receives data from a UDP socket | 165 | * Receives data from a UDP socket |
| 158 | \*-------------------------------------------------------------------------*/ | 166 | \*-------------------------------------------------------------------------*/ |
| 159 | static int meth_receive(lua_State *L) | 167 | static int meth_receive(lua_State *L) { |
| 160 | { | ||
| 161 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 168 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 162 | char buffer[UDP_DATAGRAMSIZE]; | 169 | char buffer[UDP_DATAGRAMSIZE]; |
| 163 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | 170 | size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); |
| @@ -165,19 +172,17 @@ static int meth_receive(lua_State *L) | |||
| 165 | p_tm tm = &udp->tm; | 172 | p_tm tm = &udp->tm; |
| 166 | count = MIN(count, sizeof(buffer)); | 173 | count = MIN(count, sizeof(buffer)); |
| 167 | tm_markstart(tm); | 174 | tm_markstart(tm); |
| 168 | do err = sock_recv(&udp->sock, buffer, count, &got, tm_get(tm)); | 175 | err = sock_recv(&udp->sock, buffer, count, &got, tm); |
| 169 | while (err == IO_RETRY); | ||
| 170 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); | 176 | if (err == IO_DONE) lua_pushlstring(L, buffer, got); |
| 171 | else lua_pushnil(L); | 177 | else lua_pushnil(L); |
| 172 | io_pusherror(L, err); | 178 | pusherror(L, err); |
| 173 | return 2; | 179 | return 2; |
| 174 | } | 180 | } |
| 175 | 181 | ||
| 176 | /*-------------------------------------------------------------------------*\ | 182 | /*-------------------------------------------------------------------------*\ |
| 177 | * Receives data and sender from a UDP socket | 183 | * Receives data and sender from a UDP socket |
| 178 | \*-------------------------------------------------------------------------*/ | 184 | \*-------------------------------------------------------------------------*/ |
| 179 | static int meth_receivefrom(lua_State *L) | 185 | static int meth_receivefrom(lua_State *L) { |
| 180 | { | ||
| 181 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 186 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
| 182 | struct sockaddr_in addr; | 187 | struct sockaddr_in addr; |
| 183 | socklen_t addr_len = sizeof(addr); | 188 | socklen_t addr_len = sizeof(addr); |
| @@ -187,9 +192,8 @@ static int meth_receivefrom(lua_State *L) | |||
| 187 | p_tm tm = &udp->tm; | 192 | p_tm tm = &udp->tm; |
| 188 | tm_markstart(tm); | 193 | tm_markstart(tm); |
| 189 | count = MIN(count, sizeof(buffer)); | 194 | count = MIN(count, sizeof(buffer)); |
| 190 | do err = sock_recvfrom(&udp->sock, buffer, count, &got, | 195 | err = sock_recvfrom(&udp->sock, buffer, count, &got, |
| 191 | (SA *) &addr, &addr_len, tm_get(tm)); | 196 | (SA *) &addr, &addr_len, tm); |
| 192 | while (err == IO_RETRY); | ||
| 193 | if (err == IO_DONE) { | 197 | if (err == IO_DONE) { |
| 194 | lua_pushlstring(L, buffer, got); | 198 | lua_pushlstring(L, buffer, got); |
| 195 | lua_pushstring(L, inet_ntoa(addr.sin_addr)); | 199 | lua_pushstring(L, inet_ntoa(addr.sin_addr)); |
| @@ -197,7 +201,7 @@ static int meth_receivefrom(lua_State *L) | |||
| 197 | return 3; | 201 | return 3; |
| 198 | } else { | 202 | } else { |
| 199 | lua_pushnil(L); | 203 | lua_pushnil(L); |
| 200 | io_pusherror(L, err); | 204 | pusherror(L, err); |
| 201 | return 2; | 205 | return 2; |
| 202 | } | 206 | } |
| 203 | } | 207 | } |
| @@ -205,23 +209,20 @@ static int meth_receivefrom(lua_State *L) | |||
| 205 | /*-------------------------------------------------------------------------*\ | 209 | /*-------------------------------------------------------------------------*\ |
| 206 | * Select support methods | 210 | * Select support methods |
| 207 | \*-------------------------------------------------------------------------*/ | 211 | \*-------------------------------------------------------------------------*/ |
| 208 | static int meth_getfd(lua_State *L) | 212 | static int meth_getfd(lua_State *L) { |
| 209 | { | ||
| 210 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 213 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 211 | lua_pushnumber(L, (int) udp->sock); | 214 | lua_pushnumber(L, (int) udp->sock); |
| 212 | return 1; | 215 | return 1; |
| 213 | } | 216 | } |
| 214 | 217 | ||
| 215 | /* this is very dangerous, but can be handy for those that are brave enough */ | 218 | /* this is very dangerous, but can be handy for those that are brave enough */ |
| 216 | static int meth_setfd(lua_State *L) | 219 | static int meth_setfd(lua_State *L) { |
| 217 | { | ||
| 218 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 220 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 219 | udp->sock = (t_sock) luaL_checknumber(L, 2); | 221 | udp->sock = (t_sock) luaL_checknumber(L, 2); |
| 220 | return 0; | 222 | return 0; |
| 221 | } | 223 | } |
| 222 | 224 | ||
| 223 | static int meth_dirty(lua_State *L) | 225 | static int meth_dirty(lua_State *L) { |
| 224 | { | ||
| 225 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 226 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 226 | (void) udp; | 227 | (void) udp; |
| 227 | lua_pushboolean(L, 0); | 228 | lua_pushboolean(L, 0); |
| @@ -231,14 +232,12 @@ static int meth_dirty(lua_State *L) | |||
| 231 | /*-------------------------------------------------------------------------*\ | 232 | /*-------------------------------------------------------------------------*\ |
| 232 | * Just call inet methods | 233 | * Just call inet methods |
| 233 | \*-------------------------------------------------------------------------*/ | 234 | \*-------------------------------------------------------------------------*/ |
| 234 | static int meth_getpeername(lua_State *L) | 235 | static int meth_getpeername(lua_State *L) { |
| 235 | { | ||
| 236 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); | 236 | p_udp udp = (p_udp) aux_checkclass(L, "udp{connected}", 1); |
| 237 | return inet_meth_getpeername(L, &udp->sock); | 237 | return inet_meth_getpeername(L, &udp->sock); |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | static int meth_getsockname(lua_State *L) | 240 | static int meth_getsockname(lua_State *L) { |
| 241 | { | ||
| 242 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 241 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 243 | return inet_meth_getsockname(L, &udp->sock); | 242 | return inet_meth_getsockname(L, &udp->sock); |
| 244 | } | 243 | } |
| @@ -246,8 +245,7 @@ static int meth_getsockname(lua_State *L) | |||
| 246 | /*-------------------------------------------------------------------------*\ | 245 | /*-------------------------------------------------------------------------*\ |
| 247 | * Just call option handler | 246 | * Just call option handler |
| 248 | \*-------------------------------------------------------------------------*/ | 247 | \*-------------------------------------------------------------------------*/ |
| 249 | static int meth_setoption(lua_State *L) | 248 | static int meth_setoption(lua_State *L) { |
| 250 | { | ||
| 251 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 249 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 252 | return opt_meth_setoption(L, opt, &udp->sock); | 250 | return opt_meth_setoption(L, opt, &udp->sock); |
| 253 | } | 251 | } |
| @@ -255,8 +253,7 @@ static int meth_setoption(lua_State *L) | |||
| 255 | /*-------------------------------------------------------------------------*\ | 253 | /*-------------------------------------------------------------------------*\ |
| 256 | * Just call tm methods | 254 | * Just call tm methods |
| 257 | \*-------------------------------------------------------------------------*/ | 255 | \*-------------------------------------------------------------------------*/ |
| 258 | static int meth_settimeout(lua_State *L) | 256 | static int meth_settimeout(lua_State *L) { |
| 259 | { | ||
| 260 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 257 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 261 | return tm_meth_settimeout(L, &udp->tm); | 258 | return tm_meth_settimeout(L, &udp->tm); |
| 262 | } | 259 | } |
| @@ -264,8 +261,7 @@ static int meth_settimeout(lua_State *L) | |||
| 264 | /*-------------------------------------------------------------------------*\ | 261 | /*-------------------------------------------------------------------------*\ |
| 265 | * Turns a master udp object into a client object. | 262 | * Turns a master udp object into a client object. |
| 266 | \*-------------------------------------------------------------------------*/ | 263 | \*-------------------------------------------------------------------------*/ |
| 267 | static int meth_setpeername(lua_State *L) | 264 | static int meth_setpeername(lua_State *L) { |
| 268 | { | ||
| 269 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 265 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
| 270 | p_tm tm = &udp->tm; | 266 | p_tm tm = &udp->tm; |
| 271 | const char *address = luaL_checkstring(L, 2); | 267 | const char *address = luaL_checkstring(L, 2); |
| @@ -289,8 +285,7 @@ static int meth_setpeername(lua_State *L) | |||
| 289 | /*-------------------------------------------------------------------------*\ | 285 | /*-------------------------------------------------------------------------*\ |
| 290 | * Closes socket used by object | 286 | * Closes socket used by object |
| 291 | \*-------------------------------------------------------------------------*/ | 287 | \*-------------------------------------------------------------------------*/ |
| 292 | static int meth_close(lua_State *L) | 288 | static int meth_close(lua_State *L) { |
| 293 | { | ||
| 294 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | 289 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); |
| 295 | sock_destroy(&udp->sock); | 290 | sock_destroy(&udp->sock); |
| 296 | return 0; | 291 | return 0; |
| @@ -299,8 +294,7 @@ static int meth_close(lua_State *L) | |||
| 299 | /*-------------------------------------------------------------------------*\ | 294 | /*-------------------------------------------------------------------------*\ |
| 300 | * Turns a master object into a server object | 295 | * Turns a master object into a server object |
| 301 | \*-------------------------------------------------------------------------*/ | 296 | \*-------------------------------------------------------------------------*/ |
| 302 | static int meth_setsockname(lua_State *L) | 297 | static int meth_setsockname(lua_State *L) { |
| 303 | { | ||
| 304 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); | 298 | p_udp udp = (p_udp) aux_checkclass(L, "udp{unconnected}", 1); |
| 305 | const char *address = luaL_checkstring(L, 2); | 299 | const char *address = luaL_checkstring(L, 2); |
| 306 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); | 300 | unsigned short port = (unsigned short) luaL_checknumber(L, 3); |
| @@ -320,8 +314,7 @@ static int meth_setsockname(lua_State *L) | |||
| 320 | /*-------------------------------------------------------------------------*\ | 314 | /*-------------------------------------------------------------------------*\ |
| 321 | * Creates a master udp object | 315 | * Creates a master udp object |
| 322 | \*-------------------------------------------------------------------------*/ | 316 | \*-------------------------------------------------------------------------*/ |
| 323 | static int global_create(lua_State *L) | 317 | static int global_create(lua_State *L) { |
| 324 | { | ||
| 325 | t_sock sock; | 318 | t_sock sock; |
| 326 | const char *err = inet_trycreate(&sock, SOCK_DGRAM); | 319 | const char *err = inet_trycreate(&sock, SOCK_DGRAM); |
| 327 | /* try to allocate a system socket */ | 320 | /* try to allocate a system socket */ |
