From e38c438771d10231e7ce1b74c027b4914acd6c78 Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Tue, 3 Mar 2009 22:44:26 +0000 Subject: nixio: Use POSIX file functions introduce dup() introduce fork() wait() kill() more signal interrupt wrappers more POSIX / UNIX standard compliance --- libs/nixio/src/file.c | 180 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 52 deletions(-) (limited to 'libs/nixio/src/file.c') diff --git a/libs/nixio/src/file.c b/libs/nixio/src/file.c index de43ee487..5229b4988 100644 --- a/libs/nixio/src/file.c +++ b/libs/nixio/src/file.c @@ -22,24 +22,30 @@ #include #include #include -#include +#include +#include +#include -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)); + len = lseek(fd, len, whence); + if (len == -1) { + return nixio__perror(L); + } else { + lua_pushnumber(L, len); + return 1; + } } static int nixio_file_tell(lua_State *L) { - FILE *f = nixio__checkfile(L); - off_t pos = ftello(f); + 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, (lua_Number)pos); + lua_pushnumber(L, 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_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)); - - 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 fd = nixio__checkfd(L, 1); + const char *flag = luaL_checkstring(L, 2); + off_t len = (off_t)luaL_optnumber(L, 3, 0); + int stat; + + 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} }; -- cgit v1.2.3