diff options
author | Rob Kendrick (plinth) <rjek@rjek.com> | 2013-11-26 20:22:40 +0000 |
---|---|---|
committer | Rob Kendrick (plinth) <rjek@rjek.com> | 2013-11-26 20:22:40 +0000 |
commit | 3b7f8babc8f2f8ef635b9fb3d44090f8c019a455 (patch) | |
tree | b2b82bd056cd2827ebe82eaff49912a8e9b5056b /luxio.c | |
parent | 785c8fadf519118a9c74e2bbc4f85e27c25a5f0f (diff) | |
download | luxio-3b7f8babc8f2f8ef635b9fb3d44090f8c019a455.tar.bz2 |
send(to), recv(from) in Luxio, and simple bindings to send and recv.
Diffstat (limited to 'luxio.c')
-rw-r--r-- | luxio.c | 115 |
1 files changed, 115 insertions, 0 deletions
@@ -2595,6 +2595,116 @@ luxio_getaddrinfo(lua_State *L) return 2; } +/* Socket-related send and receive functions *********************************/ + +static int +luxio_send(lua_State *L) +{ + int fd = luaL_checkint(L, 1); + size_t count; + const char *buf = luaL_checklstring(L, 2, &count); + int flags = luaL_optint(L, 3, 0); + + lua_pushinteger(L, send(fd, buf, count, flags)); + lua_pushinteger(L, errno); + + return 2; +} + +static int +luxio_sendto(lua_State *L) +{ + int fd = luaL_checkint(L, 1); + size_t count; + const char *buf = luaL_checklstring(L, 2, &count); + int flags = luaL_optint(L, 3, 0); + struct sockaddr *addr = luaL_checkudata(L, 4, LUXIO_SOCKADDR_METATABLE_NAME); + socklen_t l = luxio___sockaddr_len(L, addr); + + lua_pushinteger(L, sendto(fd, buf, count, flags, addr, l)); + lua_pushinteger(L, errno); + + return 2; +} + +static int +luxio_recv(lua_State *L) +{ + int fd = luaL_checkint(L, 1); + int count = luaL_checkint(L, 2); + int flags = luaL_optint(L, 3, 0); + ssize_t result; + char *buf = malloc(count); + + if (buf == NULL) { + lua_pushstring(L, "unable to allocate read buffer: memory exhausted"); + lua_error(L); + } + + result = recv(fd, buf, count, flags); + + if (result == -1) { + lua_pushinteger(L, result); + lua_pushinteger(L, errno); + } else { + /* sadly there appears to be no way to avoid this copy. + * luaL_Buffer actually builds things on the C stack bytes at a time, + * and there is no way to pre-allocate a Lua type other than a + * userdatum. Additionally, should Lua call its panic function because + * it can't allocate memory to copy this into, our buf will be leaked. + * We could perhaps fix this with a lot of faff, involving creating + * a userdatum for our buffer, and setting a __gc metamethod. + */ + lua_pushlstring(L, buf, result); + lua_pushinteger(L, errno); + } + + free(buf); + + return 2; +} + +static int +luxio_recvfrom(lua_State *L) +{ + int fd = luaL_checkint(L, 1); + int count = luaL_checkint(L, 2); + int flags = luaL_optint(L, 3, 0); + struct sockaddr_storage addr; + socklen_t l = sizeof(addr); + ssize_t result; + char *buf = malloc(count); + + if (buf == NULL) { + lua_pushstring(L, "unable to allocate read buffer: memory exhausted"); + lua_error(L); + } + + result = recvfrom(fd, buf, count, flags, (struct sockaddr *)&addr, &l); + + if (result == -1) { + free(buf); + lua_pushinteger(L, result); + lua_pushinteger(L, errno); + return 2; + } + + /* sadly there appears to be no way to avoid this copy. + * luaL_Buffer actually builds things on the C stack bytes at a time, + * and there is no way to pre-allocate a Lua type other than a + * userdatum. Additionally, should Lua call its panic function because + * it can't allocate memory to copy this into, our buf will be leaked. + * We could perhaps fix this with a lot of faff, involving creating + * a userdatum for our buffer, and setting a __gc metamethod. + */ + lua_pushlstring(L, buf, result); + free(buf); + lua_pushinteger(L, errno); + luxio__makesockaddr(L, (const struct sockaddr *)&addr, l); + + return 3; +} + /* Poll-binding functions ****************************************************/ #define LUXIO_POLLFD_METATABLE "luxio.pollfdarray" @@ -3224,6 +3334,11 @@ luxio_functions[] = { { "make_sockaddr", luxio_makesockaddr }, + { "send", luxio_send }, + { "sendto", luxio_sendto }, + { "recv", luxio_recv }, + { "recvfrom", luxio_recvfrom }, + { "pollfds_new", luxio_pollfds_new }, { "pollfds_resize", luxio_pollfds_resize }, { "pollfds_setslot", luxio_pollfds_set_slot }, |