Use POSIX file functions
introduce dup()
introduce fork() wait() kill()
more signal interrupt wrappers
more POSIX / UNIX standard compliance
This commit is contained in:
Steven Barth 2009-03-03 22:44:26 +00:00
parent a3079828b4
commit e38c438771
14 changed files with 326 additions and 120 deletions

View file

@ -23,19 +23,14 @@ module "luci.httpclient.receiver"
local function prepare_fd(target)
-- Open fd for appending
local file, code, msg = nixio.open(target, "r+")
if not file and code == nixio.const.ENOENT then
file, code, msg = nixio.open(target, "w")
if file then
file:flush()
end
end
local oflags = nixio.open_flags("wronly", "creat")
local file, code, msg = nixio.open(target, oflags)
if not file then
return file, code, msg
end
-- Acquire lock
local stat, code, msg = file:lock("ex", "nb")
local stat, code, msg = file:lock("tlock")
if not stat then
return stat, code, msg
end

View file

@ -6,10 +6,12 @@ AXTLS_VERSION = 1.2.1
AXTLS_DIR = axTLS
AXTLS_FILE = $(AXTLS_DIR)-$(AXTLS_VERSION).tar.gz
NIXIO_TLS ?= axtls
EXTRA_CFLAGS = -std=c99
NIXIO_CFLAGS = -D_XOPEN_SOURCE=500
NIXIO_OBJ = src/nixio.o src/socket.o src/sockopt.o src/bind.o src/address.o \
src/poll.o src/io.o src/file.o src/splice.o src/tls-context.o \
src/tls-socket.o
src/poll.o src/io.o src/file.o src/splice.o src/process.o \
src/tls-context.o src/tls-socket.o
ifeq ($(NIXIO_TLS),axtls)
TLS_CFLAGS = -IaxTLS/{ssl,crypto,config} -include src/openssl-compat.h
@ -22,17 +24,21 @@ ifeq ($(NIXIO_TLS),openssl)
TLS_LDFLAGS = -lssl
endif
ifeq ($(OS),Linux)
NIXIO_CFLAGS = -D_GNU_SOURCE
endif
%.o: %.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
src/tls-context.o: $(TLS_DEPENDS) src/tls-context.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-context.c
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-context.c
src/tls-socket.o: $(TLS_DEPENDS) src/tls-socket.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-socket.c
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-socket.c
src/openssl-compat.o: src/libaxtls.a src/openssl-compat.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/openssl-compat.c
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/openssl-compat.c
compile: $(NIXIO_OBJ)
@ -47,7 +53,7 @@ $(AXTLS_DIR)/.prepared:
touch $@
src/libaxtls.a: $(AXTLS_DIR)/.prepared
$(MAKE) -C $(AXTLS_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
$(MAKE) -C $(AXTLS_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) '-Dalloca(size)=__builtin_alloca(size)' -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
cp -p $(AXTLS_DIR)/_stage/libaxtls.a src
clean: luaclean

7
libs/nixio/README Normal file
View file

@ -0,0 +1,7 @@
Building:
With axTLS (standard):
make
With OpenSSL:
make NIXIO_TLS=openssl

View file

@ -1,7 +1,7 @@
--[[
nixio - Linux I/O library for lua
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2009 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View file

@ -23,6 +23,10 @@
#include <string.h>
#include <netdb.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
/**
* getaddrinfo(host, family, port)

View file

@ -24,6 +24,7 @@
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include "nixio.h"
/**
@ -77,7 +78,7 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
/* create socket object */
nixio_sock *sock = lua_newuserdata(L, sizeof(nixio_sock));
int status = -1;
int status = -1, clstat;
for (rp = result; rp != NULL; rp = rp->ai_next) {
sock->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
@ -88,7 +89,9 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
if (do_bind) {
status = bind(sock->fd, rp->ai_addr, rp->ai_addrlen);
} else {
status = connect(sock->fd, rp->ai_addr, rp->ai_addrlen);
do {
status = connect(sock->fd, rp->ai_addr, rp->ai_addrlen);
} while (status == -1 && errno == EINTR);
}
/* on success */
@ -99,7 +102,9 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
break;
}
close(sock->fd);
do {
clstat = close(sock->fd);
} while (clstat == -1 && errno == EINTR);
}
freeaddrinfo(result);
@ -166,7 +171,9 @@ static int nixio_sock__bind_connect(lua_State *L, int do_bind) {
if (do_bind) {
status = bind(sock->fd, rp->ai_addr, rp->ai_addrlen);
} else {
status = connect(sock->fd, rp->ai_addr, rp->ai_addrlen);
do {
status = connect(sock->fd, rp->ai_addr, rp->ai_addrlen);
} while (status == -1 && errno == EINTR);
}
/* on success */
@ -188,7 +195,10 @@ static int nixio_sock__bind_connect(lua_State *L, int do_bind) {
if (do_bind) {
status = bind(sock->fd, (struct sockaddr*)&addr, sizeof(addr));
} else {
status = connect(sock->fd, (struct sockaddr*)&addr, sizeof(addr));
do {
status = connect(sock->fd, (struct sockaddr*)&addr,
sizeof(addr));
} while (status == -1 && errno == EINTR);
}
} else {
return luaL_error(L, "not supported");
@ -229,8 +239,11 @@ static int nixio_sock_accept(lua_State *L) {
char ipaddr[INET6_ADDRSTRLEN];
void *binaddr;
uint16_t port;
int newfd;
int newfd = accept(sock->fd, (struct sockaddr *)&addr, &addrlen);
do {
newfd = accept(sock->fd, (struct sockaddr *)&addr, &addrlen);
} while (newfd == -1 && errno == EINTR);
if (newfd < 0) {
return nixio__perror(L);
}

View file

@ -22,24 +22,30 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
static int nixio_file(lua_State *L) {
static int nixio_open(lua_State *L) {
const char *filename = luaL_checklstring(L, 1, NULL);
const char *mode = luaL_optlstring(L, 2, "r", NULL);
int flags = luaL_optint(L, 2, O_RDONLY);
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd;
FILE *file = fopen(filename, mode);
if (!file) {
do {
fd = open(filename, flags, mode);
} while (fd == -1 && errno == EINTR);
if (fd == -1) {
return nixio__perror(L);
}
FILE **udata = lua_newuserdata(L, sizeof(FILE*));
int *udata = lua_newuserdata(L, sizeof(int));
if (!udata) {
return luaL_error(L, "out of memory");
}
*udata = file;
*udata = fd;
luaL_getmetatable(L, NIXIO_FILE_META);
lua_setmetatable(L, -2);
@ -47,30 +53,81 @@ static int nixio_file(lua_State *L) {
return 1;
}
static int nixio_open_flags(lua_State *L) {
int mode = 0;
const int j = lua_gettop(L);
for (int i=1; i<=j; i++) {
const char *flag = luaL_checkstring(L, i);
if (!strcmp(flag, "append")) {
mode |= O_APPEND;
} else if (!strcmp(flag, "creat")) {
mode |= O_CREAT;
} else if (!strcmp(flag, "excl")) {
mode |= O_EXCL;
} else if (!strcmp(flag, "nonblock") || !strcmp(flag, "ndelay")) {
mode |= O_NONBLOCK;
} else if (!strcmp(flag, "sync")) {
mode |= O_SYNC;
} else if (!strcmp(flag, "trunc")) {
mode |= O_TRUNC;
} else if (!strcmp(flag, "rdonly")) {
mode |= O_RDONLY;
} else if (!strcmp(flag, "wronly")) {
mode |= O_WRONLY;
} else if (!strcmp(flag, "rdwr")) {
mode |= O_RDWR;
} else {
return luaL_argerror(L, i, "supported values: append, creat, "
"excl, nonblock, ndelay, sync, trunc");
}
}
lua_pushinteger(L, mode);
return 1;
}
static int nixio_dup(lua_State *L) {
int oldfd = nixio__checkfd(L, 1);
int newfd = (lua_gettop(L) > 1) ? nixio__checkfd(L, 2) : -1;
int stat = (newfd == -1) ? dup(oldfd) : dup2(oldfd, newfd);
if (stat == -1) {
return nixio__perror(L);
} else {
int *udata = lua_newuserdata(L, sizeof(int));
if (!udata) {
return luaL_error(L, "out of memory");
}
*udata = stat;
luaL_getmetatable(L, NIXIO_FILE_META);
lua_setmetatable(L, -2);
return 1;
}
}
static int nixio_pipe(lua_State *L) {
int pipefd[2];
FILE **udata;
int pipefd[2], *udata;
if (pipe(pipefd)) {
return nixio__perror(L);
}
luaL_getmetatable(L, NIXIO_FILE_META);
udata = lua_newuserdata(L, sizeof(FILE*));
udata = lua_newuserdata(L, sizeof(int));
if (!udata) {
return luaL_error(L, "out of memory");
}
if (!(*udata = fdopen(pipefd[0], "r"))) {
return nixio__perror(L);
}
*udata = pipefd[0];
lua_pushvalue(L, -2);
lua_setmetatable(L, -2);
udata = lua_newuserdata(L, sizeof(FILE**));
if (!(*udata = fdopen(pipefd[1], "w"))) {
return nixio__perror(L);
udata = lua_newuserdata(L, sizeof(int));
if (!udata) {
return luaL_error(L, "out of memory");
}
*udata = pipefd[1];
lua_pushvalue(L, -3);
lua_setmetatable(L, -2);
@ -117,7 +174,7 @@ static int nixio_file_read(lua_State *L) {
static int nixio_file_seek(lua_State *L) {
FILE *f = nixio__checkfile(L);
int fd = nixio__checkfd(L, 1);
off_t len = (off_t)luaL_checknumber(L, 2);
int whence;
const char *whstr = luaL_optlstring(L, 3, "set", NULL);
@ -130,61 +187,78 @@ static int nixio_file_seek(lua_State *L) {
} else {
return luaL_argerror(L, 3, "supported values: set, cur, end");
}
return nixio__pstatus(L, !fseeko(f, len, whence));
}
static int nixio_file_tell(lua_State *L) {
FILE *f = nixio__checkfile(L);
off_t pos = ftello(f);
if (pos < 0) {
len = lseek(fd, len, whence);
if (len == -1) {
return nixio__perror(L);
} else {
lua_pushnumber(L, (lua_Number)pos);
lua_pushnumber(L, len);
return 1;
}
}
static int nixio_file_flush(lua_State *L) {
FILE *f = nixio__checkfile(L);
return nixio__pstatus(L, !fflush(f));
static int nixio_file_tell(lua_State *L) {
int fd = nixio__checkfd(L, 1);
off_t pos = lseek(fd, 0, SEEK_CUR);
if (pos < 0) {
return nixio__perror(L);
} else {
lua_pushnumber(L, pos);
return 1;
}
}
static int nixio_file_sync(lua_State *L) {
int fd = nixio__checkfd(L, 1);
int meta = lua_toboolean(L, 2);
return nixio__pstatus(L, (meta) ? !fsync(fd) : !fdatasync(fd));
}
static int nixio_file_lock(lua_State *L) {
int fd = fileno(nixio__checkfile(L));
int fd = nixio__checkfd(L, 1);
const char *flag = luaL_checkstring(L, 2);
off_t len = (off_t)luaL_optnumber(L, 3, 0);
int stat;
const int j = lua_gettop(L);
int flags = 0;
for (int i=2; i<=j; i++) {
const char *flag = luaL_checkstring(L, i);
if (!strcmp(flag, "sh")) {
flags |= LOCK_SH;
} else if (!strcmp(flag, "ex")) {
flags |= LOCK_EX;
} else if (!strcmp(flag, "un")) {
flags |= LOCK_UN;
} else if (!strcmp(flag, "nb")) {
flags |= LOCK_NB;
} else {
return luaL_argerror(L, i, "supported values: sh, ex, un, nb");
}
int cmd = 0;
if (!strcmp(flag, "lock")) {
cmd = F_LOCK;
} else if (!strcmp(flag, "tlock")) {
cmd = F_TLOCK;
} else if (!strcmp(flag, "ulock")) {
cmd = F_ULOCK;
} else if (!strcmp(flag, "test")) {
cmd = F_TEST;
} else {
return luaL_argerror(L, 2,
"supported values: lock, tlock, ulock, test");
}
return nixio__pstatus(L, !flock(fd, flags));
do {
stat = lockf(fd, cmd, len);
} while (stat == -1 && errno == EINTR);
return nixio__pstatus(L, !stat);
}
static int nixio_file_close(lua_State *L) {
FILE **fpp = (FILE**)luaL_checkudata(L, 1, NIXIO_FILE_META);
luaL_argcheck(L, *fpp, 1, "invalid file object");
int res = fclose(*fpp);
*fpp = NULL;
int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
luaL_argcheck(L, *fdp != -1, 1, "invalid file object");
int res;
do {
res = close(*fdp);
} while (res == -1 && errno == EINTR);
*fdp = -1;
return nixio__pstatus(L, !res);
}
static int nixio_file__gc(lua_State *L) {
FILE **fpp = (FILE**)luaL_checkudata(L, 1, NIXIO_FILE_META);
if (*fpp) {
fclose(*fpp);
*fpp = NULL;
int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
int res;
if (*fdp != -1) {
do {
res = close(*fdp);
} while (res == -1 && errno == EINTR);
*fdp = -1;
}
return 0;
}
@ -203,7 +277,7 @@ static const luaL_reg M[] = {
{"read", nixio_file_read},
{"tell", nixio_file_tell},
{"seek", nixio_file_seek},
{"flush", nixio_file_flush},
{"sync", nixio_file_sync},
{"lock", nixio_file_lock},
{"close", nixio_file_close},
{"__gc", nixio_file__gc},
@ -213,7 +287,9 @@ static const luaL_reg M[] = {
/* module table */
static const luaL_reg R[] = {
{"open", nixio_file},
{"dup", nixio_dup},
{"open", nixio_open},
{"open_flags", nixio_open_flags},
{"pipe", nixio_pipe},
{NULL, NULL}
};

View file

@ -20,6 +20,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#define VERSION 0.1
@ -53,12 +54,6 @@ nixio_sock* nixio__checksock(lua_State *L) {
return sock;
}
FILE* nixio__checkfile(lua_State *L) {
FILE **fpp = (FILE**)luaL_checkudata(L, 1, NIXIO_FILE_META);
luaL_argcheck(L, *fpp, 1, "invalid file object");
return *fpp;
}
/* read fd from nixio_sock object */
int nixio__checksockfd(lua_State *L) {
return nixio__checksock(L)->fd;
@ -80,7 +75,9 @@ int nixio__tofd(lua_State *L, int ud) {
luaL_getmetatable(L, LUA_FILEHANDLE);
if (lua_rawequal(L, -3, -4)) {
fd = ((nixio_sock*)udata)->fd;
} else if (lua_rawequal(L, -2, -4) || lua_rawequal(L, -1, -4)) {
} else if (lua_rawequal(L, -2, -4)) {
fd = *((int*)udata);
} else if (lua_rawequal(L, -1, -4)) {
fd = (*((FILE **)udata)) ? fileno(*((FILE **)udata)) : -1;
}
lua_pop(L, 4);
@ -124,6 +121,7 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
nixio_open_poll(L);
nixio_open_io(L);
nixio_open_splice(L);
nixio_open_process(L);
nixio_open_tls_context(L);
nixio_open_tls_socket(L);
@ -132,7 +130,7 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
lua_setfield(L, -2, "version");
/* some constants */
lua_createtable(L, 0, 7);
lua_createtable(L, 0, 11);
NIXIO_PUSH_CONSTANT(EACCES);
NIXIO_PUSH_CONSTANT(ENOSYS);
@ -141,6 +139,10 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
NIXIO_PUSH_CONSTANT(EAGAIN);
NIXIO_PUSH_CONSTANT(ENOMEM);
NIXIO_PUSH_CONSTANT(ENOENT);
NIXIO_PUSH_CONSTANT(SIGALRM);
NIXIO_PUSH_CONSTANT(SIGINT);
NIXIO_PUSH_CONSTANT(SIGTERM);
NIXIO_PUSH_CONSTANT(SIGKILL);
lua_setfield(L, -2, "const");

View file

@ -30,7 +30,6 @@ nixio_sock* nixio__checksock(lua_State *L);
int nixio__checksockfd(lua_State *L);
int nixio__checkfd(lua_State *L, int ud);
int nixio__tofd(lua_State *L, int ud);
FILE* nixio__checkfile(lua_State *L);
/* Module functions */
void nixio_open_file(lua_State *L);
@ -41,6 +40,7 @@ void nixio_open_address(lua_State *L);
void nixio_open_poll(lua_State *L);
void nixio_open_io(lua_State *L);
void nixio_open_splice(lua_State *L);
void nixio_open_process(lua_State *L);
void nixio_open_tls_context(lua_State *L);
void nixio_open_tls_socket(lua_State *L);

View file

@ -36,6 +36,7 @@
* port is.
*/
#include "nixio.h"
#include "config.h"
#define WITH_AXTLS 1

95
libs/nixio/src/process.c Normal file
View file

@ -0,0 +1,95 @@
/*
* nixio - Linux I/O library for lua
*
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nixio.h"
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
static int nixio_fork(lua_State *L) {
pid_t pid = fork();
if (pid == -1) {
return nixio__perror(L);
} else {
lua_pushinteger(L, pid);
return 1;
}
}
static int nixio_wait(lua_State *L) {
pid_t pidin = luaL_optinteger(L, 1, -1), pidout;
int options = 0, status;
const int j = lua_gettop(L);
for (int i=2; i<=j; i++) {
const char *flag = luaL_checkstring(L, i);
if (!strcmp(flag, "nohang")) {
options |= WNOHANG;
} else if (!strcmp(flag, "untraced")) {
options |= WUNTRACED;
} else if (!strcmp(flag, "continued")) {
options |= WCONTINUED;
} else {
return luaL_argerror(L, i,
"supported values: nohang, untraced, continued");
}
}
do {
pidout = waitpid(pidin, &status, options);
} while (pidout == -1 && errno == EINTR);
if (pidout == -1) {
return nixio__perror(L);
} else {
lua_pushinteger(L, pidout);
}
if (WIFEXITED(status)) {
lua_pushliteral(L, "exited");
lua_pushinteger(L, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
lua_pushliteral(L, "signaled");
lua_pushinteger(L, WTERMSIG(status));
} else if (WIFSTOPPED(status)) {
lua_pushliteral(L, "stopped");
lua_pushinteger(L, WSTOPSIG(status));
} else {
return 1;
}
return 3;
}
static int nixio_kill(lua_State *L) {
return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
}
/* module table */
static const luaL_reg R[] = {
{"fork", nixio_fork},
{"wait", nixio_wait},
{"kill", nixio_kill},
{NULL, NULL}
};
void nixio_open_process(lua_State *L) {
luaL_register(L, NULL, R);
}

View file

@ -91,8 +91,14 @@ static int nixio_socket(lua_State *L) {
static int nixio_sock_close(lua_State *L) {
nixio_sock *sock = nixio__checksock(L);
int sockfd = sock->fd;
int res;
sock->fd = -1;
return nixio__pstatus(L, !close(sockfd));
do {
res = close(sockfd);
} while (res == -1 && errno == EINTR);
return nixio__pstatus(L, !res);
}
/**
@ -100,8 +106,11 @@ static int nixio_sock_close(lua_State *L) {
*/
static int nixio_sock__gc(lua_State *L) {
nixio_sock *sock = (nixio_sock*)luaL_checkudata(L, 1, NIXIO_META);
int res;
if (sock && sock->fd != -1) {
close(sock->fd);
do {
res = close(sock->fd);
} while (res == -1 && errno == EINTR);
}
return 0;
}

View file

@ -25,6 +25,7 @@
#include <fcntl.h>
#include "nixio.h"
/**
* setblocking()
*/
@ -142,9 +143,9 @@ static int nixio__getsetsockopt(lua_State *L, int set) {
return luaL_error(L, "not a TCP socket");
}
if (!strcmp(option, "cork")) {
return nixio__gso_int(L, sock->fd, SOL_TCP, TCP_CORK, set);
return nixio__gso_int(L, sock->fd, IPPROTO_TCP, TCP_CORK, set);
} else if (!strcmp(option, "nodelay")) {
return nixio__gso_int(L, sock->fd, SOL_TCP, TCP_NODELAY, set);
return nixio__gso_int(L, sock->fd, IPPROTO_TCP, TCP_NODELAY, set);
} else {
return luaL_argerror(L, 3, "supported values: cork, nodelay");
}

View file

@ -16,8 +16,6 @@
* limitations under the License.
*/
#define _GNU_SOURCE
#include "nixio.h"
#include <fcntl.h>
#include <string.h>
@ -25,6 +23,8 @@
#include <unistd.h>
#include <sys/sendfile.h>
#ifdef _GNU_SOURCE
/* guess what sucks... */
#ifdef __UCLIBC__
#include <unistd.h>
@ -46,6 +46,28 @@ ssize_t splice(int __fdin, __off64_t *__offin, int __fdout,
}
#endif /* __UCLIBC__ */
/**
* splice(fd_in, fd_out, length, flags)
*/
static int nixio_splice(lua_State *L) {
int fd_in = nixio__checkfd(L, 1);
int fd_out = nixio__checkfd(L, 2);
size_t len = luaL_checkinteger(L, 3);
int flags = luaL_optinteger(L, 4, 0);
long spliced;
do {
spliced = splice(fd_in, NULL, fd_out, NULL, len, flags);
} while (spliced == -1 && errno == EINTR);
if (spliced < 0) {
return nixio__perror(L);
}
lua_pushnumber(L, spliced);
return 1;
}
/**
* Translate splice flags to integer
*/
@ -70,33 +92,7 @@ static int nixio_splice_flags(lua_State *L) {
return 1;
}
/**
* splice(fd_in, fd_out, length, flags)
*/
static int nixio_splice(lua_State *L) {
int fd_in = nixio__checkfd(L, 1);
int fd_out = nixio__checkfd(L, 2);
size_t len = luaL_checkinteger(L, 3);
int flags = luaL_optinteger(L, 4, 0);
long spliced;
do {
spliced = splice(fd_in, NULL, fd_out, NULL, len, flags);
} while (spliced == -1 && errno == EINTR);
if (spliced < 0) {
return nixio__perror(L);
}
lua_pushnumber(L, spliced);
return 1;
}
static int nixio_splice_avail(lua_State *L) {
splice(-1, 0, -1, 0, 0, 0);
lua_pushboolean(L, errno != ENOSYS);
return 1;
}
#endif /* _GNU_SOURCE */
/**
* sendfile(outfd, infd, length)
@ -118,9 +114,10 @@ static int nixio_sendfile(lua_State *L) {
/* module table */
static const luaL_reg R[] = {
#ifdef _GNU_SOURCE
{"splice", nixio_splice},
{"splice_flags", nixio_splice_flags},
{"splice_avail", nixio_splice_avail},
#endif
{"sendfile", nixio_sendfile},
{NULL, NULL}
};