*** empty log message ***

master
mark 21 years ago
parent 0abc74ed14
commit 05bc6c5bf9

@ -1,7 +1,10 @@
CFLAGS = $(WARNINGS) $(DEFINES) $(INCLUDES) CFLAGS = $(WARNINGS) $(DEFINES) $(INCLUDES)
DEFINES = -D_XOPEN_SOURCE=600
INCLUDES = -I${LUA}/src
WARNINGS = -W -Wall WARNINGS = -W -Wall
#DEFINES = -D_XOPEN_SOURCE=600
INCLUDES = -I$(LUA)/include
LUA = /home/mark/src/lang/lua/lua-5.1-rc1 LUA = /home/mark/src/lang/lua/lua-5.1-rc1
lu.so: lu.o; $(CC) -shared -o $@ lu.o mingw:; $(MAKE) "EX_LIB=ex.dll"
cygwin:; $(MAKE) "EX_LIB=ex.so" "DEFINES=-D_XOPEN_SOURCE=600"

@ -1,13 +1,12 @@
CFLAGS = -std=c99 $(WARNINGS) $(DEFINES) $(INCLUDES) CFLAGS = -std=c99 $(WARNINGS) $(DEFINES) $(INCLUDES)
DEFINES = -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L -U__STRICT_ANSI__ DEFINES = -D_POSIX_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L -U__STRICT_ANSI__
INCLUDES = -I${LUA}/src INCLUDES = -I$(LUA)/include -I.
WARNINGS = -W -Wall WARNINGS = -W -Wall
LUA = /home/mark/src/lang/lua/lua-5.1-rc2 LUA = /home/mark/src/lang/lua/lua-5.1-rc2
ex.so: ex.o; $(CC) -shared -o $@ ex.o ex.so: ex.o; $(CC) -shared -o $@ ex.o
#LIBS = -L$(LUA)/lib -llua51 spawn.a #LIBS = -L$(LUA)/lib -llua51 spawn.a
ex.dll: ex.o $(LIBS); $(CC) -shared -o $@ ex.o $(LUALIBS) $(LIBS) ex.dll: ex.o $(LIBS); $(CC) -shared -L$(LUA)/bin/Cygwin -o $@ ex.o spawn.o -llua51
spawn.a: spawn.o; $(AR) r $@ $< spawn.o: spawn.c spawn.h

@ -14,12 +14,7 @@
#include <spawn.h> #include <spawn.h>
#include <sys/wait.h> #include <sys/wait.h>
extern char **environ;
#define debug(...) fprintf(stderr,__VA_ARGS__) #define debug(...) fprintf(stderr,__VA_ARGS__)
#define Dposix_spawnp(ppid,cmd,act,attrp,argv,envp) \
(debug("posix_spawnp(%p,\"%s\",%p,%p,%p,%p)\n",(void*)ppid,cmd,(void*)act,(void*)attrp,(void*)argv,(void*)envp),\
posix_spawnp(ppid,cmd,act,attrp,argv,envp))
/* Generally useful function -- what luaL_checkudata() should do */ /* Generally useful function -- what luaL_checkudata() should do */
@ -76,8 +71,8 @@ static int ex_unsetenv(lua_State *L)
/* -- environment-table */ /* -- environment-table */
static int ex_environ(lua_State *L) static int ex_environ(lua_State *L)
{ {
char **env;
const char *nam, *val, *end; const char *nam, *val, *end;
const char **env;
lua_newtable(L); lua_newtable(L);
for (env = environ; (nam = *env); env++) { for (env = environ; (nam = *env); env++) {
end = strchr(val = strchr(nam, '=') + 1, '\0'); end = strchr(val = strchr(nam, '=') + 1, '\0');
@ -235,11 +230,12 @@ static const char **build_env(lua_State *L)
return build_args(L); /* ... */ return build_args(L); /* ... */
} }
/* */
static int get_redirect(lua_State *L, posix_spawn_file_actions_t *file_actions, static int get_redirect(lua_State *L, posix_spawn_file_actions_t *file_actions,
const char *stream, int descriptor) const char *stdname, int descriptor)
{ {
int ret; int ret;
lua_getfield(L, 2, stream); lua_getfield(L, 2, stdname);
if ((ret = !lua_isnil(L, -1))) if ((ret = !lua_isnil(L, -1)))
posix_spawn_file_actions_adddup2(file_actions, posix_spawn_file_actions_adddup2(file_actions,
fileno(luaL_checkudata(L, -1, LUA_FILEHANDLE)), descriptor); fileno(luaL_checkudata(L, -1, LUA_FILEHANDLE)), descriptor);
@ -272,7 +268,7 @@ static int ex_spawn(lua_State *L)
} }
else { else {
/* convert {arg0,arg1,...} to arg0 {arg1,...} */ /* convert {arg0,arg1,...} to arg0 {arg1,...} */
int i, n = lua_objlen(L, 1); size_t i, n = lua_objlen(L, 1);
lua_rawgeti(L, 1, 1); /* opts ... nil cmd */ lua_rawgeti(L, 1, 1); /* opts ... nil cmd */
if (lua_isnil(L, -1)) if (lua_isnil(L, -1))
luaL_error(L, "no command specified"); luaL_error(L, "no command specified");
@ -341,7 +337,7 @@ static int ex_spawn(lua_State *L)
proc->status = -1; proc->status = -1;
assert(argv && argv[0]); assert(argv && argv[0]);
assert(envp && envp[0]); assert(envp && envp[0]);
ret = Dposix_spawnp(&proc->pid, command, pactions, 0, (char *const *)argv, (char *const *)envp); ret = posix_spawnp(&proc->pid, command, pactions, 0, (char *const *)argv, (char *const *)envp);
debug("returns %d:%ld\n", ret, (long)proc->pid); debug("returns %d:%ld\n", ret, (long)proc->pid);
if (pactions) if (pactions)
posix_spawn_file_actions_destroy(pactions); posix_spawn_file_actions_destroy(pactions);

@ -9,10 +9,6 @@
#define nelemof(A) (sizeof A / sizeof *A) #define nelemof(A) (sizeof A / sizeof *A)
struct posix_spawn_file_actions {
int dups[3];
};
int posix_spawn_file_actions_init(posix_spawn_file_actions_t *act) int posix_spawn_file_actions_init(posix_spawn_file_actions_t *act)
{ {
act->dups[0] = act->dups[1] = act->dups[2] = -1; act->dups[0] = act->dups[1] = act->dups[2] = -1;

@ -2,7 +2,7 @@
#include <signal.h> #include <signal.h>
#include <sys/types.h> #include <sys/types.h>
typedef struct posix_spawnattr posix_spawnattr_t; typedef void *posix_spawnattr_t;
enum { enum {
POSIX_SPAWN_RESETIDS, POSIX_SPAWN_RESETIDS,
@ -29,6 +29,9 @@ int posix_spawnattr_setsigmask(posix_spawnattr_t *restrict attrp, const sigset_t
int posix_spawnattr_destroy(posix_spawnattr_t *attrp); int posix_spawnattr_destroy(posix_spawnattr_t *attrp);
typedef struct posix_spawn_file_actions posix_spawn_file_actions_t; typedef struct posix_spawn_file_actions posix_spawn_file_actions_t;
struct posix_spawn_file_actions {
int dups[3];
};
int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions); int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions);
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, int filedes, int newfiledes); int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, int filedes, int newfiledes);

@ -86,7 +86,8 @@ static int ex_unsetenv(lua_State *L)
/* -- environment-table */ /* -- environment-table */
static int ex_environ(lua_State *L) static int ex_environ(lua_State *L)
{ {
const char *envs, *nam, *val, *end; const char *nam, *val, *end;
const char *envs;
if (!(envs = GetEnvironmentStrings())) if (!(envs = GetEnvironmentStrings()))
return windows_error(L); return windows_error(L);
lua_newtable(L); lua_newtable(L);
@ -150,14 +151,13 @@ static HANDLE get_handle(FILE *f)
/* pathname -- iter state nil */ /* pathname -- iter state nil */
static int ex_dir(lua_State *L) { return luaL_error(L, "not yet implemented"); } static int ex_dir(lua_State *L) { return luaL_error(L, "not yet implemented"); }
/* pathname -- entry */ /* pathname/file -- entry */
/* XXX io.file -- entry */
static int ex_dirent(lua_State *L) { return luaL_error(L, "not yet implemented"); } static int ex_dirent(lua_State *L) { return luaL_error(L, "not yet implemented"); }
static int file_lock(lua_State *L, FILE *fh, const char *mode, long offset, long length) static int file_lock(lua_State *L, FILE *f, const char *mode, long offset, long length)
{ {
HANDLE h = get_handle(fh); HANDLE h = get_handle(f);
DWORD flags; DWORD flags;
LARGE_INTEGER len = {0}; LARGE_INTEGER len = {0};
OVERLAPPED ov = {0}; OVERLAPPED ov = {0};
@ -179,31 +179,6 @@ static int file_lock(lua_State *L, FILE *fh, const char *mode, long offset, long
return 1; return 1;
} }
static int file_lock_crt(lua_State *L, FILE *fh, const char *mode, long offset, long length)
{
int code;
int lkmode;
switch (*mode) {
case 'r': lkmode = LK_NBRLCK; break;
case 'w': lkmode = LK_NBLCK; break;
case 'u': lkmode = LK_UNLCK; break;
default : return luaL_error (L, "invalid mode");
}
if (!length) {
fseek (fh, 0L, SEEK_END);
length = ftell (fh);
}
fseek (fh, offset, SEEK_SET);
code = _locking (fileno(fh), lkmode, length);
if (code == -1) {
lua_pushboolean(L, 0);
lua_pushstring(L, strerror(errno));
return 2;
}
lua_pushboolean(L, 1);
return 1;
}
/* file mode [offset [length]] -- true/nil error */ /* file mode [offset [length]] -- true/nil error */
static int ex_lock(lua_State *L) static int ex_lock(lua_State *L)
{ {
@ -223,23 +198,29 @@ static int ex_unlock(lua_State *L)
} }
/* -- LUA_FILEHANDLE file file */
static int make_pipe(lua_State *L, FILE *i, FILE *o)
{
FILE **pf;
luaL_getmetatable(L, LUA_FILEHANDLE);
*(pf = lua_newuserdata(L, sizeof *pf)) = i;
lua_pushvalue(L, -2);
lua_setmetatable(L, -2);
*(pf = lua_newuserdata(L, sizeof *pf)) = o;
lua_pushvalue(L, -2);
lua_setmetatable(L, -2);
return 2;
}
/* -- in out/nil error */ /* -- in out/nil error */
static int ex_pipe(lua_State *L) static int ex_pipe(lua_State *L)
{ {
HANDLE ph[2]; HANDLE ph[2];
FILE **pf;
if (0 == CreatePipe(ph+0, ph+1, 0, 0)) if (0 == CreatePipe(ph+0, ph+1, 0, 0))
return windows_error(L); return windows_error(L);
luaL_getmetatable(L, LUA_FILEHANDLE); /* M */ return make_pipe(L,
pf = lua_newuserdata(L, sizeof *pf); /* M in */ _fdopen(_open_osfhandle((long)ph[0], _O_RDONLY), "r"),
lua_pushvalue(L, -2); /* M in M */ _fdopen(_open_osfhandle((long)ph[1], _O_WRONLY), "w"));
lua_setmetatable(L, -2); /* M in */
*pf = _fdopen(_open_osfhandle((long)ph[0], _O_RDONLY), "r");
pf = lua_newuserdata(L, sizeof *pf); /* M in out */
lua_pushvalue(L, -3); /* M in out M */
lua_setmetatable(L, -2); /* M in out */
*pf = _fdopen(_open_osfhandle((long)ph[1], _O_WRONLY), "w");
return 2;
} }
static int needs_quoting(const char *s) static int needs_quoting(const char *s)
@ -325,24 +306,24 @@ static int ex_spawn(lua_State *L)
BOOL ret; BOOL ret;
if (lua_type(L, 1) == LUA_TTABLE) { if (lua_type(L, 1) == LUA_TTABLE) {
lua_getfield(L, 1, "command"); /* opts cmd */ lua_getfield(L, 1, "command"); /* opts ... cmd */
if (!lua_isnil(L, -1)) { if (!lua_isnil(L, -1)) {
/* convert {command=command,arg1,...} to command {arg1,...} */ /* convert {command=command,arg1,...} to command {arg1,...} */
lua_insert(L, 1); /* cmd opts */ lua_insert(L, 1); /* cmd opts ... */
} }
else { else {
/* convert {arg0,arg1,...} to arg0 {arg1,...} */ /* convert {arg0,arg1,...} to arg0 {arg1,...} */
size_t i, n = lua_objlen(L, 1); size_t i, n = lua_objlen(L, 1);
lua_rawgeti(L, 1, 1); /* opts nil cmd */ lua_rawgeti(L, 1, 1); /* opts ... nil cmd */
if (lua_isnil(L, -1)) if (lua_isnil(L, -1))
luaL_error(L, "no command specified"); luaL_error(L, "no command specified");
/* XXX check LUA_TSTRING */ /* XXX check LUA_TSTRING */
lua_insert(L, 1); /* cmd opts nil */ lua_insert(L, 1); /* cmd opts ... nil */
for (i = 2; i <= n; i++) { for (i = 2; i <= n; i++) {
lua_rawgeti(L, 2, i); /* cmd opts nil argi */ lua_rawgeti(L, 2, i); /* cmd opts ... nil argi */
lua_rawseti(L, 2, i - 1); /* cmd opts nil */ lua_rawseti(L, 2, i - 1); /* cmd opts ... nil */
} }
lua_rawseti(L, 2, n); /* cmd opts */ lua_rawseti(L, 2, n); /* cmd opts ... */
} }
} }
@ -357,16 +338,12 @@ static int ex_spawn(lua_State *L)
lua_replace(L, 1); /* "cmd" ... */ lua_replace(L, 1); /* "cmd" ... */
} }
/* set defaults */
environment = 0;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
/* get arguments, environment, and redirections */ /* get arguments, environment, and redirections */
switch (lua_type(L, 2)) { switch (lua_type(L, 2)) {
default: luaL_argerror(L, 2, "expected options table"); break; default: luaL_argerror(L, 2, "expected options table"); break;
case LUA_TNONE: break; case LUA_TNONE:
environment = 0;
break;
case LUA_TTABLE: case LUA_TTABLE:
lua_getfield(L, 2, "args"); /* cmd opts ... argtab */ lua_getfield(L, 2, "args"); /* cmd opts ... argtab */
switch (lua_type(L, -1)) { switch (lua_type(L, -1)) {
@ -390,12 +367,16 @@ static int ex_spawn(lua_State *L)
switch (lua_type(L, -1)) { switch (lua_type(L, -1)) {
default: luaL_error(L, "env option must be a table"); break; default: luaL_error(L, "env option must be a table"); break;
case LUA_TNIL: case LUA_TNIL:
environment = 0;
lua_pop(L, 1); /* cmd opts */ lua_pop(L, 1); /* cmd opts */
break; break;
case LUA_TTABLE: case LUA_TTABLE:
environment = concat_env(L); /* cmd opts ... envstr */ environment = concat_env(L); /* cmd opts ... envstr */
break; break;
} }
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
if (get_redirect(L, "stdin", &si.hStdInput) /* cmd opts ... in? */ if (get_redirect(L, "stdin", &si.hStdInput) /* cmd opts ... in? */
| get_redirect(L, "stdout", &si.hStdOutput) /* cmd opts ... out? */ | get_redirect(L, "stdout", &si.hStdOutput) /* cmd opts ... out? */
| get_redirect(L, "stderr", &si.hStdError)) /* cmd opts ... err? */ | get_redirect(L, "stderr", &si.hStdError)) /* cmd opts ... err? */

Loading…
Cancel
Save