nixio next
splice() still does not work correctly
This commit is contained in:
parent
4327f9250e
commit
5ff898e624
12 changed files with 405 additions and 36 deletions
|
@ -5,7 +5,7 @@ include ../../build/gccconfig.mk
|
|||
%.o: %.c
|
||||
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
|
||||
|
||||
compile: src/nixio.o src/socket.o src/sockopt.o src/bind.o src/address.o src/poll.o src/io.o
|
||||
compile: 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
|
||||
$(LINK) $(SHLIB_FLAGS) -o src/nixio.so src/*.o
|
||||
mkdir -p dist$(LUA_LIBRARYDIR)
|
||||
cp src/nixio.so dist$(LUA_LIBRARYDIR)/nixio.so
|
||||
|
|
70
libs/nixio/lua/nixio/util.lua
Normal file
70
libs/nixio/lua/nixio/util.lua
Normal file
|
@ -0,0 +1,70 @@
|
|||
--[[
|
||||
nixio - Linux I/O library for lua
|
||||
|
||||
Copyright 2008 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
|
||||
|
||||
$Id$
|
||||
]]--
|
||||
|
||||
local nixio = require "nixio"
|
||||
local setmetatable, assert = setmetatable, assert
|
||||
|
||||
module "nixio.util"
|
||||
|
||||
local BUFFERSIZE = 8096
|
||||
local socket = nixio.socket_meta
|
||||
|
||||
function socket.sendall(self, data)
|
||||
local sent, code, msg = self:send(data)
|
||||
|
||||
if not sent then
|
||||
return sent, code, msg, data
|
||||
end
|
||||
|
||||
while sent < #data do
|
||||
data = data:sub(sent + 1)
|
||||
sent, code, msg = self:send(data)
|
||||
|
||||
if not sent then
|
||||
return sent, code, msg, data
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function socket.linesource(self, limit)
|
||||
limit = limit or BUFFERSIZE
|
||||
local buffer = ""
|
||||
return function(flush)
|
||||
local line, endp, _
|
||||
|
||||
if flush then
|
||||
line = buffer
|
||||
buffer = ""
|
||||
return line
|
||||
end
|
||||
|
||||
while not line do
|
||||
_, endp, line = buffer:find("^(.-)\r?\n")
|
||||
if line then
|
||||
buffer = buffer:sub(endp+1)
|
||||
return line
|
||||
elseif #buffer < limit then
|
||||
local newblock, code = self:recv(limit - #buffer)
|
||||
if not newblock then
|
||||
return nil, code
|
||||
end
|
||||
buffer = buffer .. newblock
|
||||
else
|
||||
return nil, 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,15 +16,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include "nixio.h"
|
||||
|
||||
|
||||
/**
|
||||
* getaddrinfo(host, family, port)
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
|
202
libs/nixio/src/file.c
Normal file
202
libs/nixio/src/file.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
static int nixio_file(lua_State *L) {
|
||||
const char *filename = luaL_checklstring(L, 1, NULL);
|
||||
const char *mode = luaL_optlstring(L, 2, "r", NULL);
|
||||
|
||||
FILE *file = fopen(filename, mode);
|
||||
if (!file) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
FILE **udata = lua_newuserdata(L, sizeof(FILE**));
|
||||
*udata = file;
|
||||
|
||||
luaL_getmetatable(L, NIXIO_FILE_META);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_pipe(lua_State *L) {
|
||||
int pipefd[2];
|
||||
FILE **udata;
|
||||
if (pipe(pipefd)) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
luaL_getmetatable(L, NIXIO_FILE_META);
|
||||
udata = lua_newuserdata(L, sizeof(FILE**));
|
||||
if (!(*udata = fdopen(pipefd[0], "r"))) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
lua_pushvalue(L, -2);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
|
||||
udata = lua_newuserdata(L, sizeof(FILE**));
|
||||
if (!(*udata = fdopen(pipefd[1], "w"))) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
lua_pushvalue(L, -3);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int nixio_file_write(lua_State *L) {
|
||||
FILE *fp = nixio__checkfile(L);
|
||||
size_t len, written;
|
||||
const char *data = luaL_checklstring(L, 2, &len);
|
||||
written = fwrite(data, sizeof(char), len, fp);
|
||||
if (written < 0) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return written;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Some code borrowed from Lua 5.1.4 liolib.c */
|
||||
static int nixio_file_read(lua_State *L) {
|
||||
FILE *f = nixio__checkfile(L);
|
||||
size_t n = (size_t)luaL_checkinteger(L, 2);
|
||||
luaL_argcheck(L, 2, n >= 0, "invalid length");
|
||||
|
||||
if (n == 0) {
|
||||
if (feof(f)) {
|
||||
return 0;
|
||||
} else {
|
||||
lua_pushliteral(L, "");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t rlen; /* how much to read */
|
||||
size_t nr; /* number of chars actually read */
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
|
||||
|
||||
do {
|
||||
char *p = luaL_prepbuffer(&b);
|
||||
if (rlen > n) rlen = n; /* cannot read more than asked */
|
||||
nr = fread(p, sizeof(char), rlen, f);
|
||||
luaL_addsize(&b, nr);
|
||||
n -= nr; /* still have to read `n' chars */
|
||||
} while (n > 0 && nr == rlen); /* until end of count or eof */
|
||||
luaL_pushresult(&b); /* close buffer */
|
||||
return (n == 0 || lua_objlen(L, -1) > 0);
|
||||
}
|
||||
|
||||
static int nixio_file_seek(lua_State *L) {
|
||||
FILE *f = nixio__checkfile(L);
|
||||
off_t len = (off_t)luaL_checknumber(L, 2);
|
||||
int whence;
|
||||
const char *whstr = luaL_optlstring(L, 3, "set", NULL);
|
||||
if (!strcmp(whstr, "set")) {
|
||||
whence = SEEK_SET;
|
||||
} else if (!strcmp(whstr, "cur")) {
|
||||
whence = SEEK_CUR;
|
||||
} else if (!strcmp(whstr, "end")) {
|
||||
whence = SEEK_END;
|
||||
} 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) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushnumber(L, (lua_Number)pos);
|
||||
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_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;
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* string representation
|
||||
*/
|
||||
static int nixio_file__tostring(lua_State *L) {
|
||||
lua_pushfstring(L, "nixio file %d", nixio__tofd(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* method table */
|
||||
static const luaL_reg M[] = {
|
||||
{"write", nixio_file_write},
|
||||
{"read", nixio_file_read},
|
||||
{"tell", nixio_file_tell},
|
||||
{"seek", nixio_file_seek},
|
||||
{"flush", nixio_file_flush},
|
||||
{"close", nixio_file_close},
|
||||
{"__gc", nixio_file__gc},
|
||||
{"__tostring", nixio_file__tostring},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"open", nixio_file},
|
||||
{"pipe", nixio_pipe},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void nixio_open_file(lua_State *L) {
|
||||
luaL_register(L, NULL, R);
|
||||
|
||||
luaL_newmetatable(L, NIXIO_FILE_META);
|
||||
luaL_register(L, NULL, M);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
}
|
|
@ -16,9 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -16,13 +16,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "nixio.h"
|
||||
|
||||
#define VERSION 0.1
|
||||
|
||||
|
@ -52,6 +49,12 @@ 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;
|
||||
|
@ -67,15 +70,16 @@ int nixio__checkfd(lua_State *L, int ud) {
|
|||
int nixio__tofd(lua_State *L, int ud) {
|
||||
void *udata = lua_touserdata(L, ud);
|
||||
int fd = -1;
|
||||
if (udata && lua_getmetatable(L, ud)) {
|
||||
if (lua_getmetatable(L, ud)) {
|
||||
luaL_getmetatable(L, NIXIO_META);
|
||||
luaL_getmetatable(L, NIXIO_FILE_META);
|
||||
luaL_getmetatable(L, LUA_FILEHANDLE);
|
||||
if (lua_rawequal(L, -2, -3)) {
|
||||
if (lua_rawequal(L, -3, -4)) {
|
||||
fd = ((nixio_sock*)udata)->fd;
|
||||
} else if (lua_rawequal(L, -1, -3)) {
|
||||
fd = fileno(*((FILE **)udata));
|
||||
} else if (lua_rawequal(L, -2, -4) || lua_rawequal(L, -1, -4)) {
|
||||
fd = (*((FILE **)udata)) ? fileno(*((FILE **)udata)) : -1;
|
||||
}
|
||||
lua_pop(L, 3);
|
||||
lua_pop(L, 4);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
@ -90,24 +94,26 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
|
|||
/* create metatable */
|
||||
luaL_newmetatable(L, NIXIO_META);
|
||||
|
||||
/* method table */
|
||||
lua_newtable(L);
|
||||
/* metatable.__index = metatable */
|
||||
lua_pushvalue(L, -1);
|
||||
|
||||
/* metatable.__index = M */
|
||||
lua_setfield(L, -3, "__index");
|
||||
lua_remove(L, -2);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
/* register module */
|
||||
luaL_register(L, "nixio", R);
|
||||
|
||||
/* register metatable as socket_meta */
|
||||
lua_pushvalue(L, -2);
|
||||
lua_setfield(L, -2, "socket_meta");
|
||||
|
||||
/* register methods */
|
||||
nixio_open_file(L);
|
||||
nixio_open_socket(L);
|
||||
nixio_open_sockopt(L);
|
||||
nixio_open_bind(L);
|
||||
nixio_open_address(L);
|
||||
nixio_open_poll(L);
|
||||
nixio_open_io(L);
|
||||
nixio_open_splice(L);
|
||||
|
||||
/* module version */
|
||||
lua_pushnumber(L, VERSION);
|
||||
|
|
|
@ -2,7 +2,16 @@
|
|||
#define NIXIO_H_
|
||||
|
||||
#define NIXIO_META "nixio.socket"
|
||||
#define NIXIO_FILE_META "nixio.file"
|
||||
#define NIXIO_BUFFERSIZE 8096
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* uClibc: broken as always */
|
||||
#define _LARGEFILE_SOURCE
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
struct nixio_socket {
|
||||
int fd;
|
||||
|
@ -19,14 +28,17 @@ 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);
|
||||
void nixio_open_socket(lua_State *L);
|
||||
void nixio_open_sockopt(lua_State *L);
|
||||
void nixio_open_bind(lua_State *L);
|
||||
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);
|
||||
|
||||
/* Method functions */
|
||||
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <poll.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "nixio.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
@ -181,7 +179,7 @@ void nixio_open_sockopt(lua_State *L) {
|
|||
luaL_register(L, NULL, M);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_getmetatable(L, LUA_FILEHANDLE);
|
||||
luaL_getmetatable(L, NIXIO_FILE_META);
|
||||
lua_pushcfunction(L, nixio_sock_setblocking);
|
||||
lua_setfield(L, -2, "setblocking");
|
||||
lua_pop(L, 1);
|
||||
|
|
91
libs/nixio/src/splice.c
Normal file
91
libs/nixio/src/splice.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "nixio.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
/* guess what sucks... */
|
||||
#ifdef __UCLIBC__
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
ssize_t splice(int __fdin, __off64_t *__offin, int __fdout,
|
||||
__off64_t *__offout, size_t __len, unsigned int __flags) {
|
||||
return syscall(__NR_splice, __fdin, __offin, __fdout, __offout, __len, __flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a flag is set in the table and translates it into a bitmap
|
||||
*/
|
||||
static void nixio_splice_flags__w(lua_State *L, int *m, int f, const char *t) {
|
||||
lua_pushstring(L, t);
|
||||
lua_rawget(L, -2);
|
||||
if (lua_toboolean(L, -1)) {
|
||||
*m |= f;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate integer to poll flags and vice versa
|
||||
*/
|
||||
static int nixio_splice_flags(lua_State *L) {
|
||||
int flags = 0;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1);
|
||||
nixio_splice_flags__w(L, &flags, SPLICE_F_MOVE, "move");
|
||||
nixio_splice_flags__w(L, &flags, SPLICE_F_NONBLOCK, "nonblock");
|
||||
nixio_splice_flags__w(L, &flags, SPLICE_F_MORE, "more");
|
||||
lua_pushinteger(L, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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 = splice(fd_in, NULL, fd_out, NULL, len, flags);
|
||||
|
||||
if (spliced < 0) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_pushnumber(L, spliced);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"splice", nixio_splice},
|
||||
{"splice_flags", nixio_splice_flags},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void nixio_open_splice(lua_State *L) {
|
||||
luaL_register(L, NULL, R);
|
||||
}
|
Loading…
Reference in a new issue