static int luv_fs_write(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); uv_buf_t buf; int64_t offset; int ref; uv_fs_t* req; size_t count; uv_buf_t *bufs = NULL; if (lua_istable(L, 2)) { bufs = luv_prep_bufs(L, 2, &count); } else if (lua_isstring(L, 2)) { luv_check_buf(L, 2, &buf); count = 1; } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } offset = luaL_checkinteger(L, 3); ref = luv_check_continuation(L, 4); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); req->ptr = buf.base; ((luv_req_t*)req->data)->data = bufs; FS_CALL(write, req, file, bufs ? bufs : &buf, count, offset); }
static int luv_fs_mkdtemp(lua_State* L) { const char* tpl = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(mkdtemp, req, tpl); }
static int luv_write2(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); uv_write_t* req; int ret, ref; uv_stream_t* send_handle; send_handle = luv_check_stream(L, 3); ref = luv_check_continuation(L, 4); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); if (lua_istable(L, 2)) { size_t count; uv_buf_t *bufs = luv_prep_bufs(L, 2, &count); ret = uv_write2(req, handle, bufs, count, send_handle, luv_write_cb); free(bufs); } else if (lua_isstring(L, 2)) { uv_buf_t buf; luv_check_buf(L, 2, &buf); ret = uv_write2(req, handle, &buf, 1, send_handle, luv_write_cb); } else { return luaL_argerror(L, 2, "data must be string or table of strings"); } if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } lua_pushvalue(L, 2); ((luv_req_t*)req->data)->data_ref = luaL_ref(L, LUA_REGISTRYINDEX); return 1; }
static int luv_fs_fdatasync(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fdatasync, req, file); }
static int luv_udp_send(lua_State* L) { uv_udp_t* handle = luv_check_udp(L, 1); uv_udp_send_t* req; uv_buf_t buf; int ret, port, ref; const char* host; struct sockaddr_storage addr; luv_check_buf(L, 2, &buf); host = luaL_checkstring(L, 3); port = luaL_checkinteger(L, 4); if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_error(L, "Invalid IP address or port [%s:%d]", host, port); } ref = luv_check_continuation(L, 5); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_udp_send(req, handle, &buf, 1, (struct sockaddr*)&addr, luv_udp_send_cb); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } return 1; }
static int luv_fs_lstat(lua_State* L) { const char* path = luaL_checkstring(L, 1); int ref = luv_check_continuation(L, 2); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(lstat, req, path); }
static int luv_fs_scandir(lua_State* L) { const char* path = luaL_checkstring(L, 1); int flags = 0; // TODO: find out what these flags are. int ref = luv_check_continuation(L, 2); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(scandir, req, path, flags); }
static int luv_fs_ftruncate(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int64_t offset = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(ftruncate, req, file, offset); }
static int luv_fs_access(lua_State* L) { const char* path = luaL_checkstring(L, 1); int amode = luv_check_amode(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(access, req, path, amode); }
static int luv_fs_chmod(lua_State* L) { const char* path = luaL_checkstring(L, 1); int mode = luaL_checkinteger(L, 2); int ref = luv_check_continuation(L, 3); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(chmod, req, path, mode); }
static int luv_fs_fchown(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); uv_uid_t uid = luaL_checkinteger(L, 2); uv_uid_t gid = luaL_checkinteger(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(fchown, req, file, uid, gid); }
static int luv_fs_utime(lua_State* L) { const char* path = luaL_checkstring(L, 1); double atime = luaL_checknumber(L, 2); double mtime = luaL_checknumber(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(utime, req, path, atime, mtime); }
static int luv_fs_chown(lua_State* L) { const char* path = luaL_checkstring(L, 1); uv_uid_t uid = luaL_checkinteger(L, 2); uv_uid_t gid = luaL_checkinteger(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(chown, req, path, uid, gid); }
static int luv_fs_futime(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); double atime = luaL_checknumber(L, 2); double mtime = luaL_checknumber(L, 3); int ref = luv_check_continuation(L, 4); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(futime, req, file, atime, mtime); }
static int luv_fs_sendfile(lua_State* L) { uv_file out_fd = luaL_checkinteger(L, 1); uv_file in_fd = luaL_checkinteger(L, 2); int64_t in_offset = luaL_checkinteger(L, 3); size_t length = luaL_checkinteger(L, 4); int ref = luv_check_continuation(L, 5); uv_fs_t* req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(sendfile, req, out_fd, in_fd, in_offset, length); }
static int luv_shutdown(lua_State* L) { uv_stream_t* handle = luv_check_stream(L, 1); int ref = luv_check_continuation(L, 2); uv_shutdown_t* req = lua_newuserdata(L, sizeof(*req)); int ret; req->data = luv_setup_req(L, ref); ret = uv_shutdown(req, handle, luv_shutdown_cb); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } return 1; }
static int luv_fs_read(lua_State* L) { uv_file file = luaL_checkinteger(L, 1); int64_t len = luaL_checkinteger(L, 2); int64_t offset = luaL_checkinteger(L, 3); uv_buf_t buf; int ref; uv_fs_t* req; char* data = malloc(len); if (!data) return luaL_error(L, "Failure to allocate buffer"); buf = uv_buf_init(data, len); ref = luv_check_continuation(L, 4); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); // TODO: find out why we can't just use req->ptr for the base ((luv_req_t*)req->data)->data = buf.base; FS_CALL(read, req, file, &buf, 1, offset); }
static int luv_fs_symlink(lua_State* L) { const char* path = luaL_checkstring(L, 1); const char* new_path = luaL_checkstring(L, 2); int flags = 0, ref; uv_fs_t* req; if (lua_type(L, 3) == LUA_TTABLE) { lua_getfield(L, 3, "dir"); if (lua_toboolean(L, -1)) flags |= UV_FS_SYMLINK_DIR; lua_pop(L, 1); lua_getfield(L, 3, "junction"); if (lua_toboolean(L, -1)) flags |= UV_FS_SYMLINK_JUNCTION; lua_pop(L, 1); } ref = luv_check_continuation(L, 4); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); FS_CALL(symlink, req, path, new_path, flags); }
static int luv_tcp_connect(lua_State* L) { uv_tcp_t* handle = luv_check_tcp(L, 1); const char* host = luaL_checkstring(L, 2); int port = luaL_checkinteger(L, 3); struct sockaddr_storage addr; uv_connect_t* req; int ret, ref; if (uv_ip4_addr(host, port, (struct sockaddr_in*)&addr) && uv_ip6_addr(host, port, (struct sockaddr_in6*)&addr)) { return luaL_argerror(L, 3, "Invalid IP address or port"); } ref = luv_check_continuation(L, 4); req = lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_tcp_connect(req, handle, (struct sockaddr*)&addr, luv_connect_cb); if (ret < 0) { lua_pop(L, 1); return luv_error(L, ret); } return 1; }
static int luv_getnameinfo(lua_State* L) { uv_getnameinfo_t* req; struct sockaddr_storage addr; const char* ip = NULL; int flags = 0; int ret, ref, port = 0; luaL_checktype(L, 1, LUA_TTABLE); memset(&addr, 0, sizeof(addr)); lua_getfield(L, 1, "ip"); if (lua_isstring(L, -1)) { ip = lua_tostring(L, -1); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "ip property must be string if set"); } lua_pop(L, 1); lua_getfield(L, 1, "port"); if (lua_isnumber(L, -1)) { port = lua_tointeger(L, -1); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "port property must be integer if set"); } lua_pop(L, 1); if (ip || port) { if (!ip) ip = "0.0.0.0"; if (!uv_ip4_addr(ip, port, (struct sockaddr_in*)&addr)) { addr.ss_family = AF_INET; } else if (!uv_ip6_addr(ip, port, (struct sockaddr_in6*)&addr)) { addr.ss_family = AF_INET6; } else { return luaL_argerror(L, 1, "Invalid ip address or port"); } } lua_getfield(L, 1, "family"); if (lua_isnumber(L, -1)) { addr.ss_family = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { addr.ss_family = luv_af_string_to_num(lua_tostring(L, -1)); } else if (!lua_isnil(L, -1)) { luaL_argerror(L, 1, "family must be string if set"); } lua_pop(L, 1); ref = luv_check_continuation(L, 2); req = (uv_getnameinfo_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_getnameinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getnameinfo_cb, (struct sockaddr*)&addr, flags); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } if (ref == LUA_NOREF) { lua_pop(L, 1); lua_pushstring(L, req->host); lua_pushstring(L, req->service); luv_cleanup_req(L, (luv_req_t*)req->data); return 2; } return 1; }
static int luv_getaddrinfo(lua_State* L) { uv_getaddrinfo_t* req; const char* node; const char* service; struct addrinfo hints_s; struct addrinfo* hints = &hints_s; int ret, ref; if (lua_isnoneornil(L, 1)) node = NULL; else node = luaL_checkstring(L, 1); if (lua_isnoneornil(L, 2)) service = NULL; else service = luaL_checkstring(L, 2); if (!lua_isnoneornil(L, 3)) luaL_checktype(L, 3, LUA_TTABLE); else hints = NULL; if (hints) { // Initialize the hints memset(hints, 0, sizeof(*hints)); // Process the `family` hint. lua_getfield(L, 3, "family"); if (lua_isnumber(L, -1)) { hints->ai_family = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { hints->ai_family = luv_af_string_to_num(lua_tostring(L, -1)); } else if (lua_isnil(L, -1)) { hints->ai_family = AF_UNSPEC; } else { luaL_argerror(L, 3, "family hint must be string if set"); } lua_pop(L, 1); // Process `socktype` hint lua_getfield(L, 3, "socktype"); if (lua_isnumber(L, -1)) { hints->ai_socktype = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { hints->ai_socktype = luv_sock_string_to_num(lua_tostring(L, -1)); } else if (!lua_isnil(L, -1)) { return luaL_argerror(L, 3, "socktype hint must be string if set"); } lua_pop(L, 1); // Process the `protocol` hint lua_getfield(L, 3, "protocol"); if (lua_isnumber(L, -1)) { hints->ai_protocol = lua_tointeger(L, -1); } else if (lua_isstring(L, -1)) { int protocol = luv_af_string_to_num(lua_tostring(L, -1)); if (protocol) { hints->ai_protocol = protocol; } else { return luaL_argerror(L, 3, "Invalid protocol hint"); } } else if (!lua_isnil(L, -1)) { return luaL_argerror(L, 3, "protocol hint must be string if set"); } lua_pop(L, 1); lua_getfield(L, 3, "addrconfig"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_ADDRCONFIG; lua_pop(L, 1); #ifdef AI_V4MAPPED lua_getfield(L, 3, "v4mapped"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_V4MAPPED; lua_pop(L, 1); #endif #ifdef AI_ALL lua_getfield(L, 3, "all"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_ALL; lua_pop(L, 1); #endif lua_getfield(L, 3, "numerichost"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_NUMERICHOST; lua_pop(L, 1); lua_getfield(L, 3, "passive"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_PASSIVE; lua_pop(L, 1); lua_getfield(L, 3, "numericserv"); if (lua_toboolean(L, -1)) { hints->ai_flags |= AI_NUMERICSERV; /* On OS X upto at least OSX 10.9, getaddrinfo crashes * if AI_NUMERICSERV is set and the servname is NULL or "0". * This workaround avoids a segfault in libsystem. */ if (NULL == service) service = "00"; } lua_pop(L, 1); lua_getfield(L, 3, "canonname"); if (lua_toboolean(L, -1)) hints->ai_flags |= AI_CANONNAME; lua_pop(L, 1); } ref = luv_check_continuation(L, 4); req = (uv_getaddrinfo_t*)lua_newuserdata(L, sizeof(*req)); req->data = luv_setup_req(L, ref); ret = uv_getaddrinfo(luv_loop(L), req, ref == LUA_NOREF ? NULL : luv_getaddrinfo_cb, node, service, hints); if (ret < 0) { luv_cleanup_req(L, (luv_req_t*)req->data); lua_pop(L, 1); return luv_error(L, ret); } if (ref == LUA_NOREF) { lua_pop(L, 1); luv_pushaddrinfo(L, req->addrinfo); uv_freeaddrinfo(req->addrinfo); luv_cleanup_req(L, (luv_req_t*)req->data); } return 1; }