Beispiel #1
0
static int luv_new_signal(lua_State* L) {
  uv_signal_t* handle = lua_newuserdata(L, sizeof(*handle));
  int ret = uv_signal_init(luv_loop(L), handle);
  if (ret < 0) {
    lua_pop(L, 1);
    return luv_error(L, ret);
  }
  handle->data = luv_setup_handle(L);
  return 1;
}
Beispiel #2
0
static int luv_tcp_simultaneous_accepts(lua_State* L) {
  uv_tcp_t* handle = luv_check_tcp(L, 1);
  int ret, enable;
  luaL_checktype(L, 2, LUA_TBOOLEAN);
  enable = lua_toboolean(L, 2);
  ret = uv_tcp_simultaneous_accepts(handle, enable);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #3
0
static int luv_getrusage(lua_State* L) {
  uv_rusage_t rusage;
  int ret = uv_getrusage(&rusage);
  if (ret < 0) return luv_error(L, ret);
  lua_createtable(L, 0, 16);
  // user CPU time used
  luv_push_timeval_table(L, &rusage.ru_utime);
  lua_setfield(L, -2, "utime");
  // system CPU time used
  luv_push_timeval_table(L, &rusage.ru_stime);
  lua_setfield(L, -2, "stime");
  // maximum resident set size
  lua_pushinteger(L, rusage.ru_maxrss);
  lua_setfield(L, -2, "maxrss");
  // integral shared memory size
  lua_pushinteger(L, rusage.ru_ixrss);
  lua_setfield(L, -2, "ixrss");
  // integral unshared data size
  lua_pushinteger(L, rusage.ru_idrss);
  lua_setfield(L, -2, "idrss");
  // integral unshared stack size
  lua_pushinteger(L, rusage.ru_isrss);
  lua_setfield(L, -2, "isrss");
  // page reclaims (soft page faults)
  lua_pushinteger(L, rusage.ru_minflt);
  lua_setfield(L, -2, "minflt");
  // page faults (hard page faults)
  lua_pushinteger(L, rusage.ru_majflt);
  lua_setfield(L, -2, "majflt");
  // swaps
  lua_pushinteger(L, rusage.ru_nswap);
  lua_setfield(L, -2, "nswap");
  // block input operations
  lua_pushinteger(L, rusage.ru_inblock);
  lua_setfield(L, -2, "inblock");
  // block output operations
  lua_pushinteger(L, rusage.ru_oublock);
  lua_setfield(L, -2, "oublock");
  // IPC messages sent
  lua_pushinteger(L, rusage.ru_msgsnd);
  lua_setfield(L, -2, "msgsnd");
  // IPC messages received
  lua_pushinteger(L, rusage.ru_msgrcv);
  lua_setfield(L, -2, "msgrcv");
  // signals received
  lua_pushinteger(L, rusage.ru_nsignals);
  lua_setfield(L, -2, "nsignals");
  // voluntary context switches
  lua_pushinteger(L, rusage.ru_nvcsw);
  lua_setfield(L, -2, "nvcsw");
  // involuntary context switches
  lua_pushinteger(L, rusage.ru_nivcsw);
  lua_setfield(L, -2, "nivcsw");
  return 1;
}
Beispiel #4
0
static int luv_new_socket_poll(lua_State* L) {
  int fd = luaL_checkinteger(L, 1);
  uv_poll_t* handle = (uv_poll_t*)luv_newuserdata(L, sizeof(*handle));
  int ret = uv_poll_init_socket(luv_loop(L), handle, fd);
  if (ret < 0) {
    lua_pop(L, 1);
    return luv_error(L, ret);
  }
  handle->data = luv_setup_handle(L);
  return 1;
}
Beispiel #5
0
static int luv_fs_poll_start(lua_State* L) {
  uv_fs_poll_t* handle = luv_check_fs_poll(L, 1);
  const char* path = luaL_checkstring(L, 2);
  unsigned int interval = luaL_checkinteger(L, 3);
  int ret;
  luv_check_callback(L, handle->data, LUV_FS_POLL, 4);
  ret = uv_fs_poll_start(handle, luv_fs_poll_cb, path, interval);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #6
0
Datei: misc.c Projekt: luvit/luv
static int luv_os_setpriority(lua_State* L) {
  uv_pid_t pid = luaL_checkinteger(L, 1);
  int priority= luaL_checkinteger(L, 2);
  int ret = uv_os_setpriority(pid, priority);
  if (ret == 0) {
    lua_pushboolean(L, 1);
    ret = 1;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #7
0
static int luv_new_thread(lua_State* L) {
  int ret;
  size_t len;
  const char* buff;
  luv_thread_t* thread;
  int cbidx = 1;
#if LUV_UV_VERSION_GEQ(1, 26, 0)
  uv_thread_options_t options;
  options.flags = UV_THREAD_NO_FLAGS;
#endif
  thread = (luv_thread_t*)lua_newuserdata(L, sizeof(*thread));
  memset(thread, 0, sizeof(*thread));
  luaL_getmetatable(L, "uv_thread");
  lua_setmetatable(L, -2);

#if LUV_UV_VERSION_GEQ(1, 26, 0)
  if (lua_type(L, 1) == LUA_TTABLE)
  {
    cbidx++;

    lua_getfield(L, 1, "stack_size");
    if (!lua_isnil(L, -1))
    {
      options.flags |= UV_THREAD_HAS_STACK_SIZE;
      if (lua_isnumber(L, -1)) {
        options.stack_size = lua_tointeger(L, -1);
      }
      else {
        return luaL_argerror(L, 1, "stack_size option must be a number if set");
      }
    }
    lua_pop(L, 1);
  }
#endif

  buff = luv_thread_dumped(L, cbidx, &len);

  //clear in luv_thread_gc or in child threads
  thread->argc = luv_thread_arg_set(L, &thread->arg, cbidx+1, lua_gettop(L) - 1, LUVF_THREAD_UHANDLE);
  thread->len = len;
  thread->code = (char*)malloc(thread->len);
  memcpy(thread->code, buff, len);

#if LUV_UV_VERSION_GEQ(1, 26, 0)
  ret = uv_thread_create_ex(&thread->handle, &options, luv_thread_cb, thread);
#else
  ret = uv_thread_create(&thread->handle, luv_thread_cb, thread);
#endif
  if (ret < 0) return luv_error(L, ret);

  return 1;
}
Beispiel #8
0
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;
}
Beispiel #9
0
Datei: misc.c Projekt: luvit/luv
static int luv_os_getpriority(lua_State* L) {
  int priority;
  uv_pid_t pid = luaL_checkinteger(L, 1);
  int ret = uv_os_getpriority(pid, &priority);
  if (ret == 0) {
    lua_pushnumber(L, priority);
    ret = 1;
  }
  else {
    ret = luv_error(L, ret);
  }
  return ret;
}
Beispiel #10
0
Datei: misc.c Projekt: luvit/luv
static int luv_os_getenv(lua_State* L) {
  const char* name = luaL_checkstring(L, 1);
  size_t size = luaL_optinteger(L, 2, LUAL_BUFFERSIZE);
  char *buff = malloc(size);
  int ret = uv_os_getenv(name, buff, &size);
  if (ret == 0) {
    lua_pushlstring(L, buff, size);
    ret = 1;
  } else
    ret = luv_error(L, ret);
  free(buff);
  return ret;
}
Beispiel #11
0
static int luv_tcp_keepalive(lua_State* L) {
  uv_tcp_t* handle = luv_check_tcp(L, 1);
  int ret, enable;
  unsigned int delay = 0;
  luaL_checktype(L, 2, LUA_TBOOLEAN);
  enable = lua_toboolean(L, 2);
  if (enable) {
    delay = luaL_checkinteger(L, 3);
  }
  ret = uv_tcp_keepalive(handle, enable, delay);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #12
0
Datei: misc.c Projekt: luvit/luv
static int luv_if_indextoiid(lua_State* L) {
  char interface_id[UV_IF_NAMESIZE];
  size_t interface_id_len = sizeof(interface_id);
  unsigned int ifindex = (unsigned int)luaL_checkinteger(L, 1);

  int ret = uv_if_indextoiid(ifindex - 1, interface_id, &interface_id_len);
  if (ret == 0) {
    lua_pushlstring(L, interface_id, interface_id_len);
    ret = 1;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #13
0
Datei: tty.c Projekt: luvit/luv
static int luv_new_tty(lua_State* L) {
    int readable, ret;
    uv_tty_t* handle;
    uv_file fd = luaL_checkinteger(L, 1);
    luaL_checktype(L, 2, LUA_TBOOLEAN);
    readable = lua_toboolean(L, 2);
    handle = (uv_tty_t*)luv_newuserdata(L, sizeof(*handle));
    ret = uv_tty_init(luv_loop(L), handle, fd, readable);
    if (ret < 0) {
        lua_pop(L, 1);
        return luv_error(L, ret);
    }
    handle->data = luv_setup_handle(L);
    return 1;
}
Beispiel #14
0
static int luv_recv_buffer_size(lua_State* L) {
  uv_handle_t* handle = luv_check_handle(L, 1);
  int value;
  int ret;
  if (lua_isnoneornil(L, 2)) {
    value = 0;
  }
  else {
    value = luaL_checkinteger(L, 2);
  }
  ret = uv_recv_buffer_size(handle, &value);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #15
0
Datei: misc.c Projekt: luvit/luv
static int luv_if_indextoname(lua_State* L) {
  /* 40 bytes address, 16 bytes device name, plus reserve. */
  char scoped_addr[128];
  size_t scoped_addr_len = sizeof(scoped_addr);
  unsigned int ifindex = (unsigned int)luaL_checkinteger(L, 1);

  int ret = uv_if_indextoname(ifindex - 1, scoped_addr, &scoped_addr_len);
  if (ret == 0) {
    lua_pushlstring(L, scoped_addr, scoped_addr_len);
    ret = 1;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #16
0
Datei: misc.c Projekt: luvit/luv
static int luv_os_gethostname(lua_State* L) {
#if LUV_UV_VERSION_GEQ(1, 26, 0)
  char hostname[UV_MAXHOSTNAMESIZE];
#else
  char hostname[PATH_MAX];
#endif
  size_t size = sizeof(hostname);
  int ret = uv_os_gethostname(hostname, &size);
  if (ret == 0) {
    lua_pushlstring(L, hostname, size);
    ret = 1;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #17
0
Datei: udp.c Projekt: luvit/luv
static int luv_new_udp(lua_State* L) {
    uv_udp_t* handle = (uv_udp_t*)luv_newuserdata(L, sizeof(*handle));
    int ret;
    if (lua_isnoneornil(L, 1)) {
        ret = uv_udp_init(luv_loop(L), handle);
    }
    else {
        ret = uv_udp_init_ex(luv_loop(L), handle, lua_tointeger(L, 1));
    }
    if (ret < 0) {
        lua_pop(L, 1);
        return luv_error(L, ret);
    }
    handle->data = luv_setup_handle(L);
    return 1;
}
Beispiel #18
0
Datei: udp.c Projekt: luvit/luv
static int luv_udp_try_send(lua_State* L) {
    uv_udp_t* handle = luv_check_udp(L, 1);
    uv_buf_t buf;
    int ret, port;
    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);
    }
    ret = uv_udp_try_send(handle, &buf, 1, (struct sockaddr*)&addr);
    if (ret < 0) return luv_error(L, ret);
    lua_pushinteger(L, ret);
    return 1;
}
Beispiel #19
0
Datei: misc.c Projekt: luvit/luv
static int luv_gettimeofday(lua_State* L) {
  uv_timeval64_t tv = { 0 };

  int ret = uv_gettimeofday(&tv);
  if (ret == 0)
  {
#if defined(__LP64__)
    lua_pushinteger(L, tv.tv_sec);
#else
    lua_pushnumber(L, tv.tv_sec);
#endif
    lua_pushinteger(L, tv.tv_usec);
    return 2;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #20
0
static int luv_poll_start(lua_State* L) {
  uv_poll_t* handle = luv_check_poll(L, 1);
  int events, ret;
  switch (luaL_checkoption(L, 2, "rw", luv_pollevents)) {
    case 0: events = UV_READABLE; break;
    case 1: events = UV_WRITABLE; break;
    case 2: events = UV_READABLE | UV_WRITABLE; break;
    case 3: events = UV_DISCONNECT; break;
    case 4: events = UV_READABLE|UV_DISCONNECT; break;
    case 5: events = UV_WRITABLE|UV_DISCONNECT; break;
    case 6: events = UV_READABLE|UV_WRITABLE|UV_DISCONNECT; break;
    default: events = 0; /* unreachable */
  }
  luv_check_callback(L, (luv_handle_t*)handle->data, LUV_POLL, 3);
  ret = uv_poll_start(handle, events, luv_poll_cb);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #21
0
Datei: misc.c Projekt: luvit/luv
static int luv_os_uname(lua_State* L) {
  uv_utsname_t uname;

  int ret = uv_os_uname(&uname);
  if (ret == 0) {
    lua_newtable(L);
    lua_pushstring(L, uname.sysname);
    lua_setfield(L, -2, "sysname");
    lua_pushstring(L, uname.release);
    lua_setfield(L, -2, "release");
    lua_pushstring(L, uname.version);
    lua_setfield(L, -2, "version");
    lua_pushstring(L, uname.machine);
    lua_setfield(L, -2, "machine");
    ret = 1;
  }
  else
    ret = luv_error(L, ret);
  return ret;
}
Beispiel #22
0
static int luv_fs_event_start(lua_State* L) {
  uv_fs_event_t* handle = luv_check_fs_event(L, 1);
  const char* path = luaL_checkstring(L, 2);
  int flags = 0, ret;
  luaL_checktype(L, 3, LUA_TTABLE);
  lua_getfield(L, 3, "watch_entry");
  if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_WATCH_ENTRY;
  lua_pop(L, 1);
  lua_getfield(L, 3, "stat");
  if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_STAT;
  lua_pop(L, 1);
  lua_getfield(L, 3, "recursive");
  if (lua_toboolean(L, -1)) flags |= UV_FS_EVENT_RECURSIVE;
  lua_pop(L, 1);
  luv_check_callback(L, handle->data, LUV_FS_EVENT, 4);
  ret = uv_fs_event_start(handle, luv_fs_event_cb, path, flags);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #23
0
static int luv_tcp_bind(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);
  unsigned int flags = 0;
  struct sockaddr_storage addr;
  int ret;
  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);
  }
  if (lua_type(L, 4) == LUA_TTABLE) {
    lua_getfield(L, 4, "ipv6only");
    if (lua_toboolean(L, -1)) flags |= UV_TCP_IPV6ONLY;
    lua_pop(L, 1);
  }
  ret = uv_tcp_bind(handle, (struct sockaddr*)&addr, flags);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #24
0
static int luv_try_write(lua_State* L) {
  uv_stream_t* handle = luv_check_stream(L, 1);
  int ret;
  if (lua_istable(L, 2)) {
    size_t count;
    uv_buf_t *bufs = luv_prep_bufs(L, 2, &count);
    ret = uv_try_write(handle, bufs, count);
    free(bufs);
  }
  else if (lua_isstring(L, 2)) {
    uv_buf_t buf;
    luv_check_buf(L, 2, &buf);
    ret = uv_try_write(handle, &buf, 1);
  }
  else {
    return luaL_argerror(L, 2, "data must be string or table of strings");
  }
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #25
0
static int luv_signal_start(lua_State* L) {
  uv_signal_t* handle = luv_check_signal(L, 1);
  int signum, ret;
  if (lua_isnumber(L, 2)) {
    signum = lua_tointeger(L, 2);
  }
  else if (lua_isstring(L, 2)) {
    signum = luv_sig_string_to_num(luaL_checkstring(L, 2));
    luaL_argcheck(L, signum, 2, "Invalid Signal name");
  }
  else {
    return luaL_argerror(L, 2, "Missing Signal name");
  }

  if (!lua_isnoneornil(L, 3)) {
    luv_check_callback(L, handle->data, LUV_SIGNAL, 3);
  }
  ret = uv_signal_start(handle, luv_signal_cb, signum);
  if (ret < 0) return luv_error(L, ret);
  lua_pushinteger(L, ret);
  return 1;
}
Beispiel #26
0
static int luv_new_thread(lua_State* L) {
  int ret;
  size_t len;
  const char* buff;
  luv_thread_t* thread;
  thread = lua_newuserdata(L, sizeof(*thread));
  memset(thread, 0, sizeof(*thread));
  luaL_getmetatable(L, "uv_thread");
  lua_setmetatable(L, -2);

  buff = luv_thread_dumped(L, 1, &len);

  thread->argc = luv_thread_arg_set(L, &thread->arg, 2, lua_gettop(L) - 1, 1);
  thread->len = len;
  thread->code = malloc(thread->len);
  memcpy(thread->code, buff, len);

  ret = uv_thread_create(&thread->handle, luv_thread_cb, thread);
  if (ret < 0) return luv_error(L, ret);

  return 1;
}
Beispiel #27
0
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_error(L, "Invalid IP address or port [%s:%d]", host, 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;
}
Beispiel #28
0
static int luv_queue_work(lua_State* L) {
  int top = lua_gettop(L);
  luv_work_ctx_t* ctx = luv_check_work_ctx(L, 1);
  luv_work_t* work = malloc(sizeof(*work));
  int ret;

  luv_thread_arg_set(L, &work->arg, 2, top);
  work->ctx = ctx;
  work->work.data = work;
  ret = uv_queue_work(luv_loop(L), &work->work, luv_work_cb, luv_after_work_cb);
  if (ret < 0) {
    free(work);
    return luv_error(L, ret);
  }

  //ref up to ctx 
  lua_pushlightuserdata(L, work);
  lua_pushvalue(L, 1);
  lua_rawset(L, LUA_REGISTRYINDEX);

  lua_pushboolean(L, 1);
  return 1;
}
Beispiel #29
0
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;
}
Beispiel #30
0
static int luv_spawn(lua_State* L) {
  uv_process_t* handle;
  uv_process_options_t options;
  size_t i, len = 0;
  int ret;

  memset(&options, 0, sizeof(options));
  options.exit_cb = exit_cb;
  options.file = luaL_checkstring(L, 1);
  options.flags = 0;

  // Make sure the 2nd argument is a table
  luaL_checktype(L, 2, LUA_TTABLE);

  // get the args list
  lua_getfield(L, 2, "args");
  // +1 for inserted command at front
  if (lua_type(L, -1) == LUA_TTABLE) {
    len = 1 + lua_rawlen(L, -1);
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 3, "args option must be table");
  }
  else {
    len = 1;
  }
  // +1 for null terminator at end
  options.args = malloc((len + 1) * sizeof(*options.args));
  if (!options.args) {
    luv_clean_options(&options);
    return luaL_error(L, "Problem allocating args");
  }
  options.args[0] = (char*)options.file;
  for (i = 1; i < len; ++i) {
    lua_rawgeti(L, -1, i);
    options.args[i] = (char*)lua_tostring(L, -1);
    lua_pop(L, 1);
  }
  options.args[len] = NULL;
  lua_pop(L, 1);

  // get the stdio list
  lua_getfield(L, 2, "stdio");
  if (lua_type(L, -1) == LUA_TTABLE) {
    options.stdio_count = len = lua_rawlen(L, -1);
    options.stdio = malloc(len * sizeof(*options.stdio));
    if (!options.stdio) {
      luv_clean_options(&options);
      return luaL_error(L, "Problem allocating stdio");
    }
    for (i = 0; i < len; ++i) {
      lua_rawgeti(L, -1, i + 1);
      // integers are assumed to be file descripters
      if (lua_type(L, -1) == LUA_TNUMBER) {
        options.stdio[i].flags = UV_INHERIT_FD;
        options.stdio[i].data.fd = lua_tointeger(L, -1);
      }
      // userdata is assumed to be a uv_stream_t instance
      else if (lua_type(L, -1) == LUA_TUSERDATA) {
        uv_os_fd_t fd;
        uv_stream_t* stream = luv_check_stream(L, -1);
        int err = uv_fileno((uv_handle_t*)stream, &fd);
        if (err == UV_EINVAL || err == UV_EBADF) {
          options.stdio[i].flags = UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE;
        }
        else {
          options.stdio[i].flags = UV_INHERIT_STREAM;
        }
        options.stdio[i].data.stream = stream;
      }
      else if (lua_type(L, -1) == LUA_TNIL) {
        options.stdio[i].flags = UV_IGNORE;
      }
      else {
        luv_clean_options(&options);
        return luaL_argerror(L, 2, "stdio table entries must be nil, uv_stream_t, or integer");
      }
      lua_pop(L, 1);
    }
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 2, "stdio option must be table");
  }
  lua_pop(L, 1);

  // Get the env
  lua_getfield(L, 2, "env");
  if (lua_type(L, -1) == LUA_TTABLE) {
    len = lua_rawlen(L, -1);
    options.env = malloc((len + 1) * sizeof(*options.env));
    if (!options.env) {
      luv_clean_options(&options);
      return luaL_error(L, "Problem allocating env");
    }
    for (i = 0; i < len; ++i) {
      lua_rawgeti(L, -1, i + 1);
      options.env[i] = (char*)lua_tostring(L, -1);
      lua_pop(L, 1);
    }
    options.env[len] = NULL;
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 2, "env option must be table");
  }
  lua_pop(L, 1);

  // Get the cwd
  lua_getfield(L, 2, "cwd");
  if (lua_type(L, -1) == LUA_TSTRING) {
    options.cwd = (char*)lua_tostring(L, -1);
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 2, "cwd option must be string");
  }
  lua_pop(L, 1);

  // Check for uid
  lua_getfield(L, 2, "uid");
  if (lua_type(L, -1) == LUA_TNUMBER) {
    options.uid = lua_tointeger(L, -1);
    options.flags |= UV_PROCESS_SETUID;
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 2, "uid option must be number");
  }
  lua_pop(L, 1);

  // Check for gid
  lua_getfield(L, 2, "gid");
  if (lua_type(L, -1) == LUA_TNUMBER) {
    options.gid = lua_tointeger(L, -1);
    options.flags |= UV_PROCESS_SETGID;
  }
  else if (lua_type(L, -1) != LUA_TNIL) {
    luv_clean_options(&options);
    return luaL_argerror(L, 2, "gid option must be number");
  }
  lua_pop(L, 1);

  // Check for the boolean flags
  lua_getfield(L, 2, "verbatim");
  if (lua_toboolean(L, -1)) {
    options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
  }
  lua_pop(L, 1);
  lua_getfield(L, 2, "detached");
  if (lua_toboolean(L, -1)) {
    options.flags |= UV_PROCESS_DETACHED;
  }
  lua_pop(L, 1);
  lua_getfield(L, 2, "hide");
  if (lua_toboolean(L, -1)) {
    options.flags |= UV_PROCESS_WINDOWS_HIDE;
  }
  lua_pop(L, 1);

  handle = lua_newuserdata(L, sizeof(*handle));
  handle->type = UV_PROCESS;
  handle->data = luv_setup_handle(L);

  if (!lua_isnoneornil(L, 3)) {
    luv_check_callback(L, handle->data, LUV_EXIT, 3);
  }

  ret = uv_spawn(luv_loop(L), handle, &options);

  luv_clean_options(&options);
  if (ret < 0) {
    /* The async callback is required here because luajit GC may reclaim the
     * luv handle before libuv is done closing it down.
     */
    uv_close((uv_handle_t*)handle, luv_spawn_close_cb);
    return luv_error(L, ret);
  }
  lua_pushinteger(L, handle->pid);
  return 2;
}