Esempio n. 1
0
/*
 * Arguments: evq_udata, ev_ludata, [reuse_fd (boolean)]
 * Returns: [evq_udata]
 */
static int
levq_del (lua_State *L)
{
    struct event_queue *evq = checkudata(L, 1, EVQ_TYPENAME);
    struct event *ev = levq_toevent(L, 2);
    const int reuse_fd = lua_toboolean(L, 3);
    int res = 0;

    lua_assert(ev);

#undef ARG_LAST
#define ARG_LAST	1

#ifdef EVQ_POST_INIT
    if (ev == evq->ev_post)
	evq->ev_post = NULL;
#endif

    if (!event_deleted(ev))
	res = evq_del(ev, reuse_fd);

    if (!(ev->flags & (EVENT_ACTIVE | EVENT_DELETE)))
	levq_del_event(evq, ev);

    ev->flags |= EVENT_DELETE;

    if (!res) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 2
0
/*
 * Returns: [thread_ludata]
 */
static int
thread_init (lua_State *L)
{
    struct sys_thread *td;

    /* TLS Index */
    if (g_TLSIndex == INVALID_TLS_INDEX) {
#ifndef _WIN32
	const int res = pthread_key_create(&g_TLSIndex, NULL);
	if (res) {
	    errno = res;
	    goto err;
	}
#else
	if ((g_TLSIndex = TlsAlloc()) == INVALID_TLS_INDEX)
	    goto err;
#endif
    }
    /* VM Mutex */
    td = sys_get_thread();
    if (!td) {
	if (vmthread_new(L, (void *) &td))
	    goto err;

	thread_settable(L, L, td->tid);
	sys_set_thread(td);
	sys_vm2_enter(td);
    }
    lua_pushlightuserdata(L, td->vmtd);
    return 1;
 err:
    return sys_seterror(L, 0);
}
Esempio n. 3
0
/*
 * Returns: [evq_udata]
 */
static int
levq_new (lua_State *L)
{
    struct event_queue *evq = lua_newuserdata(L, sizeof(struct event_queue));

    memset(evq, 0, sizeof(struct event_queue));

    lua_assert(sizeof(struct event) >= sizeof(struct timeout_queue));
    lua_assert(sizeof(struct event) >= sizeof(struct evq_sync_op));

    if (!evq_init(evq)) {
	lua_State *NL;

	luaL_getmetatable(L, EVQ_TYPENAME);
	lua_setmetatable(L, -2);

	lua_newtable(L);  /* environ. (EVQ_CORO_ENV) */
	lua_pushvalue(L, -1);
	lua_setfenv(L, -3);

	NL = lua_newthread(L);
	if (!NL) return 0;

	evq->L = NL;
	lua_rawsetp(L, -2, NL);  /* save coroutine to avoid GC */

	lua_newtable(L);  /* {ev_id => cb_func} (EVQ_CORO_CALLBACK) */
	lua_newtable(L);  /* {ev_id => obj_udata} (EVQ_CORO_UDATA) */
	lua_xmove(L, NL, 3);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 4
0
/*
 * Arguments: sd_udata, new_sd_udata, [sock_addr_udata]
 * Returns: [new_sd_udata | false (EAGAIN)]
 */
static int
sock_accept (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    sd_t *sdp = checkudata(L, 2, SD_TYPENAME);
    struct sock_addr *from = lua_isnoneornil(L, 3) ? NULL
     : checkudata(L, 3, SA_TYPENAME);
    struct sockaddr *sap = NULL;
    socklen_t *slp = NULL;

    if (from) {
	sap = &from->u.addr;
	slp = &from->addrlen;
    }
#ifndef _WIN32
    do sd = accept(sd, sap, slp);
    while (sd == -1 && SYS_ERRNO == EINTR);
#else
    sd = accept(sd, sap, slp);
#endif
    if (sd != (sd_t) -1) {
	*sdp = sd;
	lua_settop(L, 2);
	return 1;
    }
    else if (SYS_EAGAIN(SYS_ERRNO)) {
	lua_pushboolean(L, 0);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 5
0
/*
 * Arguments: path (string)
 * Returns: [total_bytes (number), available_bytes (number),
 *	free_bytes (number)]
 */
static int
sys_statfs (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  int64_t ntotal, navail, nfree;
  int res;

#ifndef _WIN32
  struct statvfs buf;

  sys_vm_leave(L);
  res = statvfs(path, &buf);
  sys_vm_enter(L);

  ntotal = buf.f_blocks * buf.f_frsize;
  nfree = buf.f_bfree * buf.f_bsize;
  navail = buf.f_bavail * buf.f_bsize;
#else
  ULARGE_INTEGER na, nt, nf;

  SetErrorMode(SEM_FAILCRITICALERRORS);  /* for floppy disks */
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    res = is_WinNT
     ? !GetDiskFreeSpaceExW(os_path, &na, &nt, &nf)
     : !GetDiskFreeSpaceExA(os_path, &na, &nt, &nf);

    free(os_path);
    sys_vm_enter(L);
  }

  ntotal = (int64_t) nt.QuadPart;
  nfree = (int64_t) nf.QuadPart;
  navail = (int64_t) na.QuadPart;
#endif
  if (!res) {
    lua_pushnumber(L, (lua_Number) ntotal);
    lua_pushnumber(L, (lua_Number) navail);
    lua_pushnumber(L, (lua_Number) nfree);
    return 3;
  }
  return sys_seterror(L, 0);
}
Esempio n. 6
0
/*
 * Arguments: dpool_udata, data_items (any) ...
 */
static int
dpool_put (lua_State *L)
{
    struct sys_thread *td = sys_thread_get();
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    int nput = lua_gettop(L) - 1;

    if (!td) luaL_argerror(L, 0, "Threading not initialized");
    if (!nput) luaL_argerror(L, 2, "data expected");

    lua_getfenv(L, 1);  /* storage */
    lua_insert(L, 1);

    if (dp->n >= dp->max) {
	if (dp->flags & DPOOL_PUTONFULL) {
	    lua_rawgetp(L, 1, (void *) DPOOL_PUTONFULL);
	    lua_insert(L, 2);
	    lua_call(L, 1 + nput, LUA_MULTRET);
	    nput = lua_gettop(L) - 1;
	    if (!nput) return 0;
	} else {
	    do {
		const int res = thread_event_wait(&dp->tev, td,
		 TIMEOUT_INFINITE);

		sys_thread_check(td);
		if (res) return sys_seterror(L, 0);
	    } while (dp->n >= dp->max);
	}
    }

    /* Try directly move data between threads */
    if (dp->nwaits && !dp->td) {
	dp->td = td;
	dp->nput = nput;
	thread_event_signal(&dp->tev);
	sys_thread_switch(0);
	dp->td = NULL;
	if (!dp->nput) return 0;  /* moved to thread */
	dp->nput = 0;
    }

    /* Keep data in the storage */
    {
	int top = dp->top;

	lua_pushinteger(L, nput);
	do {
	    lua_rawseti(L, 1, ++top);
	} while (nput--);
	dp->top = top;

	if (!dp->n++) {
	    thread_event_signal(&dp->tev);
	}
    }
    return 0;
}
Esempio n. 7
0
/*
 * Arguments: dpool_udata, data_items (any) ...
 */
static int
dpool_put (lua_State *L)
{
    struct sys_thread *td = sys_get_thread();
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    int nput = lua_gettop(L) - 1;

    if (!td) luaL_argerror(L, 0, "Threading not initialized");
    if (!nput) luaL_argerror(L, 2, "data expected");

    lua_getfenv(L, 1);  /* storage */
    lua_insert(L, 1);

    if (dp->n >= dp->max) {
	if (dp->flags & DPOOL_PUTONFULL) {
	    lua_pushlightuserdata(L, (void *) DPOOL_PUTONFULL);
	    lua_rawget(L, 1);
	    lua_insert(L, 2);
	    lua_call(L, 1 + nput, LUA_MULTRET);
	    nput = lua_gettop(L) - 1;
	    if (!nput) return 0;
	} else do {
	    if (thread_event_wait(&dp->tev, TIMEOUT_INFINITE))
		return sys_seterror(L, 0);
	} while (dp->n >= dp->max);
    }

    /* Try directly move data between threads */
    if (dp->nwaits && !dp->td) {
	dp->td = td;
	dp->nput = nput;
	thread_event_signal(&dp->tev);
	thread_yield(L);
	dp->td = NULL;
	if (!dp->nput) return 0;  /* moved to thread */
	dp->nput = 0;
    }

    /* Keep data in the storage */
    {
	int top = dp->top;

	lua_pushinteger(L, nput);
	do {
	    lua_rawseti(L, 1, ++top);
	} while (nput--);
	dp->top = top;

	/* notify event_queue */
	if (!dp->n++ && dp->trigger)
	    sys_trigger_notify(&dp->trigger, SYS_EVREAD);

	thread_event_signal(&dp->tev);
    }
    return 0;
}
Esempio n. 8
0
/*
 * Arguments: sd_udata, nonblocking (boolean)
 * Returns: [sd_udata]
 */
static int
sock_nonblocking (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    unsigned long opt = lua_toboolean(L, 2);

    lua_settop(L, 1);
    return !ioctlsocket(sd, FIONBIO, &opt) ? 1
     : sys_seterror(L, 0);
}
Esempio n. 9
0
/*
 * Arguments: fd_udata, path (string), [permissions (number)]
 * Returns: [fd_udata]
 */
static int
sys_create (lua_State *L)
{
  fd_t fd, *fdp = checkudata(L, 1, FD_TYPENAME);
  const char *path = luaL_checkstring(L, 2);
#ifndef _WIN32
  mode_t perm = (mode_t) luaL_optinteger(L, 3, SYS_FILE_PERMISSIONS);
#endif

#ifndef _WIN32
  sys_vm_leave(L);
  fd = creat(path, perm);
  sys_vm_enter(L);
#else
  {
    const int flags = GENERIC_WRITE;
    const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE
     | FILE_SHARE_DELETE;
    const DWORD creation = CREATE_ALWAYS;
    const DWORD attr = FILE_ATTRIBUTE_NORMAL
     | SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION;

    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    fd = is_WinNT
     ? CreateFileW(os_path, flags, share, NULL, creation, attr, NULL)
     : CreateFileA(os_path, flags, share, NULL, creation, attr, NULL);

    free(os_path);
    sys_vm_enter(L);
  }
#endif

  if (fd != (fd_t) -1) {
    *fdp = fd;
    lua_settop(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Esempio n. 10
0
/*
 * Arguments: path (string)
 * Returns: [boolean]
 */
static int
sys_chroot (lua_State *L)
{
    const char *path = luaL_checkstring(L, 1);

    if (!chroot(path)) {
	lua_pushboolean(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 11
0
/*
 * Arguments: sd_udata, [backlog (number)]
 * Returns: [sd_udata]
 */
static int
sock_listen (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    const int backlog = luaL_optinteger(L, 2, SOMAXCONN);

    if (!listen(sd, backlog)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 12
0
/*
 * Arguments: sd_udata, sock_addr_udata
 * Returns: [sd_udata]
 */
static int
sock_bind (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    struct sock_addr *sap = checkudata(L, 2, SA_TYPENAME);

    if (!bind(sd, &sap->u.addr, sap->addrlen)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 13
0
/*
 * Arguments: sd_udata
 * Returns: [sd_udata]
 */
static int
sock_shutdown (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);

    /* SHUT_RD (SD_RECEIVE) has different behavior in unix and win32 */
    if (!shutdown(sd, SHUT_WR)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 14
0
/*
 * Arguments: path (string), [permissions (number)]
 * Returns: [boolean]
 */
static int
sys_mkfifo (lua_State *L)
{
    const char *path = luaL_checkstring(L, 1);
    mode_t perm = (mode_t) luaL_optinteger(L, 2, SYS_FILE_PERMISSIONS);

    if (!mkfifo(path, perm)) {
	lua_pushboolean(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 15
0
/*
 * Arguments: evq_udata, signal (string), ignore (boolean)
 * Returns: [evq_udata]
 */
static int
levq_ignore_signal (lua_State *L)
{
    struct event_queue *evq = checkudata(L, 1, EVQ_TYPENAME);
    const int signo = sig_flags[luaL_checkoption(L, 2, NULL, sig_names)];
    const int ignore = lua_toboolean(L, 3);

    if (!evq_ignore_signal(evq, signo, ignore)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 16
0
/*
 * Arguments: evq_udata, [signal (string)]
 * Returns: [evq_udata]
 */
static int
levq_signal (lua_State *L)
{
    struct event_queue *evq = checkudata(L, 1, EVQ_TYPENAME);
    const int signo = lua_isnoneornil(L, 2) ? EVQ_SIGEVQ
     : sig_flags[luaL_checkoption(L, 2, NULL, sig_names)];

    if (!evq_signal(evq, signo)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 17
0
/*
 * Arguments: [buffer_max_size (number), buffer_min_size (number)]
 * Returns: [pipe_udata]
 */
static int
pipe_new (lua_State *L)
{
    const unsigned int max_size = (unsigned int)
     luaL_optinteger(L, 1, PIPE_BUF_MAXSIZE);
    const unsigned int min_size = (unsigned int)
     luaL_optinteger(L, 2, PIPE_BUF_MINSIZE);
    struct pipe_ref *pr;
    struct pipe *pp;

    if (min_size > max_size
     || min_size < PIPE_BUF_MINSIZE
     || max_size > PIPE_BUF_MAXSIZE
     /* (max_size / min_size) should be power of 2 */
     || ((max_size / min_size) & (max_size / min_size - 1)) != 0)
	luaL_argerror(L, 1, "invalid size");

    pr = lua_newuserdata(L, sizeof(struct pipe_ref));
    pp = calloc(sizeof(struct pipe), 1);
    if (!pp) goto err;

    pr->pipe = pp;
    pr->put_timeout = TIMEOUT_INFINITE;

    luaL_getmetatable(L, PIPE_TYPENAME);
    lua_setmetatable(L, -2);

    if (thread_critsect_new(&pp->cs)
     || thread_cond_new(&pp->put_cond)
     || thread_cond_new(&pp->get_cond))
	goto err;

    /* allocate initial buffer */
    {
	struct pipe_buf *pb = malloc(min_size);

	if (!pb) goto err;

	memset(pb, 0, sizeof(struct pipe_buf));
	pb->len = min_size - PIPE_BUF_EXTRASIZE;
	pb->next_buf = pb;

	pp->rbuf = pp->wbuf = pb;
	pp->buf_size = min_size;
    }
    pp->buf_max_size = max_size;

    return 1;
 err:
    return sys_seterror(L, 0);
}
Esempio n. 18
0
/*
 * Arguments: existing_path (string), new_path (string)
 * Returns: [boolean]
 */
static int
sys_rename (lua_State *L)
{
  const char *old = luaL_checkstring(L, 1);
  const char *new = luaL_checkstring(L, 2);
  int res;

#ifndef _WIN32
  sys_vm_leave(L);
  res = rename(old, new);
  sys_vm_enter(L);
#else
  {
    void *os_old = utf8_to_filename(old);
    void *os_new = utf8_to_filename(new);
    if (!os_old || !os_new) {
      free(os_old);
      free(os_new);
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);
    }

    sys_vm_leave(L);
    res = is_WinNT
     ? !MoveFileW(os_old, os_new)
     : !MoveFileA(os_old, os_new);

    free(os_old);
    free(os_new);
    sys_vm_enter(L);
  }
#endif

  if (!res) {
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Esempio n. 19
0
/*
 * Arguments: path (string)
 * Returns: [string]
 */
static int
sys_realpath (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);

#ifndef _WIN32
  char real[PATH_MAX];

  if (realpath(path, real)) {
    lua_pushstring(L, real);
    return 1;
  }
#else
  void *os_path = utf8_to_filename(path);
  if (!os_path)
    return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

  {
    WCHAR os_real[MAX_PATHNAME];
    const int n = is_WinNT
     ? GetFullPathNameW(os_path, MAX_PATHNAME, os_real, NULL)
     : GetFullPathNameA(os_path, MAX_PATHNAME, (char *) os_real, NULL);

    free(os_path);

    if (n != 0 && n < MAX_PATHNAME) {
      void *real = filename_to_utf8(os_real);
      if (!real)
        return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

      lua_pushstring(L, real);
      free(real);
      return 1;
    }
  }
#endif
  return sys_seterror(L, 0);
}
Esempio n. 20
0
/*
 * Arguments: reg_udata, subkey (string)
 * Returns: [reg_udata]
 */
static int
reg_del_key (lua_State *L)
{
    HKEY hk = lua_unboxpointer(L, 1, WREG_TYPENAME);
    const char *subkey = luaL_checkstring(L, 2);
    int res;

    res = RegDeleteKeyA(hk, subkey);
    if (!res) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, res);
}
Esempio n. 21
0
/*
 * Arguments: reg_udata, [name (string)]
 * Returns: [reg_udata]
 */
static int
reg_del_value (lua_State *L)
{
    HKEY hk = lua_unboxpointer(L, 1, WREG_TYPENAME);
    const char *name = lua_tostring(L, 2);
    int res;

    res = RegDeleteValueA(hk, name);
    if (!res) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, res);
}
Esempio n. 22
0
/*
 * Arguments: sd_udata, option (string),
 *	[value_lo (number), value_hi (number)]
 * Returns: [sd_udata | value_lo (number), value_hi (number)]
 */
static int
sock_sockopt (lua_State *L)
{
    static const int opt_flags[] = {
	SO_REUSEADDR, SO_TYPE, SO_ERROR, SO_DONTROUTE,
	SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT, SO_RCVLOWAT,
	SO_BROADCAST, SO_KEEPALIVE, SO_OOBINLINE, SO_LINGER,
#define OPTNAMES_TCP	12
	TCP_NODELAY,
#define OPTNAMES_IP	13
	IP_MULTICAST_TTL, IP_MULTICAST_IF, IP_MULTICAST_LOOP
    };
    static const char *const opt_names[] = {
	"reuseaddr", "type", "error", "dontroute",
	"sndbuf", "rcvbuf", "sndlowat", "rcvlowat",
	"broadcast", "keepalive", "oobinline", "linger",
	"tcp_nodelay",
	"multicast_ttl", "multicast_if", "multicast_loop", NULL
    };
#undef OPT_START
#define OPT_START	2
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    const int optname = luaL_checkoption(L, OPT_START, NULL, opt_names);
    const int level = (optname < OPTNAMES_TCP) ? SOL_SOCKET
     : (optname < OPTNAMES_IP ? IPPROTO_TCP : IPPROTO_IP);
    const int optflag = opt_flags[optname];
    int optval[4];
    socklen_t optlen = sizeof(int);
    const int nargs = lua_gettop(L);

    if (nargs > OPT_START) {
	optval[0] = lua_tointeger(L, OPT_START + 1);
	if (nargs > OPT_START + 1) {
	    optval[1] = lua_tointeger(L, OPT_START + 2);
	    optlen *= 2;
	}
	if (!setsockopt(sd, level, optflag, (char *) &optval, optlen)) {
	    lua_settop(L, 1);
	    return 1;
	}
    }
    else if (!getsockopt(sd, level, optflag, (char *) &optval, &optlen)) {
	lua_pushinteger(L, optval[0]);
	if (optlen <= sizeof(int))
	    return 1;
	lua_pushinteger(L, optval[1]);
	return 2;
    }
    return sys_seterror(L, 0);
}
Esempio n. 23
0
/*
 * Returns: [rand_udata]
 */
static int
sys_random (lua_State *L)
{
#ifndef _WIN32
  fd_t *fdp = lua_newuserdata(L, sizeof(fd_t));

#if defined(__OpenBSD__)
  *fdp = open("/dev/arandom", O_RDONLY, 0);
  if (*fdp == (fd_t) -1)
    *fdp = open("/dev/urandom", O_RDONLY, 0);
#else
  *fdp = open("/dev/urandom", O_RDONLY, 0);
#endif
  if (*fdp != (fd_t) -1) {
#else
  HCRYPTPROV *p = lua_newuserdata(L, sizeof(void *));

  if (CryptAcquireContext(p, NULL, NULL,
   PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
#endif
    luaL_getmetatable(L, RAND_TYPENAME);
    lua_setmetatable(L, -2);
    return 1;
  }
  return sys_seterror(L, 0);
}

/*
 * Arguments: rand_udata
 */
static int
rand_close (lua_State *L)
{
#ifndef _WIN32
  fd_t *fdp = (fd_t *) checkudata(L, 1, RAND_TYPENAME);

  if (*fdp != (fd_t) -1) {
    close(*fdp);
    *fdp = (fd_t) -1;
  }
#else
  HCRYPTPROV *p = (HCRYPTPROV *) checkudata(L, 1, RAND_TYPENAME);

  if (*p != (HCRYPTPROV) -1) {
    CryptReleaseContext(*p, 0);
    *p = (HCRYPTPROV) -1;
  }
#endif
  return 0;
}
Esempio n. 24
0
/*
 * Arguments: sd_udata, binary_address (multiaddr),
 *	[binary_address_ipv4 (interface) | interface_ipv6 (number),
 *	add/drop (boolean)]
 * Returns: [sd_udata]
 */
static int
sock_membership (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    int len, af;
    const char *maddrp = sock_checkladdr(L, 2, &len, &af);
    const int optflag = !lua_isboolean(L, -1) || lua_toboolean(L, -1)
     ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
    union {
	struct ip_mreq ip;
#ifdef IPPROTO_IPV6
	struct ipv6_mreq ip6;
#endif
    } mr;
    int level, mr_len;

    memset(&mr, 0, sizeof(mr));
    if (af == AF_INET) {
	const char *ifacep = (lua_type(L, 3) == LUA_TSTRING)
	 ? sock_checkladdr(L, 3, &len, &af) : NULL;

	if (ifacep && af != AF_INET)
	    luaL_argerror(L, 3, "invalid interface");

	memcpy(&mr.ip.imr_multiaddr, maddrp, len);
	if (ifacep)
	    memcpy(&mr.ip.imr_interface, ifacep, len);

	level = IPPROTO_IP;
	mr_len = sizeof(struct ip_mreq);
    }
    else {
#ifdef IPPROTO_IPV6
	memcpy(&mr.ip6.ipv6mr_multiaddr, maddrp, len);
	mr.ip6.ipv6mr_interface = lua_tointeger(L, 3);

	level = IPPROTO_IPV6;
	mr_len = sizeof(struct ipv6_mreq);
#else
	luaL_argerror(L, 2, "invalid family");
#endif
    }

    if (!setsockopt(sd, level, optflag, (char *) &mr, mr_len)) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 25
0
/*
 * Arguments: dpool_udata, [timeout (milliseconds)]
 * Returns: [signalled/timedout (boolean)]
 */
static int
dpool_wait (lua_State *L)
{
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    const msec_t timeout = lua_isnoneornil(L, 2)
     ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 2);
    int res;

    res = thread_event_wait(&dp->tev, timeout);
    if (res >= 0) {
	lua_pushboolean(L, !res);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 26
0
/*
 * Arguments: ecb_udata, {string | membuf_udata} ...
 * Returns: [success/partial (boolean), count (number)]
 */
static int
ecb_write (lua_State *L)
{
  LPEXTENSION_CONTROL_BLOCK ecb = lua_unboxpointer(L, 1, ECB_TYPENAME);
  size_t n = 0;  /* number of chars actually write */
  int i, narg = lua_gettop(L);

  if (ecb->dwHttpStatusCode & ECB_STATUS_HEADERS_SEND) {
    ecb->dwHttpStatusCode ^= ECB_STATUS_HEADERS_SEND;

    lua_pushfstring(L, "HTTP/1.1 %d\r\n",
     (ecb->dwHttpStatusCode & ECB_STATUS_MASK));

    lua_rawgetp(L, LUA_REGISTRYINDEX, ecb);

    lua_pushliteral(L, "\r\n");
    lua_concat(L, 3);

    lua_insert(L, 2);
    ++narg;
  }

  for (i = 2; i <= narg; ++i) {
    struct sys_buffer sb;
    int nw;

    if (!sys_buffer_read_init(L, i, &sb)
     || sb.size == 0)  /* don't close the connection */
      continue;
    sys_vm_leave();
    {
      DWORD l = sb.size;
      nw = ecb->WriteClient(ecb->ConnID, sb.ptr.w, &l, 0)
       ? (int) l : -1;
    }
    sys_vm_enter();
    if (nw == -1) {
      if (n > 0) break;
      return sys_seterror(L, 0);
    }
    n += nw;
    sys_buffer_read_next(&sb, nw);
    if ((size_t) nw < sb.size) break;
  }
  lua_pushboolean(L, (i > narg));
  lua_pushinteger(L, n);
  return 2;
}
Esempio n. 27
0
/*
 * Arguments: reg_udata, [root (reg_udata | string), subkey (string),
 *	mode (string: "r", "w", "rw")]
 * Returns: [reg_udata]
 */
static int
reg_open (lua_State *L)
{
    HKEY *hkp = checkudata(L, 1, WREG_TYPENAME);
    HKEY hk = reg_root2key(L, 2);
    const char *subkey = lua_tostring(L, 3);
    REGSAM desired = reg_mode2sam(L, 4);
    int res;

    res = RegOpenKeyExA(hk, subkey, 0, desired, hkp);
    if (!res) {
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, res);
}
Esempio n. 28
0
/*
 * Returns: [dpool_udata]
 */
static int
thread_data_pool (lua_State *L)
{
    struct data_pool *dp = lua_newuserdata(L, sizeof(struct data_pool));
    memset(dp, 0, sizeof(struct data_pool));
    dp->max = (unsigned int) -1;

    if (!thread_event_new(&dp->tev)) {
	luaL_getmetatable(L, DPOOL_TYPENAME);
	lua_setmetatable(L, -2);

	lua_newtable(L);  /* data and callbacks storage */
	lua_setfenv(L, -2);
	return 1;
    }
    return sys_seterror(L, 0);
}
Esempio n. 29
0
/*
 * Arguments: [timeout (milliseconds)]
 * Returns: [boolean]
 */
static int
thread_suspend_wrap (lua_State *L)
{
  struct sys_thread *td = sys_thread_get();
  const msec_t timeout = lua_isnoneornil(L, 1)
   ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 1);
  const int res = sys_thread_suspend(td, timeout);

  if (res >= 0) {
    if (res == 1) {
      lua_pushboolean(L, 0);
      return 1;  /* timed out */
    }
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Esempio n. 30
0
static int
thread_channel (lua_State *L)
{
    struct channel *chan = lua_newuserdata(L, sizeof(struct channel));
    memset(chan, 0, sizeof(struct channel));
    chan->max = (unsigned int) -1;

    if (!thread_cond_new(&chan->put) && !thread_cond_new(&chan->get)) {
        thread_critsect_new(&chan->mutex);
	luaL_getmetatable(L, CHANNEL_TYPENAME);
	lua_setmetatable(L, -2);

	lua_newtable(L);  /* data storage */
	lua_setfenv(L, -2);
	return 1;
    }
    return sys_seterror(L, 0);
}