diff --git a/Changelog b/Changelog new file mode 100755 index 0000000..25ff61a --- /dev/null +++ b/Changelog @@ -0,0 +1,31 @@ +ex-20070109 + +API changes + +* os.unsetenv is now folded into os.setenv + +* os.rmdir is now folded into os.remove + +* os.dir now elides . and .. entries from the listing + +* lock and unlock now appear in the io table + +* io.lock and io.unlock return the file object in case of success + +POSIX implementation changes + +* ENVIRON_DECL should be defined to expand to extern char **environ; on systems which neglect to declare environ when including + +* prepare for dirent metatable + +* ex_pipe() refactored + +Windows implementation changes + +* os.remove must be overridden + +* prepare for dirent metatable + +* simplify directory iteration by adding POSIX-like abstraction + +* ex_pipe() refactored diff --git a/README b/README index a60a4da..0d7661a 100755 --- a/README +++ b/README @@ -1,10 +1,10 @@ -- Environment -os.setenv(name, value) -os.unsetenv(name) +os.getenv(name) -- get environment variable +os.setenv(name, value) -- set/unset environment variable os.environ() -- returns a copy of the environment -- Miscellaneous -os.sleep(seconds) +os.sleep(seconds) -- sleep for (floating) seconds -- File system os.chdir(pathname) diff --git a/posix/Makefile b/posix/Makefile index 19c984e..1d5dfd9 100755 --- a/posix/Makefile +++ b/posix/Makefile @@ -1,13 +1,13 @@ CFLAGS = $(WARNINGS) $(DEFINES) $(INCLUDES) -DEFINES = $(DEBUG) -D_XOPEN_SOURCE=600 -DMISSING_POSIX_SPAWN -DMISSING_ENVIRON_DECL="extern char **environ" +DEFINES = $(DEBUG) -D_XOPEN_SOURCE=600 -DMISSING_POSIX_SPAWN -DENVIRON_DECL="extern char **environ;" 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 -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/medgar/src/lang/lua/lua-5.1.1 +#LUA = /home/medgar/src/lang/lua/lua5_1_1/cygw15 LIBS = -L$(LUA)/src -llua5.1 ex-OBJS = ex.o spawn.o diff --git a/posix/ex.c b/posix/ex.c index 8521785..78b79ec 100755 --- a/posix/ex.c +++ b/posix/ex.c @@ -3,23 +3,21 @@ #include #include #include -#include /* environ */ - -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" #include +ENVIRON_DECL #include #include #include -#include "spawn.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" -MISSING_ENVIRON_DECL; +#define absindex(L,i) ((i)>0?(i):lua_gettop(L)+(i)+1) +#include "spawn.h" -#define absindex(L,i) ((i)>0?(i):lua_gettop(L)+(i)+1) /* -- nil error */ extern int push_error(lua_State *L) @@ -41,8 +39,8 @@ static int ex_getenv(lua_State *L) return 1; } -/* name value -- true/nil error * - * name -- true/nil error */ +/* name value -- true/nil error + * name nil -- true/nil error */ static int ex_setenv(lua_State *L) { const char *nam = luaL_checkstring(L, 1); @@ -126,13 +124,23 @@ static FILE *check_file(lua_State *L, int idx, const char *argname) return *pf; } +static FILE **new_file(lua_State *L, int fd, const char *mode) +{ + FILE **pf = lua_newuserdata(L, sizeof *pf); + *pf = 0; + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + *pf = fdopen(fd, mode); + return pf; +} + + #define new_dirent(L) lua_newtable(L) -/* pathname/file -- entry */ +/* pathname/file [entry] -- entry */ static int ex_dirent(lua_State *L) { struct stat st; - int isdir; switch (lua_type(L, 1)) { default: return luaL_typerror(L, 1, "file or pathname"); case LUA_TSTRING: { @@ -146,19 +154,20 @@ 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_settop(L, 1); new_dirent(L); - lua_replace(L, 2); } - if (isdir) + else { + lua_settop(L, 2); + } + if (S_ISDIR(st.st_mode)) lua_pushliteral(L, "directory"); else lua_pushliteral(L, "file"); lua_setfield(L, 2, "type"); lua_pushnumber(L, st.st_size); lua_setfield(L, 2, "size"); - lua_settop(L, 2); return 1; } @@ -202,8 +211,8 @@ static int diriter_close(lua_State *L) static int isdotfile(const char *name) { - return name[0] && (name[1] == 0 - || (name[1] == '.' && name[2] == 0)); + return name[0] == '.' && (name[1] == '\0' + || (name[1] == '.' && name[2] == '\0')); } /* pathname -- iter state nil */ @@ -259,11 +268,11 @@ static int file_lock(lua_State *L, FILE *f, const char *mode, long offset, long k.l_len = length; if (-1 == fcntl(fileno(f), F_SETLK, &k)) return push_error(L); - lua_pushboolean(L, 1); + lua_settop(L, 1); return 1; } -/* file mode [offset [length]] -- true/nil error */ +/* file mode [offset [length]] -- file/nil error */ static int ex_lock(lua_State *L) { FILE *f = check_file(L, 1, NULL); @@ -273,7 +282,7 @@ static int ex_lock(lua_State *L) return file_lock(L, f, mode, offset, length); } -/* file [offset [length]] -- true/nil error */ +/* file [offset [length]] -- file/nil error */ static int ex_unlock(lua_State *L) { lua_pushliteral(L, "u"); @@ -290,22 +299,12 @@ static int closeonexec(int d) return fl; } -static int new_file(lua_State *L, int fd, const char *mode) -{ - 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) { int fd[2]; if (-1 == pipe(fd)) - return 0; + return push_error(L); closeonexec(fd[0]); closeonexec(fd[1]); new_file(L, fd[0], "r"); @@ -322,8 +321,8 @@ static void get_redirect(lua_State *L, int idx, const char *stdname, struct spaw lua_pop(L, 1); } -/* filename [args-opts] -- true/nil error */ -/* args-opts -- true/nil error */ +/* filename [args-opts] -- proc/nil error */ +/* args-opts -- proc/nil error */ static int ex_spawn(lua_State *L) { struct spawn_params *params; @@ -385,13 +384,13 @@ 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, "bad env option (table expected, got %s)", + luaL_typename(L, -1)); case LUA_TNIL: break; case LUA_TTABLE: spawn_param_env(params); /* cmd opts ... */ break; - default: - return luaL_error(L, "bad env option (table expected, got %s)", luaL_typename(L, -1)); } get_redirect(L, 2, "stdin", params); /* cmd opts ... */ get_redirect(L, 2, "stdout", params); /* cmd opts ... */ @@ -405,9 +404,7 @@ static int ex_spawn(lua_State *L) /* 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) { - from = absindex(L, from); - to = absindex(L, to); - for (; l->name; l++) { + for (to = absindex(L, to); l->name; l++) { lua_getfield(L, from, l->name); if (lua_isnil(L, -1)) { lua_pop(L, 1); @@ -467,6 +464,7 @@ int luaopen_ex(lua_State *L) lua_getglobal(L, "io"); /* ex . io */ if (lua_isnil(L, -1)) return luaL_error(L, "io not loaded"); copy_fields(L, ex_iolib, 1, -1); /* ex . io */ + copy_fields(L, ex_iofile_methods, 1, -1); /* ex . io */ lua_getfield(L, 1, "pipe"); /* ex . io ex_pipe */ lua_getfield(L, -2, "stderr"); /* ex . io ex_pipe io_stderr */ lua_getfenv(L, -1); /* ex . io ex_pipe io_stderr E */ diff --git a/posix/posix_spawn.c b/posix/posix_spawn.c index 7514df4..a1499b0 100755 --- a/posix/posix_spawn.c +++ b/posix/posix_spawn.c @@ -3,6 +3,7 @@ #include #include +ENVIRON_DECL #include #include @@ -12,7 +13,6 @@ #define OPEN_MAX sysconf(_SC_OPEN_MAX) #endif -MISSING_ENVIRON_DECL; int posix_spawn_file_actions_init(posix_spawn_file_actions_t *act) { diff --git a/posix/spawn.c b/posix/spawn.c index fd30bdf..b39d53b 100755 --- a/posix/spawn.c +++ b/posix/spawn.c @@ -1,7 +1,5 @@ -#include "lua.h" -#include "lauxlib.h" - #include +ENVIRON_DECL #include #if MISSING_POSIX_SPAWN #include "posix_spawn.h" @@ -9,8 +7,10 @@ #include #endif +#include "lua.h" +#include "lauxlib.h" + #include "spawn.h" -MISSING_ENVIRON_DECL; struct spawn_params { lua_State *L; diff --git a/posix/spawn.h b/posix/spawn.h index 46d9753..bb5df7c 100755 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -2,7 +2,7 @@ #define SPAWN_H #include -#include +#include "lua.h" #define PROCESS_HANDLE "process" struct process; diff --git a/w32api/Makefile b/w32api/Makefile index 3586c30..a752624 100755 --- a/w32api/Makefile +++ b/w32api/Makefile @@ -8,8 +8,10 @@ WARNINGS = -W -Wall -Wno-missing-braces LUA = /home/medgar/work/noom/lua/lua51 LUALIBS = -L$(LUA) -llua5.1 -ex.dll-OBJS = ex.o spawn.o pusherror.o +ex.dll-OBJS = ex.o spawn.o pusherror.o dirent.o ex.dll-LIBS = $(LUALIBS) $(EXTRALIBS) ex.dll: $(ex.dll-OBJS) $(CC) $(TARGET_ARCH) -shared -o $@ $(ex.dll-OBJS) $(ex.dll-LIBS) clean:; rm ex.dll *.o + +wdir.o: wdir.c wdir.h diff --git a/w32api/dirent.c b/w32api/dirent.c new file mode 100755 index 0000000..cbce017 --- /dev/null +++ b/w32api/dirent.c @@ -0,0 +1,68 @@ +#include +#include +#include "dirent.h" + +struct DIR_tag { + int first; + HANDLE hf; + WIN32_FIND_DATA fd; +}; + +static char *mkpattern(const char *name) +{ + static const char suffix[] = "\\*"; + size_t len = strlen(name); + char *pattern = malloc(len + sizeof suffix); + if (pattern) + strcpy(memcpy(pattern, name, len) + len, suffix); + return pattern; +} + +DIR * +opendir(const char *name) +{ + DIR *pi = malloc(sizeof *pi); + char *pattern = mkpattern(name); + if (!pi || !pattern + || INVALID_HANDLE_VALUE == (pi->hf = FindFirstFile(pattern, &pi->fd))) { + free(pi); + pi = 0; + } + else { + pi->first = 1; + } + free(pattern); + return pi; +} + +static int isdotfile(const char *name) +{ + return name[0] == '.' && (name[1] == 0 + || (name[1] == '.' && name[2] == 0)); +} + +const WIN32_FIND_DATA * +readdir(DIR *pi) +{ + switch (pi->first) do { + default: + if (!FindNextFile(pi->hf, &pi->fd)) { + FindClose(pi->hf); + pi->hf = INVALID_HANDLE_VALUE; + return 0; + } + case 1: pi->first = 0; + } while (isdotfile(pi->fd.cFileName)); + return &pi->fd; +} + +void +closedir(DIR *pi) +{ + if (pi->hf != INVALID_HANDLE_VALUE) + { + FindClose(pi->hf); + pi->hf = INVALID_HANDLE_VALUE; + } + free(pi); +} diff --git a/w32api/dirent.h b/w32api/dirent.h new file mode 100755 index 0000000..b88825a --- /dev/null +++ b/w32api/dirent.h @@ -0,0 +1,6 @@ +#include + +typedef struct DIR_tag DIR; +DIR *opendir(const char *name); +const WIN32_FIND_DATA *readdir(DIR *pi); +void closedir(DIR *pi); diff --git a/w32api/ex.c b/w32api/ex.c index 4466c44..5e22fdf 100755 --- a/w32api/ex.c +++ b/w32api/ex.c @@ -7,18 +7,19 @@ #include #include #include +#include "dirent.h" #include "lua.h" #include "lualib.h" #include "lauxlib.h" -#include "spawn.h" -#include "pusherror.h" +#define absindex(L,i) ((i)>0?(i):lua_gettop(L)+(i)+1) +#include "spawn.h" -#define absindex(L,i) ((i)>0?(i):lua_gettop(L)+(i)+1) +#include "pusherror.h" +#define push_error(L) windows_pushlasterror(L) -#define file_handle(fp) (HANDLE)_get_osfhandle(fileno(fp)) /* name -- value/nil */ @@ -32,7 +33,7 @@ static int ex_getenv(lua_State *L) len = GetEnvironmentVariable(nam, val, sizeof val); } if (len == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) - return windows_pushlasterror(L); + return push_error(L); lua_pushlstring(L, val, len); if (val != sval) free(val); return 1; @@ -45,7 +46,7 @@ static int ex_setenv(lua_State *L) const char *nam = luaL_checkstring(L, 1); const char *val = lua_tostring(L, 2); if (!SetEnvironmentVariable(nam, val)) - return windows_pushlasterror(L); + return push_error(L); lua_pushboolean(L, 1); return 1; } @@ -55,7 +56,7 @@ static int ex_environ(lua_State *L) { const char *nam, *val, *end; const char *envs = GetEnvironmentStrings(); - if (!envs) return windows_pushlasterror(L); + if (!envs) return push_error(L); lua_newtable(L); for (nam = envs; *nam; nam = end + 1) { end = strchr(val = strchr(nam, '=') + 1, '\0'); @@ -81,7 +82,7 @@ static int ex_chdir(lua_State *L) { const char *pathname = luaL_checkstring(L, 1); if (!SetCurrentDirectory(pathname)) - return windows_pushlasterror(L); + return push_error(L); lua_pushboolean(L, 1); return 1; } @@ -91,7 +92,7 @@ static int ex_mkdir(lua_State *L) { const char *pathname = luaL_checkstring(L, 1); if (!CreateDirectory(pathname, 0)) - return windows_pushlasterror(L); + return push_error(L); lua_pushboolean(L, 1); return 1; } @@ -101,7 +102,7 @@ static int ex_currentdir(lua_State *L) { char pathname[MAX_PATH + 1]; size_t len = GetCurrentDirectory(sizeof pathname, pathname); - if (len == 0) return windows_pushlasterror(L); + if (len == 0) return push_error(L); lua_pushlstring(L, pathname, len); return 1; } @@ -115,12 +116,13 @@ static int ex_remove(lua_State *L) || (attr & FILE_ATTRIBUTE_DIRECTORY ? !RemoveDirectory(pathname) : !DeleteFile(pathname))) - return windows_pushlasterror(L); + return push_error(L); lua_pushboolean(L, 1); return 1; } -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); @@ -137,6 +139,19 @@ FILE *check_file(lua_State *L, int idx, const char *argname) return *pf; } +static FILE **new_file(lua_State *L, HANDLE h, int dmode, const char *mode) +{ + FILE **pf = lua_newuserdata(L, sizeof *pf); + *pf = 0; + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + *pf = _fdopen(_open_osfhandle((long)h, dmode), mode); + return pf; +} + +#define file_handle(fp) (HANDLE)_get_osfhandle(fileno(fp)) + + static uint64_t get_file_size(const char *name) { HANDLE h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); @@ -169,7 +184,7 @@ static int ex_dirent(lua_State *L) const char *name = lua_tostring(L, 1); attr = GetFileAttributes(name); if (attr == (DWORD)-1) - return windows_pushlasterror(L); + return push_error(L); isdir = attr & FILE_ATTRIBUTE_DIRECTORY; if (isdir) size = 0; @@ -181,7 +196,7 @@ static int ex_dirent(lua_State *L) uint64_t lsize; BY_HANDLE_FILE_INFORMATION info; if (!GetFileInformationByHandle(file_handle(f), &info)) - return windows_pushlasterror(L); + return push_error(L); attr = info.dwFileAttributes; isdir = attr & FILE_ATTRIBUTE_DIRECTORY; lsize = info.nFileSizeHigh; lsize <<= 32; lsize += info.nFileSizeLow; @@ -205,12 +220,7 @@ static int ex_dirent(lua_State *L) return 1; } -#define DIR_HANDLE "WIN32_FIND_DATA" -struct diriter { - HANDLE hf; - int first; - WIN32_FIND_DATA fd; -}; +#define DIR_HANDLE "DIR*" /* ...diriter... -- ...diriter... pathname */ static int diriter_getpathname(lua_State *L, int index) @@ -238,32 +248,18 @@ 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->hf != INVALID_HANDLE_VALUE) { - FindClose(pi->hf); - pi->hf = INVALID_HANDLE_VALUE; - } + DIR **pd = lua_touserdata(L, 1); + closedir(*pd); + *pd = 0; lua_pushnil(L); diriter_setpathname(L, 1); return 0; } -static int isdotfile(const char *filename) +static int isdotfile(const char *name) { - return filename[0] == '.' && - (filename[1] == '\0' || (filename[1] == '.' && filename[2] == '\0')); -} - -static int nextfile(struct diriter *pi) -{ - if (!pi->first || isdotfile(pi->fd.cFileName)) - do if (!FindNextFile(pi->hf, &pi->fd)) { - FindClose(pi->hf); - pi->hf = INVALID_HANDLE_VALUE; - return 0; - } while (isdotfile(pi->fd.cFileName)); - pi->first = 0; - return 1; + return name[0] == '.' && (name[1] == '\0' + || (name[1] == '.' && name[2] == '\0')); } /* pathname -- iter state nil */ @@ -271,31 +267,29 @@ static int nextfile(struct diriter *pi) static int ex_dir(lua_State *L) { const char *pathname; - struct diriter *pi; + DIR **pd; + const WIN32_FIND_DATA *d; switch (lua_type(L, 1)) { default: return luaL_typerror(L, 1, "pathname"); case LUA_TSTRING: - lua_pushvalue(L, 1); /* pathname ... pathname */ - lua_pushliteral(L, "\\*"); /* pathname ... pathname "\\*" */ - lua_concat(L, 2); /* pathname ... pattern */ - pathname = lua_tostring(L, -1); - lua_pushcfunction(L, ex_dir); /* pathname ... pat iter */ - pi = lua_newuserdata(L, sizeof *pi);/* pathname ... pat iter state */ - pi->hf = FindFirstFile(pathname, &pi->fd); - if (pi->hf == INVALID_HANDLE_VALUE) - return windows_pushlasterror(L); - pi->first = 1; - luaL_getmetatable(L, DIR_HANDLE); /* pathname ... pat iter state M */ - lua_setmetatable(L, -2); /* pathname ... pat iter state */ - lua_pushvalue(L, 1); /* pathname ... pat iter state pathname */ - diriter_setpathname(L, -2); /* pathname ... pat iter state */ + pathname = lua_tostring(L, 1); + lua_pushcfunction(L, ex_dir); /* pathname ... iter */ + 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); - if (!nextfile(pi)) return 0; + pd = luaL_checkudata(L, 1, DIR_HANDLE); + do d = readdir(*pd); + while (d && isdotfile(d->cFileName)); + if (!d) return push_error(L); new_dirent(L); /* diriter ... entry */ diriter_getpathname(L, 1); /* diriter ... entry dirpath */ - lua_pushstring(L, pi->fd.cFileName);/* diriter ... entry dirpath name */ + lua_pushstring(L, d->cFileName); /* diriter ... entry dirpath name */ lua_pushvalue(L, -1); /* diriter ... entry dirpath name name */ lua_setfield(L, -4, "name"); /* diriter ... entry dirpath name */ lua_concat(L, 2); /* diriter ... entry fullpath */ @@ -326,8 +320,7 @@ static int file_lock(lua_State *L, FILE *f, const char *mode, long offset, long ret = flags ? LockFileEx(h, flags, 0, len.LowPart, len.HighPart, &ov) : UnlockFileEx(h, 0, len.LowPart, len.HighPart, &ov); if (!ret) - return windows_pushlasterror(L); - /* return the file */ + return push_error(L); lua_settop(L, 1); return 1; } @@ -351,33 +344,16 @@ static int ex_unlock(lua_State *L) } -static int make_pipe(FILE **i, FILE **o) +/* -- in out/nil error */ +static int ex_pipe(lua_State *L) { HANDLE ph[2]; - if (0 == CreatePipe(ph+0, ph+1, 0, 0)) - return 0; + if (!CreatePipe(ph + 0, ph + 1, 0, 0)) + return push_error(L); SetHandleInformation(ph[0], HANDLE_FLAG_INHERIT, 0); SetHandleInformation(ph[1], HANDLE_FLAG_INHERIT, 0); - *i = _fdopen(_open_osfhandle((long)ph[0], _O_RDONLY), "r"); - *o = _fdopen(_open_osfhandle((long)ph[1], _O_WRONLY), "w"); - return 1; -} - -#define new_file(L) lua_newuserdata(L, sizeof(FILE *)) - -/* -- in out/nil error */ -static int ex_pipe(lua_State *L) -{ - FILE *i, *o, **pf; - if (!make_pipe(&i, &o)) - return windows_pushlasterror(L); - luaL_getmetatable(L, LUA_FILEHANDLE); /* M */ - *(pf = new_file(L)) = i; /* M i */ - lua_pushvalue(L, -2); /* M i M */ - lua_setmetatable(L, -2); /* M i */ - *(pf = new_file(L)) = o; /* M i o */ - lua_pushvalue(L, -3); /* M i o M */ - lua_setmetatable(L, -2); /* M i o */ + new_file(L, ph[0], _O_RDONLY, "r"); + new_file(L, ph[1], _O_WRONLY, "w"); return 2; } @@ -386,7 +362,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, file_handle(check_file(L, -1, stdname))); lua_pop(L, 1); } @@ -456,6 +432,7 @@ static int ex_spawn(lua_State *L) default: return luaL_error(L, "bad env option (table expected, got %s)", luaL_typename(L, -1)); case LUA_TNIL: + break; case LUA_TTABLE: spawn_param_env(params); /* cmd opts ... */ break; @@ -468,11 +445,11 @@ static int ex_spawn(lua_State *L) return spawn_param_execute(params); /* proc/nil error */ } + /* 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) { - to = absindex(L, to); - for (; l->name; l++) { + for (to = absindex(L, to); l->name; l++) { lua_getfield(L, from, l->name); if (lua_isnil(L, -1)) { lua_pop(L, 1); @@ -533,6 +510,7 @@ int luaopen_ex(lua_State *L) lua_getglobal(L, "io"); /* ex . io */ if (lua_isnil(L, -1)) return luaL_error(L, "io not loaded"); copy_fields(L, ex_iolib, 1, -1); /* ex . io */ + copy_fields(L, ex_iofile_methods, 1, -1); /* ex . io */ lua_getfield(L, 1, "pipe"); /* ex . io ex_pipe */ lua_getfield(L, -2, "stderr"); /* ex . io ex_pipe io_stderr */ lua_getfenv(L, -1); /* ex . io ex_pipe io_stderr E */ diff --git a/w32api/pusherror.h b/w32api/pusherror.h index 3e33a94..9105332 100755 --- a/w32api/pusherror.h +++ b/w32api/pusherror.h @@ -1,8 +1,8 @@ #ifndef pusherror_h #define pusherror_h -#include #include +#include "lua.h" int windows_pusherror(lua_State *L, DWORD error, int nresults); #define windows_pushlasterror(L) windows_pusherror(L, GetLastError(), -2) diff --git a/w32api/spawn.c b/w32api/spawn.c index 08c7ad5..1f099c7 100755 --- a/w32api/spawn.c +++ b/w32api/spawn.c @@ -1,11 +1,10 @@ #include - -#include -#include - #include #include +#include "lua.h" +#include "lauxlib.h" + #include "spawn.h" #include "pusherror.h" @@ -81,11 +80,6 @@ void spawn_param_env(struct spawn_params *p) { lua_State *L = p->L; luaL_Buffer env; - if (lua_isnil(L, -1)) { - p->environment = 0; - lua_pop(L, 1); - return; - } /* convert env table to zstring list */ /* {nam1=val1,nam2=val2} => "nam1=val1\0nam2=val2\0\0" */ luaL_buffinit(L, &env); @@ -108,9 +102,8 @@ void spawn_param_env(struct spawn_params *p) p->environment = lua_tostring(L, -1); } -void spawn_param_redirect(struct spawn_params *p, const char *stdname, FILE *f) +void spawn_param_redirect(struct spawn_params *p, const char *stdname, HANDLE h) { - HANDLE h = file_handle(f); SetHandleInformation(h, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); if (!(p->si.dwFlags & STARTF_USESTDHANDLES)) { p->si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); diff --git a/w32api/spawn.h b/w32api/spawn.h index 0c484b7..30caf56 100755 --- a/w32api/spawn.h +++ b/w32api/spawn.h @@ -1,8 +1,8 @@ #ifndef SPAWN_H #define SPAWN_H -#include #include +#include "lua.h" #define PROCESS_HANDLE "process" struct process; @@ -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, HANDLE h); int spawn_param_execute(struct spawn_params *p); int process_wait(lua_State *L);