Example #1
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;
}
Example #2
0
/*
 * Arguments: sd_udata, {string | membuf_udata},
 *	[to (sock_addr_udata), options (string) ...]
 * Returns: [success/partial (boolean), count (number)]
 */
static int
sock_send (lua_State *L)
{
    static const int o_flags[] = {
	MSG_OOB, MSG_DONTROUTE,
    };
    static const char *const o_names[] = {
	"oob", "dontroute", NULL
    };
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    const struct sock_addr *to = !lua_isuserdata(L, 3) ? NULL
     : checkudata(L, 3, SA_TYPENAME);
    struct sys_buffer sb;
    int nw;  /* number of chars actually send */
    unsigned int i, flags = 0;

    if (!sys_buffer_read_init(L, 2, &sb))
	luaL_argerror(L, 2, "buffer expected");
    for (i = lua_gettop(L); i > 3; --i) {
	flags |= o_flags[luaL_checkoption(L, i, NULL, o_names)];
    }
    sys_vm_leave();
    do nw = !to ? send(sd, sb.ptr.r, sb.size, flags)
     : sendto(sd, sb.ptr.r, sb.size, flags, &to->u.addr, to->addrlen);
    while (nw == -1 && SYS_ERRNO == EINTR);
    sys_vm_enter();
    if (nw == -1) {
	if (!SYS_EAGAIN(SYS_ERRNO))
	    return sys_seterror(L, 0);
	nw = 0;
    } else {
	sys_buffer_read_next(&sb, nw);
    }
    lua_pushboolean(L, ((size_t) nw == sb.size));
    lua_pushinteger(L, nw);
    return 2;
}
Example #3
0
/*
 * Arguments: sd_udata, fd_udata, [count (number)]
 * Returns: [count (number) | false (EAGAIN)]
 */
static int
sock_sendfile (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    fd_t fd = (fd_t) lua_unboxinteger(L, 2, FD_TYPENAME);
    size_t n = (size_t) lua_tointeger(L, 3);
    ssize_t res;

    sys_vm_leave();
#ifndef _WIN32
#if defined(__linux__)
    do res = sendfile(sd, fd, NULL, n ? n : ~((size_t) 0));
    while (res == -1 && SYS_ERRNO == EINTR);
#else
    {
	off_t nw, off = lseek(fd, 0, SEEK_CUR);

#if defined(__APPLE__) && defined(__MACH__)
	nw = n;
	do res = sendfile(fd, sd, off, &nw, NULL, 0);
#else
	do res = sendfile(fd, sd, off, n, NULL, &nw, 0);
#endif
	while (res == -1 && SYS_ERRNO == EINTR);
	if (res != -1) {
	    res = (size_t) nw;
	    lseek(fd, nw, SEEK_CUR);
	}
    }
#endif
    sys_vm_enter();

    if (res != -1 || SYS_EAGAIN(SYS_ERRNO)) {
	if (res == -1) {
	    lua_pushboolean(L, 0);
	    return 1;
	}
#else
    res = TransmitFileMap(sd, fd, n);
    sys_vm_enter();

    if (res != 0L) {
#endif
	lua_pushinteger(L, res);
	return 1;
    }
    return sys_seterror(L, 0);
}

/*
 * Arguments: sd_udata, {string | membuf_udata} ...
 * Returns: [success/partial (boolean), count (number)]
 */
static int
sock_write (lua_State *L)
{
    sd_t sd = (sd_t) lua_unboxinteger(L, 1, SD_TYPENAME);
    ssize_t n = 0;  /* number of chars actually write */
    int i, nargs = lua_gettop(L);

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

	if (!sys_buffer_read_init(L, i, &sb))
	    continue;
	sys_vm_leave();
#ifndef _WIN32
	do nw = write(sd, sb.ptr.r, sb.size);
	while (nw == -1 && SYS_ERRNO == EINTR);
#else
	{
	    WSABUF buf = {sb.size, sb.ptr.w};
	    DWORD l;
	    nw = !WSASend(sd, &buf, 1, &l, 0, NULL, NULL) ? l : -1;
	}
#endif
	sys_vm_enter();
	if (nw == -1) {
	    if (n > 0 || SYS_EAGAIN(SYS_ERRNO)) 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 > nargs));
    lua_pushinteger(L, n);
    return 2;
}