From 785c362a9f81f0cb416d567ecb9fa428913a692d Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 10 Feb 2006 00:56:44 +0000 Subject: [PATCH] A few changes. --- posix/Makefile | 14 +++++---- posix/ex.c | 61 +++++++++++++++++++++++--------------- posix/posix_spawn.c | 9 ++++-- posix/posix_spawn.h | 4 +++ posix/spawn.c | 11 ++++--- posix/spawn.h | 1 + tests/rt3.lua | 2 +- tests/rt4.lua | 1 - tests/rt5.lua | 1 - w32api/ex.c | 71 +++++++++++++++++++++++++++------------------ 10 files changed, 107 insertions(+), 68 deletions(-) diff --git a/posix/Makefile b/posix/Makefile index cf829cc..32b99c1 100755 --- a/posix/Makefile +++ b/posix/Makefile @@ -1,8 +1,8 @@ -CFLAGS = -std=c99 $(WARNINGS) $(DEFINES) $(INCLUDES) -DEFINES = -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L \ - -U__STRICT_ANSI__ \ - -D_GNU_SOURCE -DMISSING_POSIX_SPAWN \ - -D'debug(...)=fprintf(stderr,__VA_ARGS__)' +CFLAGS = $(WARNINGS) $(DEFINES) $(INCLUDES) +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 WARNINGS = -W -Wall #LUA = /home/mark/src/lang/lua/lua-5.1-rc2 @@ -16,9 +16,11 @@ ex.so: $(ex-OBJS); $(CC) -shared -o $@ $(ex-OBJS) #LIBS = -L$(LUA)/lib -llua51 spawn.a EXTRA = posix_spawn.o -ex.dll: $(ex-OBJS) $(LIBS); $(CC) -shared -L$(LUA)/bin/Cygwin -o $@ $(ex-OBJS) $(EXTRA) -llua51 +ex.dll: $(ex-OBJS) $(EXTRA) $(LIBS); $(CC) -shared -L$(LUA)/bin/Cygwin -o $@ $(ex-OBJS) $(EXTRA) -llua51 ex.o: ex.c spawn.h spawn.o: spawn.c spawn.h posix_spawn.o: posix_spawn.c posix_spawn.h + +clean:; rm -f *.o ex.dll ex.so ex.a diff --git a/posix/ex.c b/posix/ex.c index 9ebc181..43a689f 100755 --- a/posix/ex.c +++ b/posix/ex.c @@ -1,17 +1,16 @@ #include #include -#include #include #include -#include +#include #include #include #include #include -#include #include +#include #include #include "spawn.h" @@ -121,11 +120,11 @@ FILE *check_file(lua_State *L, int idx, const char *argname) FILE **pf; if (idx > 0) pf = luaL_checkudata(L, idx, LUA_FILEHANDLE); else { - idx = absindex(idx); + idx = absindex(L, idx); pf = lua_touserdata(L, idx); luaL_getmetatable(L, LUA_FILEHANDLE); if (!pf || !lua_getmetatable(L, idx) || !lua_rawequal(L, -1, -2)) - luaL_error(L, "%s option: expected %s, got %s", + luaL_error(L, "bad %s option (%s expected, got %s)", argname, LUA_FILEHANDLE, luaL_typename(L, idx)); lua_pop(L, 2); } @@ -137,8 +136,10 @@ FILE *check_file(lua_State *L, int idx, const char *argname) static int ex_dirent(lua_State *L) { struct stat st; + int isdir; + lua_Number size; switch (lua_type(L, 1)) { - default: return luaL_argerror(L, 1, "expected file or pathname"); + default: return luaL_typerror(L, 1, "file or pathname"); case LUA_TSTRING: { const char *name = lua_tostring(L, 1); if (-1 == stat(name, &st)) @@ -150,18 +151,19 @@ static int ex_dirent(lua_State *L) return push_error(L); } break; } + isdir = S_ISDIR(st.st_mode); if (lua_type(L, 2) != LUA_TTABLE) { lua_newtable(L); lua_replace(L, 2); } lua_pushliteral(L, "type"); - if (S_ISDIR(st.st_mode)) + if (isdir) lua_pushliteral(L, "directory"); else lua_pushliteral(L, "file"); lua_settable(L, 2); lua_pushliteral(L, "size"); - lua_pushnumber(L, st.st_size); + lua_pushnumber(L, size); lua_settable(L, 2); lua_settop(L, 2); return 1; @@ -216,7 +218,7 @@ static int ex_dir(lua_State *L) struct diriter *pi; struct dirent *d; switch (lua_type(L, 1)) { - default: return luaL_argerror(L, 1, "expected pathname"); + default: return luaL_typerror(L, 1, "pathname"); case LUA_TSTRING: pathname = lua_tostring(L, 1); lua_pushcfunction(L, ex_dir); /* pathname ... iter */ @@ -313,7 +315,6 @@ static int ex_pipe(lua_State *L) FILE *i, *o, **pf; if (!make_pipe(&i, &o)) return push_error(L); - debug("make_pipe returns %p<-%p\n", i, o); luaL_getmetatable(L, LUA_FILEHANDLE); /* M */ *(pf = lua_newuserdata(L, sizeof *pf)) = i; /* M i */ lua_pushvalue(L, -2); /* M i M */ @@ -337,9 +338,20 @@ static void get_redirect(lua_State *L, int idx, const char *stdname, struct spaw /* args-opts -- true/nil error */ static int ex_spawn(lua_State *L) { - struct spawn_params *params = spawn_param_init(L); + struct spawn_params *params; + int have_options; - if (lua_type(L, 1) == LUA_TTABLE) { + switch (lua_type(L, 1)) { + default: return luaL_typerror(L, 1, "string or table"); + case LUA_TSTRING: + switch (lua_type(L, 2)) { + default: return luaL_typerror(L, 2, "table"); + case LUA_TNONE: have_options = 0; break; + case LUA_TTABLE: have_options = 1; break; + } + break; + case LUA_TTABLE: + have_options = 1; lua_getfield(L, 1, "command"); /* opts ... cmd */ if (!lua_isnil(L, -1)) { /* convert {command=command,arg1,...} to command {arg1,...} */ @@ -356,21 +368,23 @@ static int ex_spawn(lua_State *L) } lua_rawseti(L, 2, n); /* cmd opts ... */ } + if (lua_type(L, 1) != LUA_TSTRING) + return luaL_error(L, "bad command option (string expected, got %s)", + luaL_typename(L, 1)); + break; } + params = spawn_param_init(L); + /* get filename to execute */ - if (lua_type(L, 1) != LUA_TSTRING) - return luaL_error(L, "command option: expected string, got %s", luaL_typename(L, 1)); spawn_param_filename(params, lua_tostring(L, 1)); /* get arguments, environment, and redirections */ - switch (lua_type(L, 2)) { - default: return luaL_argerror(L, 2, "expected options table"); - case LUA_TNONE: break; - case LUA_TTABLE: + if (have_options) { lua_getfield(L, 2, "args"); /* cmd opts ... argtab */ switch (lua_type(L, -1)) { - default: return luaL_error(L, "args option must be an array"); + default: return luaL_error(L, "bad args option (table expected, got %s)", + luaL_typename(L, -1)); case LUA_TNIL: lua_pop(L, 1); /* cmd opts ... */ lua_pushvalue(L, 2); /* cmd opts ... opts */ @@ -383,7 +397,8 @@ static int ex_spawn(lua_State *L) } lua_getfield(L, 2, "env"); /* cmd opts ... envtab */ switch (lua_type(L, -1)) { - default: return luaL_error(L, "env option must be a table"); + default: return luaL_error(L, "bad env option (table expected, got %s)", + luaL_typename(L, -1)); case LUA_TNIL: case LUA_TTABLE: spawn_param_env(params); /* cmd opts ... */ @@ -392,8 +407,8 @@ static int ex_spawn(lua_State *L) get_redirect(L, 2, "stdin", params); /* cmd opts ... */ get_redirect(L, 2, "stdout", params); /* cmd opts ... */ get_redirect(L, 2, "stderr", params); /* cmd opts ... */ - break; } + return spawn_param_execute(params); /* proc/nil error */ } @@ -486,9 +501,7 @@ int luaopen_ex(lua_State *L) /* proc metatable */ luaL_newmetatable(L, PROCESS_HANDLE); /* ex . P */ copy_fields(L, ex_process_methods, 1, -1); /* ex . P */ - lua_pushliteral(L, "__index"); /* ex . P __index */ - lua_pushvalue(L, -2); /* ex . P __index P */ - lua_settable(L, -3); /* ex . P */ + lua_setfield(L, -1, "__index"); /* ex . P */ lua_settop(L, 1); /* ex */ return 1; diff --git a/posix/posix_spawn.c b/posix/posix_spawn.c index abbf013..9a80628 100755 --- a/posix/posix_spawn.c +++ b/posix/posix_spawn.c @@ -5,7 +5,8 @@ #include #include #include -#include "spawn.h" + +#include "posix_spawn.h" #define nelemof(A) (sizeof A / sizeof *A) @@ -50,10 +51,12 @@ int posix_spawnp(pid_t *restrict ppid, case -1: return -1; default: return 0; case 0: - if (act) - for (size_t i = 0; i < nelemof(act->dups); i++) + if (act) { + size_t i; + for (i = 0; i < nelemof(act->dups); i++) if (act->dups[i] > -1) dup2(i, act->dups[i]); + } environ = (char **)envp; execvp(path, argv); _exit(EXIT_FAILURE); diff --git a/posix/posix_spawn.h b/posix/posix_spawn.h index fedb0d9..f4d576d 100755 --- a/posix/posix_spawn.h +++ b/posix/posix_spawn.h @@ -2,6 +2,10 @@ #include #include +#if __STDC_VERSION__ < 199901L +#define restrict +#endif + typedef void *posix_spawnattr_t; enum { diff --git a/posix/spawn.c b/posix/spawn.c index d3a3028..5c492a1 100755 --- a/posix/spawn.c +++ b/posix/spawn.c @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -115,11 +117,8 @@ struct process { int spawn_param_execute(struct spawn_params *p) { lua_State *L = p->L; - struct process *proc = lua_newuserdata(L, sizeof *proc); int ret; - luaL_getmetatable(L, PROCESS_HANDLE); - lua_setmetatable(L, -2); - proc->status = -1; + struct process *proc; if (!p->argv) { p->argv = lua_newuserdata(L, 2 * sizeof *p->argv); p->argv[0] = p->command; @@ -127,6 +126,10 @@ int spawn_param_execute(struct spawn_params *p) } if (!p->envp) p->envp = (const char **)environ; + proc = lua_newuserdata(L, sizeof *proc); + luaL_getmetatable(L, PROCESS_HANDLE); + lua_setmetatable(L, -2); + proc->status = -1; ret = posix_spawnp(&proc->pid, p->command, &p->redirect, 0, (char *const *)p->argv, (char *const *)p->envp); posix_spawn_file_actions_destroy(&p->redirect); return ret != 0 ? push_error(L) : 1; diff --git a/posix/spawn.h b/posix/spawn.h index e1862ba..fc80446 100755 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -1,6 +1,7 @@ #ifndef SPAWN_H #define SPAWN_H +#include #include #define PROCESS_HANDLE "process" diff --git a/tests/rt3.lua b/tests/rt3.lua index d517ea3..a17cd25 100755 --- a/tests/rt3.lua +++ b/tests/rt3.lua @@ -2,7 +2,7 @@ require "ex" print"os.chdir" -assert(os.chdir("..")) +assert(os.chdir("tests")) print(os.currentdir()) print"os.mkdir" diff --git a/tests/rt4.lua b/tests/rt4.lua index 606bf4f..e672620 100755 --- a/tests/rt4.lua +++ b/tests/rt4.lua @@ -1,6 +1,5 @@ #!/usr/bin/env lua require "ex" - local f = assert(io.open("hullo.test", "w+")) f:lock("w") f:write("Hello\n") diff --git a/tests/rt5.lua b/tests/rt5.lua index 6648592..cefb88b 100755 --- a/tests/rt5.lua +++ b/tests/rt5.lua @@ -1,6 +1,5 @@ #!/usr/bin/env lua require "ex" - assert(arg[1], "argument required") local proc = assert(os.spawn(arg[1])) print(proc) diff --git a/w32api/ex.c b/w32api/ex.c index 2c14e44..d0ccde8 100755 --- a/w32api/ex.c +++ b/w32api/ex.c @@ -143,12 +143,12 @@ FILE *check_file(lua_State *L, int idx, const char *argname) FILE **pf; if (idx > 0) pf = luaL_checkudata(L, idx, LUA_FILEHANDLE); else { - idx = absindex(idx); + idx = absindex(L, idx); pf = lua_touserdata(L, idx); luaL_getmetatable(L, LUA_FILEHANDLE); - if (!pf || !lua_getmetatable(L, idx - 1) || !lua_rawequal(L, -1, -2)) - luaL_error(L, "%s option: expected %s, got %s", - argname, LUA_FILEHANDLE, luaL_typename(L, idx - 2)); + if (!pf || !lua_getmetatable(L, idx) || !lua_rawequal(L, -1, -2)) + luaL_error(L, "bad %s option (%s expected, got %s)", + argname, LUA_FILEHANDLE, luaL_typename(L, idx)); lua_pop(L, 2); } if (!*pf) return luaL_error(L, "attempt to use a closed file"), NULL; @@ -176,27 +176,30 @@ static uint64_t get_size(const char *name) /* pathname/file -- entry */ static int ex_dirent(lua_State *L) { - DWORD attr; - uint64_t size; + int isdir; + lua_Number size; switch (lua_type(L, 1)) { - default: return luaL_argerror(L, 1, "expected file or pathname"); + default: return luaL_typerror(L, 1, "file or pathname"); case LUA_TSTRING: { const char *name = lua_tostring(L, 1); - attr = GetFileAttributes(name); + DWORD attr = GetFileAttributes(name); if (attr == (DWORD)-1) return push_error(L); - if (attr & FILE_ATTRIBUTE_DIRECTORY) + isdir = attr & FILE_ATTRIBUTE_DIRECTORY; + if (isdir) size = 0; else size = get_size(name); } break; case LUA_TUSERDATA: { FILE *f = check_file(L, 1, NULL); + uint64_t lsize; BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(get_handle(f), &info)) return push_error(L); - attr = info.dwFileAttributes; - size = info.nFileSizeHigh; size <<= 32; size += info.nFileSizeLow; + isdir = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + lsize = info.nFileSizeHigh; lsize <<= 32; lsize += info.nFileSizeLow; + size = lsize; } break; } if (lua_type(L, 2) != LUA_TTABLE) { @@ -204,7 +207,7 @@ static int ex_dirent(lua_State *L) lua_replace(L, 2); } lua_pushliteral(L, "type"); - if (attr & FILE_ATTRIBUTE_DIRECTORY) + if (isdir) lua_pushliteral(L, "directory"); else lua_pushliteral(L, "file"); @@ -235,7 +238,7 @@ static int diriter_setpathname(lua_State *L, int index) { size_t len; const char *path = lua_tolstring(L, -1, &len); - if (path[len - 1] != *LUA_DIRSEP) { + if (path && path[len - 1] != *LUA_DIRSEP) { lua_pushliteral(L, LUA_DIRSEP); lua_concat(L, 2); } @@ -265,7 +268,7 @@ static int ex_dir(lua_State *L) const char *pathname; struct diriter *pi; switch (lua_type(L, 1)) { - default: return luaL_argerror(L, 1, "expected pathname"); + default: return luaL_typerror(L, 1, "pathname"); case LUA_TSTRING: lua_pushvalue(L, 1); /* pathname ... pathname */ lua_pushliteral(L, "\\*"); /* pathname ... pathname "\\*" */ @@ -389,9 +392,20 @@ static void get_redirect(lua_State *L, int idx, const char *stdname, struct spaw /* args-opts -- true/nil error */ static int ex_spawn(lua_State *L) { - struct spawn_params *params = spawn_param_init(L); + struct spawn_params *params; + int have_options; - if (lua_type(L, 1) == LUA_TTABLE) { + switch (lua_type(L, 1)) { + default: return luaL_typerror(L, 1, "string or table"); + case LUA_TSTRING: + switch (lua_type(L, 2)) { + default: return luaL_typerror(L, 2, "table"); + case LUA_TNONE: have_options = 0; break; + case LUA_TTABLE: have_options = 1; break; + } + break; + case LUA_TTABLE: + have_options = 1; lua_getfield(L, 1, "command"); /* opts ... cmd */ if (!lua_isnil(L, -1)) { /* convert {command=command,arg1,...} to command {arg1,...} */ @@ -408,21 +422,23 @@ static int ex_spawn(lua_State *L) } lua_rawseti(L, 2, n); /* cmd opts ... */ } + if (lua_type(L, 1) != LUA_TSTRING) + return luaL_error(L, "bad command option (string expected, got %s)", + luaL_typename(L, 1)); + break; } + params = spawn_param_init(L); + /* get filename to execute */ - if (lua_type(L, 1) != LUA_TSTRING) - return luaL_error(L, "command option: expected string, got %s", luaL_typename(L, 1)); spawn_param_filename(params, lua_tostring(L, 1)); /* get arguments, environment, and redirections */ - switch (lua_type(L, 2)) { - default: return luaL_argerror(L, 2, "expected options table"); - case LUA_TNONE: break; - case LUA_TTABLE: + if (have_options) { lua_getfield(L, 2, "args"); /* cmd opts ... argtab */ switch (lua_type(L, -1)) { - default: return luaL_error(L, "args option must be an array"); + default: return luaL_error(L, "bad args option (table expected, got %s)", + luaL_typename(L, -1)); case LUA_TNIL: lua_pop(L, 1); /* cmd opts ... */ lua_pushvalue(L, 2); /* cmd opts ... opts */ @@ -435,7 +451,8 @@ static int ex_spawn(lua_State *L) } lua_getfield(L, 2, "env"); /* cmd opts ... envtab */ switch (lua_type(L, -1)) { - default: return luaL_error(L, "env option must be a table"); + default: return luaL_error(L, "bad env option (table expected, got %s)", + luaL_typename(L, -1)); case LUA_TNIL: case LUA_TTABLE: spawn_param_env(params); /* cmd opts ... */ @@ -444,8 +461,8 @@ static int ex_spawn(lua_State *L) get_redirect(L, 2, "stdin", params); /* cmd opts ... */ get_redirect(L, 2, "stdout", params); /* cmd opts ... */ get_redirect(L, 2, "stderr", params); /* cmd opts ... */ - break; } + return spawn_param_execute(params); /* proc/nil error */ } @@ -538,9 +555,7 @@ int luaopen_ex(lua_State *L) /* proc metatable */ luaL_newmetatable(L, PROCESS_HANDLE); /* ex . P */ copy_fields(L, ex_process_methods, 1, -1); /* ex . P */ - lua_pushliteral(L, "__index"); /* ex . P __index */ - lua_pushvalue(L, -2); /* ex . P __index P */ - lua_settable(L, -3); /* ex . P */ + lua_setfield(L, -1, "__index"); /* ex . P */ lua_settop(L, 1); /* ex */ return 1;