From 2843236d3fcba8517269d4cace3c205975f3e210 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 19 Dec 2006 07:19:27 +0000 Subject: [PATCH] remove unsetenv() dir() elides "." and ".." entries ex_dir() internally uses DIR** instead of struct diriter refactor implementation of ex_pipe() pass fd instead of FILE* to spawn_param_redirect() --- posix/Makefile | 9 +-- posix/ex.c | 170 ++++++++++++++++++++++--------------------------- posix/spawn.c | 8 +-- posix/spawn.h | 2 +- 4 files changed, 85 insertions(+), 104 deletions(-) diff --git a/posix/Makefile b/posix/Makefile index 32b99c1..f9aa506 100755 --- a/posix/Makefile +++ b/posix/Makefile @@ -3,10 +3,12 @@ DEFINES = $(DEBUG) -D_XOPEN_SOURCE=500 -DMISSING_POSIX_SPAWN DEBUG= -D'debug(...)=fprintf(stderr,__VA_ARGS__)' # -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L \ -U__STRICT_ANSI__ -D_GNU_SOURCE -INCLUDES = -I$(LUA)/include +INCLUDES = -I$(LUA)/include -I$(LUA)/src WARNINGS = -W -Wall #LUA = /home/mark/src/lang/lua/lua-5.1-rc2 -LUA = /home/mark/src/lang/lua/lua51 +#LUA = /home/mark/src/lang/lua/lua51 +LUA = /home/medgar/src/lang/lua/lua-5.1.1 +LIBS = -L$(LUA)/src -llua5.1 ex-OBJS = ex.o spawn.o @@ -14,9 +16,8 @@ default: ex.dll ex.so: $(ex-OBJS); $(CC) -shared -o $@ $(ex-OBJS) -#LIBS = -L$(LUA)/lib -llua51 spawn.a EXTRA = posix_spawn.o -ex.dll: $(ex-OBJS) $(EXTRA) $(LIBS); $(CC) -shared -L$(LUA)/bin/Cygwin -o $@ $(ex-OBJS) $(EXTRA) -llua51 +ex.dll: $(ex-OBJS) $(EXTRA); $(CC) -shared -o $@ $(ex-OBJS) $(EXTRA) $(LIBS) ex.o: ex.c spawn.h spawn.o: spawn.c spawn.h diff --git a/posix/ex.c b/posix/ex.c index 7ec5a87..dc9a6d9 100755 --- a/posix/ex.c +++ b/posix/ex.c @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" #include #include @@ -38,23 +38,14 @@ static int ex_getenv(lua_State *L) return 1; } -/* name value -- true/nil error */ +/* name value -- true/nil error * + * name -- true/nil error */ static int ex_setenv(lua_State *L) { const char *nam = luaL_checkstring(L, 1); - const char *val = luaL_checkstring(L, 2); - if (-1 == setenv(nam, val, 1)) - return push_error(L); - lua_pushboolean(L, 1); - return 1; -} - -/* name -- true/nil error */ -static int ex_unsetenv(lua_State *L) -{ - const char *nam = luaL_checkstring(L, 1); - if (-1 == unsetenv(nam)) - return push_error(L); + const char *val = lua_tostring(L, 2); + int err = val ? setenv(nam, val, 1) : unsetenv(nam); + if (err == -1) return push_error(L); lua_pushboolean(L, 1); return 1; } @@ -115,7 +106,7 @@ static int ex_currentdir(lua_State *L) } -FILE *check_file(lua_State *L, int idx, const char *argname) +static FILE *check_file(lua_State *L, int idx, const char *argname) { FILE **pf; if (idx > 0) pf = luaL_checkudata(L, idx, LUA_FILEHANDLE); @@ -170,9 +161,6 @@ static int ex_dirent(lua_State *L) } #define DIR_HANDLE "DIR*" -struct diriter { - DIR *dir; -}; /* ...diriter... -- ...diriter... pathname */ static int diriter_getpathname(lua_State *L, int index) @@ -200,44 +188,47 @@ static int diriter_setpathname(lua_State *L, int index) /* diriter -- diriter */ static int diriter_close(lua_State *L) { - struct diriter *pi = lua_touserdata(L, 1); - if (pi->dir) { - closedir(pi->dir); - pi->dir = 0; - lua_pushnil(L); - diriter_setpathname(L, 1); + DIR **pd = lua_touserdata(L, 1); + if (*pd) { + closedir(*pd); + *pd = 0; } + lua_pushnil(L); + diriter_setpathname(L, 1); return 0; } +static int isdotfile(const char *name) +{ + return name[0] && (name[1] == 0 + || (name[1] == '.' && name[2] == 0)); +} + /* pathname -- iter state nil */ /* diriter ... -- entry */ static int ex_dir(lua_State *L) { const char *pathname; - struct diriter *pi; + DIR **pd; struct dirent *d; switch (lua_type(L, 1)) { default: return luaL_typerror(L, 1, "pathname"); case LUA_TSTRING: pathname = lua_tostring(L, 1); lua_pushcfunction(L, ex_dir); /* pathname ... iter */ - pi = lua_newuserdata(L, sizeof *pi);/* pathname ... iter state */ - pi->dir = opendir(pathname); - if (!pi->dir) return push_error(L); + pd = lua_newuserdata(L, sizeof *pd);/* pathname ... iter state */ + *pd = opendir(pathname); + if (!*pd) return push_error(L); luaL_getmetatable(L, DIR_HANDLE); /* pathname ... iter state M */ lua_setmetatable(L, -2); /* pathname ... iter state */ lua_pushvalue(L, 1); /* pathname ... iter state pathname */ diriter_setpathname(L, -2); /* pathname ... iter state */ return 2; case LUA_TUSERDATA: - pi = luaL_checkudata(L, 1, DIR_HANDLE); - d = readdir(pi->dir); - if (!d) { - closedir(pi->dir); - pi->dir = 0; - return push_error(L); - } + pd = luaL_checkudata(L, 1, DIR_HANDLE); + do d = readdir(*pd); + while (d && isdotfile(d->d_name)); + if (!d) return push_error(L); lua_newtable(L); /* diriter ... entry */ diriter_getpathname(L, 1); /* diriter ... entry dirpath */ lua_pushstring(L, d->d_name); /* diriter ... entry dirpath name */ @@ -298,31 +289,26 @@ static int closeonexec(int d) return fl; } -static int make_pipe(FILE **i, FILE **o) +static int new_file(lua_State *L, int fd, const char *mode) { - int fd[2]; - if (-1 == pipe(fd)) - return 0; - closeonexec(fd[0]); - closeonexec(fd[1]); - *i = fdopen(fd[0], "r"); - *o = fdopen(fd[1], "w"); + FILE **pf = lua_newuserdata(L, sizeof *pf); + *pf = 0; + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + *pf = fdopen(fd, mode); return 1; } /* -- in out/nil error */ static int ex_pipe(lua_State *L) { - FILE *i, *o, **pf; - if (!make_pipe(&i, &o)) - return push_error(L); - luaL_getmetatable(L, LUA_FILEHANDLE); /* M */ - *(pf = lua_newuserdata(L, sizeof *pf)) = i; /* M i */ - lua_pushvalue(L, -2); /* M i M */ - lua_setmetatable(L, -2); /* M i */ - *(pf = lua_newuserdata(L, sizeof *pf)) = o; /* M i o */ - lua_pushvalue(L, -3); /* M i o M */ - lua_setmetatable(L, -2); /* M i o */ + int fd[2]; + if (-1 == pipe(fd)) + return 0; + closeonexec(fd[0]); + closeonexec(fd[1]); + new_file(L, fd[0], "r"); + new_file(L, fd[1], "w"); return 2; } @@ -331,7 +317,7 @@ static void get_redirect(lua_State *L, int idx, const char *stdname, struct spaw { lua_getfield(L, idx, stdname); if (!lua_isnil(L, -1)) - spawn_param_redirect(p, stdname, check_file(L, -1, stdname)); + spawn_param_redirect(p, stdname, fileno(check_file(L, -1, stdname))); lua_pop(L, 1); } @@ -414,44 +400,6 @@ static int ex_spawn(lua_State *L) } -static const luaL_reg ex_iolib[] = { - {"pipe", ex_pipe}, - {0,0} -}; -static const luaL_reg ex_iofile_methods[] = { - {"lock", ex_lock}, - {"unlock", ex_unlock}, - {0,0} -}; -static const luaL_reg ex_oslib[] = { - {"getenv", ex_getenv}, - {"setenv", ex_setenv}, - {"unsetenv", ex_unsetenv}, - {"environ", ex_environ}, - - {"sleep", ex_sleep}, - - {"chdir", ex_chdir}, - {"mkdir", ex_mkdir}, - {"currentdir", ex_currentdir}, - - {"dir", ex_dir}, - {"dirent", ex_dirent}, - - {"spawn", ex_spawn}, - {0,0} -}; -static const luaL_reg ex_diriter_methods[] = { - {"__gc", diriter_close}, -/* {"__tostring", diriter_tostring}, */ - {0,0} -}; -static const luaL_reg ex_process_methods[] = { - {"__tostring", process_tostring}, - {"wait", process_wait}, - {0,0} -}; - /* copy the fields given in 'l' from one table to another; insert missing fields */ static void copy_fields(lua_State *L, const luaL_reg *l, int from, int to) { @@ -469,6 +417,38 @@ static void copy_fields(lua_State *L, const luaL_reg *l, int from, int to) int luaopen_ex(lua_State *L) { + const luaL_reg ex_iolib[] = { + {"pipe", ex_pipe}, + {0,0} }; + const luaL_reg ex_iofile_methods[] = { + {"lock", ex_lock}, + {"unlock", ex_unlock}, + {0,0} }; + const luaL_reg ex_oslib[] = { + {"getenv", ex_getenv}, + {"setenv", ex_setenv}, + {"environ", ex_environ}, + + {"sleep", ex_sleep}, + + {"chdir", ex_chdir}, + {"mkdir", ex_mkdir}, + {"currentdir", ex_currentdir}, + + {"dir", ex_dir}, + {"dirent", ex_dirent}, + + {"spawn", ex_spawn}, + {0,0} }; + const luaL_reg ex_diriter_methods[] = { + {"__gc", diriter_close}, + /* {"__tostring", diriter_tostring}, */ + {0,0} }; + const luaL_reg ex_process_methods[] = { + {"__tostring", process_tostring}, + {"wait", process_wait}, + {0,0} }; + /* Make all functions available via ex. namespace */ luaL_register(L, "ex", ex_iolib); /* . ex */ luaL_register(L, 0, ex_oslib); diff --git a/posix/spawn.c b/posix/spawn.c index e1cc7f7..64b885f 100755 --- a/posix/spawn.c +++ b/posix/spawn.c @@ -1,5 +1,5 @@ -#include -#include +#include "lua.h" +#include "lauxlib.h" #include #include @@ -93,7 +93,7 @@ void spawn_param_env(struct spawn_params *p) make_vector(p->L); /* ... arr */ } -void spawn_param_redirect(struct spawn_params *p, const char *stdname, FILE *f) +void spawn_param_redirect(struct spawn_params *p, const char *stdname, int fd) { int d; switch (stdname[3]) { @@ -101,7 +101,7 @@ void spawn_param_redirect(struct spawn_params *p, const char *stdname, FILE *f) case 'o': d = STDOUT_FILENO; break; case 'e': d = STDERR_FILENO; break; } - posix_spawn_file_actions_adddup2(&p->redirect, fileno(f), d); + posix_spawn_file_actions_adddup2(&p->redirect, fd, d); } struct process { diff --git a/posix/spawn.h b/posix/spawn.h index fc80446..46d9753 100755 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -12,7 +12,7 @@ struct spawn_params *spawn_param_init(lua_State *L); void spawn_param_filename(struct spawn_params *p, const char *filename); void spawn_param_args(struct spawn_params *p); void spawn_param_env(struct spawn_params *p); -void spawn_param_redirect(struct spawn_params *p, const char *stdname, FILE *f); +void spawn_param_redirect(struct spawn_params *p, const char *stdname, int fd); int spawn_param_execute(struct spawn_params *p); int process_wait(lua_State *L); int process_tostring(lua_State *L);