summaryrefslogtreecommitdiffhomepage
path: root/libs/nixio/src/file.c
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2009-03-03 22:44:26 +0000
committerSteven Barth <steven@midlink.org>2009-03-03 22:44:26 +0000
commite38c438771d10231e7ce1b74c027b4914acd6c78 (patch)
tree91ca365e48919d9af60e11ec7564f47538208289 /libs/nixio/src/file.c
parenta3079828b4e0c0fabd96dfca87b99a5b5d9529e5 (diff)
nixio:
Use POSIX file functions introduce dup() introduce fork() wait() kill() more signal interrupt wrappers more POSIX / UNIX standard compliance
Diffstat (limited to 'libs/nixio/src/file.c')
-rw-r--r--libs/nixio/src/file.c180
1 files changed, 128 insertions, 52 deletions
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 <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));
+ 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}
};