static int lluv_udp_try_send(lua_State *L) { lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa); size_t len; const char *str = luaL_checklstring(L, 4, &len); uv_buf_t buf = uv_buf_init((char*)str, len); if(err < 0) { lua_settop(L, 3); lua_pushliteral(L, ":"); lua_insert(L, -2); lua_concat(L, 3); return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_check_none(L, 3); err = uv_udp_try_send(LLUV_H(handle, uv_udp_t), &buf, 1, (struct sockaddr*)&sa); if(err < 0) { return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_pushinteger(L, err); return 1; }
static int lluv_udp_send_(lua_State *L, lluv_handle_t *handle, struct sockaddr *sa, uv_buf_t *buf, size_t n){ int err; lluv_req_t *req; if(lua_gettop(L) == 6){ int ctx; lluv_check_callable(L, -2); ctx = luaL_ref(L, LLUV_LUA_REGISTRY); req = lluv_req_new(L, UV_UDP_SEND, handle); lluv_req_ref(L, req); /* string/table */ req->ctx = ctx; } else{ if(lua_gettop(L) == 4) lua_settop(L, 5); else lluv_check_args_with_cb(L, 5); req = lluv_req_new(L, UV_UDP_SEND, handle); lluv_req_ref(L, req); /* string/table */ } err = uv_udp_send(LLUV_R(req, udp_send), LLUV_H(handle, uv_udp_t), buf, n, sa, lluv_on_udp_send_cb); return lluv_return_req(L, handle, req, err); }
static lluv_handle_t* lluv_check_tcp(lua_State *L, int idx, lluv_flags_t flags){ lluv_handle_t *handle = lluv_check_stream(L, idx, LLUV_FLAG_OPEN); luaL_argcheck (L, LLUV_H(handle, uv_handle_t)->type == UV_TCP, idx, LLUV_TCP_NAME" expected"); luaL_argcheck (L, FLAGS_IS_SET(handle->flags, flags), idx, LLUV_TCP_NAME" closed"); return handle; }
static int lluv_poll_start(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_READABLE, "readable" }, { UV_WRITABLE, "writable" }, #if LLUV_UV_VER_GE(1,9,0) { UV_DISCONNECT, "disconnect" }, #endif { 0, NULL } }; lluv_handle_t *handle = lluv_check_poll(L, 1, LLUV_FLAG_OPEN); int events = UV_READABLE; int err; if(!lua_isfunction(L, 2)) events = lluv_opt_flags_ui(L, 2, UV_READABLE, FLAGS); lluv_check_args_with_cb(L, 3); LLUV_START_CB(handle) = luaL_ref(L, LLUV_LUA_REGISTRY); err = uv_poll_start(LLUV_H(handle, uv_poll_t), events, lluv_on_poll_start); if(err >= 0) lluv_handle_lock(L, handle, LLUV_LOCK_START); return lluv_return(L, handle, LLUV_START_CB(handle), err); }
static int lluv_process_kill(lua_State *L){ lluv_handle_t *handle = lluv_check_process(L, 1, LLUV_FLAG_OPEN); int sig = luaL_optint(L, 2, SIGTERM); int err = uv_process_kill(LLUV_H(handle, uv_process_t), sig); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, (uv_errno_t)err, NULL); } lua_settop(L, 1); return 1; }
static int lluv_tcp_getpeername(lua_State *L){ lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; int sa_len = sizeof(sa); int err = uv_tcp_getpeername(LLUV_H(handle, uv_tcp_t), (struct sockaddr*)&sa, &sa_len); lua_settop(L, 1); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } return lluv_push_addr(L, &sa); }
static int lluv_tcp_open(lua_State *L){ lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); uv_os_sock_t sock = lluv_check_os_sock(L, 2); int err = uv_tcp_open(LLUV_H(handle, uv_tcp_t), sock); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
static int lluv_udp_set_multicast_interface(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); const char *interface_addr = luaL_checkstring(L, 2); int err = uv_udp_set_multicast_interface(LLUV_H(handle, uv_udp_t), interface_addr); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
static int lluv_udp_set_ttl(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); int ttl = luaL_checkint(L, 2); int err = uv_udp_set_ttl(LLUV_H(handle, uv_udp_t), ttl); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
static int lluv_poll_stop(lua_State *L){ lluv_handle_t *handle = lluv_check_poll(L, 1, LLUV_FLAG_OPEN); int err = uv_poll_stop(LLUV_H(handle, uv_poll_t)); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lluv_handle_unlock(L, handle, LLUV_LOCK_START); lua_settop(L, 1); return 1; }
static int lluv_tcp_simultaneous_accepts(lua_State *L){ lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); int enable = lua_toboolean(L, 2); int err = uv_tcp_simultaneous_accepts(LLUV_H(handle, uv_tcp_t), enable); lua_settop(L, 1); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } return 1; }
static int lluv_udp_set_broadcast(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); int enable = lua_toboolean(L, 2); int err = uv_udp_set_broadcast(LLUV_H(handle, uv_udp_t), enable); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
static int lluv_udp_start_recv(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); int err; lluv_check_args_with_cb(L, 2); LLUV_READ_CB(handle) = luaL_ref(L, LLUV_LUA_REGISTRY); err = uv_udp_recv_start(LLUV_H(handle, uv_udp_t), lluv_alloc_buffer_cb, lluv_on_udp_recv_cb); if(err >= 0) lluv_handle_lock(L, handle, LLUV_LOCK_READ); return lluv_return(L, handle, LLUV_READ_CB(handle), err); }
static int lluv_signal_start(lua_State *L){ lluv_handle_t *handle = lluv_check_signal(L, 1, LLUV_FLAG_OPEN); int signum = luaL_checkint(L, 2); int err; lluv_check_args_with_cb(L, 3); LLUV_START_CB(handle) = luaL_ref(L, LLUV_LUA_REGISTRY); err = uv_signal_start(LLUV_H(handle, uv_signal_t), lluv_on_signal_start, signum); if(err >= 0) lluv_handle_lock(L, handle, LLUV_LOCK_START); return lluv_return(L, handle, LLUV_START_CB(handle), err); }
static int lluv_tcp_keepalive(lua_State *L){ lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); int enable = lua_toboolean(L, 2); unsigned int delay = 0; int err; if(enable) delay = (unsigned int)luaL_checkint(L, 3); err = uv_tcp_keepalive(LLUV_H(handle, uv_tcp_t), enable, delay); lua_settop(L, 1); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } return 1; }
static int lluv_tcp_connect(lua_State *L){ lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; lluv_req_t *req; int err = lluv_check_addr(L, 2, &sa); if(err < 0){ lua_settop(L, 3); lua_pushliteral(L, ":");lua_insert(L, -2);lua_concat(L, 3); return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_check_args_with_cb(L, 4); req = lluv_req_new(L, UV_CONNECT, handle); err = uv_tcp_connect(LLUV_R(req, connect), LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, lluv_on_stream_connect_cb); return lluv_return_req(L, handle, req, err); }
static int lluv_udp_stop_recv(lua_State *L){ lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); int err; lluv_check_none(L, 2); err = uv_udp_recv_stop(LLUV_H(handle, uv_udp_t)); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } if(LLUV_READ_CB(handle) != LUA_NOREF){ luaL_unref(L, LLUV_LUA_REGISTRY, LLUV_READ_CB(handle)); LLUV_READ_CB(handle) = LUA_NOREF; lluv_handle_unlock(L, handle, LLUV_LOCK_READ); } lua_settop(L, 1); return 1; }
static int lluv_udp_set_membership(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_LEAVE_GROUP, "leave" }, { UV_JOIN_GROUP, "join" }, { 0, NULL } }; lluv_handle_t *handle = lluv_check_udp(L, 1, LLUV_FLAG_OPEN); const char *multicast_addr = luaL_checkstring(L, 2); const char *interface_addr = luaL_checkstring(L, 3); uv_membership membership = (uv_membership)lluv_opt_named_const(L, 4, UV_JOIN_GROUP, FLAGS); int err = uv_udp_set_membership(LLUV_H(handle, uv_udp_t), multicast_addr, interface_addr, membership); if(err < 0){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, NULL); } lua_settop(L, 1); return 1; }
static void opt_get_stdio(lua_State *L, int idx, uv_process_options_t *opt){ static const lluv_uv_const_t FLAGS[] = { { UV_IGNORE, "ignore" }, { UV_CREATE_PIPE, "create_pipe" }, { UV_INHERIT_FD, "inherit_fd" }, { UV_INHERIT_STREAM, "inherit_stream" }, { UV_READABLE_PIPE, "readable_pipe" }, { UV_WRITABLE_PIPE, "writable_pipe" }, { 0, NULL } }; size_t i, n; rawgets(L, idx, "stdio"); if(lua_isnil(L, -1)){ lua_settop(L, 1); return; } if(!lua_istable(L, -1)){ lua_pop(L, 1); lua_pushstring(L, "stdio option must be an array"); lua_error(L); return; } n = lua_objlen(L, -1); if(n == 0){ lua_pop(L, 1); return; } opt->stdio = lluv_alloc(L, n * sizeof(*opt->stdio)); opt->stdio_count = n; for(i = 0; i < n; ++i){ lua_rawgeti(L, -1, i + 1); if(lua_istable(L, -1)){ uv_stdio_flags flags = 0; if(opt_exists(L, -1, "fd")){ opt->stdio[i].data.fd = (int)opt_get_int64 (L, -1, "fd", 0, "stdio.fd option must be a number" ); flags = UV_INHERIT_FD; } else if(opt_exists(L, -1, "stream")){ lluv_handle_t *handle; rawgets(L, -1, "stream"); handle = lluv_check_stream(L, -1, LLUV_FLAG_OPEN); lua_pop(L, 1); opt->stdio[i].data.stream = LLUV_H(handle, uv_stream_t); flags = UV_INHERIT_STREAM; } else{ opt->stdio[i].data.fd = 0; flags = UV_IGNORE; } if(opt_exists(L, -1, "flags")){ rawgets(L, -1, "flags"); flags = lluv_opt_flags_ui(L, -1, 0, FLAGS); lua_pop(L, 1); // flags = opt_get_int64 (L, -1, "flags", 0, "stdio.flags option must be a number" ); } opt->stdio[i].flags = flags; } else if(lua_isnumber(L, -1)){ opt->stdio[i].data.fd = (int)lutil_checkint64(L, -1); opt->stdio[i].flags = UV_INHERIT_FD; } else if(lua_isuserdata(L, -1)){ lluv_handle_t *handle = lluv_check_stream(L, -1, LLUV_FLAG_OPEN); opt->stdio[i].data.stream = LLUV_H(handle, uv_stream_t); opt->stdio[i].flags = UV_INHERIT_STREAM; } else{ lua_pushstring(L, "stdio element must be table, stream or number"); lua_error(L); return; } lua_pop(L, 1); } lua_pop(L, 1); }
static int lluv_process_pid(lua_State *L){ lluv_handle_t *handle = lluv_check_process(L, 1, LLUV_FLAG_OPEN); lutil_pushint64(L, LLUV_H(handle, uv_process_t)->pid); return 1; }
static int lluv_tcp_bind(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_TCP_IPV6ONLY , "ipv6only" }, { 0, NULL } }; lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa); unsigned int flags = 0; int top = lua_gettop(L); if(top > 5)lua_settop(L, top = 5); if((top > 4) || (!lua_isfunction(L, 4))){ flags = lluv_opt_flags_ui(L, 4, flags, FLAGS); } if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } err = uv_tcp_bind(LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, flags); if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } if(lua_isfunction(L, top)){ lua_pushvalue(L, 1); lua_pushnil(L); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), lluv_push_addr(L, &sa) + 2 ); } lua_settop(L, 1); return 1; }
static lluv_handle_t* lluv_check_udp(lua_State *L, int idx, lluv_flags_t flags){ lluv_handle_t *handle = lluv_check_handle(L, idx, flags); luaL_argcheck (L, LLUV_H(handle, uv_handle_t)->type == UV_UDP, idx, LLUV_UDP_NAME" expected"); return handle; }