X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=libs%2Fnixio%2Fsrc%2Fsplice.c;h=38a45c22abc5cbbb6228ceae5e4684b4de0ef43d;hb=6ea063dc11d38fa1f2b7c57eb8193fd8034d736e;hp=538b99e695d56a44b930f07f5b99c7a213716052;hpb=06450d3fe3b5248276e3113a358954ee85af5779;p=project%2Fluci.git diff --git a/libs/nixio/src/splice.c b/libs/nixio/src/splice.c index 538b99e69..38a45c22a 100644 --- a/libs/nixio/src/splice.c +++ b/libs/nixio/src/splice.c @@ -16,17 +16,36 @@ * limitations under the License. */ +#ifdef __linux__ #define _GNU_SOURCE +#endif #include "nixio.h" #include +#include +#include +#include +#include + + +#ifndef __WINNT__ + +#ifndef BSD #include +#else +#include +#include +#include +#endif + +#ifdef _GNU_SOURCE +#ifdef SPLICE_F_MOVE /* guess what sucks... */ #ifdef __UCLIBC__ #include -#include #include + ssize_t splice(int __fdin, __off64_t *__offin, int __fdout, __off64_t *__offout, size_t __len, unsigned int __flags) { #ifdef __NR_splice @@ -42,35 +61,16 @@ ssize_t splice(int __fdin, __off64_t *__offin, int __fdout, return -1; #endif } -#endif /* __UCLIBC__ */ -/** - * 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); -} +#undef SPLICE_F_MOVE +#undef SPLICE_F_NONBLOCK +#undef SPLICE_F_MORE -/** - * Translate integer to poll flags and vice versa - */ -static int nixio_splice_flags(lua_State *L) { - int flags = 0; +#define SPLICE_F_MOVE 1 +#define SPLICE_F_NONBLOCK 2 +#define SPLICE_F_MORE 4 - 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; -} +#endif /* __UCLIBC__ */ /** * splice(fd_in, fd_out, length, flags) @@ -80,44 +80,105 @@ static int nixio_splice(lua_State *L) { int fd_out = nixio__checkfd(L, 2); size_t len = luaL_checkinteger(L, 3); int flags = luaL_optinteger(L, 4, 0); + long spliced; - - long spliced = splice(fd_in, NULL, fd_out, NULL, len, flags); + 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); + lua_pushinteger(L, spliced); + return 1; +} + +/** + * Translate splice flags to integer + */ +static int nixio_splice_flags(lua_State *L) { + const int j = lua_gettop(L); + int flags = 0; + for (int i=1; i<=j; i++) { + const char *flag = luaL_checkstring(L, i); + if (!strcmp(flag, "move")) { + flags |= SPLICE_F_MOVE; + } else if (!strcmp(flag, "nonblock")) { + flags |= SPLICE_F_NONBLOCK; + } else if (!strcmp(flag, "more")) { + flags |= SPLICE_F_MORE; + } else { + return luaL_argerror(L, i, "supported values: " + "move, nonblock, more"); + } + } + lua_pushinteger(L, flags); + return 1; } +#endif /* SPLICE_F_MOVE */ +#endif /* _GNU_SOURCE */ + /** * sendfile(outfd, infd, length) */ static int nixio_sendfile(lua_State *L) { - int sockfd = nixio__checksockfd(L); + int sock = nixio__checksockfd(L); int infd = nixio__checkfd(L, 2); size_t len = luaL_checkinteger(L, 3); + off_t spliced; - long spliced = sendfile(sockfd, infd, NULL, len); +#ifndef BSD + do { + spliced = sendfile(sock, infd, NULL, len); + } while (spliced == -1 && errno == EINTR); - if (spliced < 0) { + if (spliced == -1) { return nixio__perror(L); } +#else + int r; + const off_t offset = lseek(infd, 0, SEEK_CUR); - lua_pushnumber(L, spliced); + do { +#ifdef __DARWIN__ + r = sendfile(infd, sock, offset, (off_t *)&len, NULL, 0); +#else + r = sendfile(infd, sock, offset, len, NULL, &spliced, 0); +#endif + } while (r == -1 && errno == EINTR); + + if (r == -1) { + return nixio__perror(L); + } +#endif + + lua_pushinteger(L, spliced); return 1; } /* module table */ static const luaL_reg R[] = { +#ifdef _GNU_SOURCE +#ifdef SPLICE_F_MOVE {"splice", nixio_splice}, {"splice_flags", nixio_splice_flags}, +#endif +#endif {"sendfile", nixio_sendfile}, {NULL, NULL} }; + void nixio_open_splice(lua_State *L) { luaL_register(L, NULL, R); } + +#else /* __WINNT__ */ + +void nixio_open_splice(lua_State *L) { +} + +#endif /* !__WINNT__ */