--- lpc-1.0.0.orig/Makefile +++ lpc-1.0.0/Makefile @@ -1,17 +1,24 @@ -LUA_PREFIX = /usr/local/ -PREFIX = /usr/local/ +LUA_PKGCONF ?= lua + MODULE = lpc VERSION = 1.0.0 -INSTALL_PREFIX = $(PREFIX)/lib/lua/5.1/ +ifneq ($(shell pkg-config $(LUA_PKGCONF) || echo not-installed),) +$(error $(LUA_PKGCONF).pc not found) +endif +INSTALL_PREFIX = $(DESTDIR)$(shell pkg-config $(LUA_PKGCONF) --variable=INSTALL_CMOD) + CC = gcc TARGET = lpc.so OBJS = lpc.o LIBS = -CFLAGS = -I $(LUA_PREFIX)/include -fPIC +CFLAGS = -fPIC LDFLAGS = -shared -fPIC +LUA_CFLAGS = $(shell pkg-config $(LUA_PKGCONF) --cflags) +LUA_LDFLAGS = $(shell pkg-config $(LUA_PKGCONF) --libs) + default: $(TARGET) @@ -29,7 +36,7 @@ rm -rf $(MODULE)-$(VERSION) $(TARGET): $(OBJS) - $(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) + $(CC) $(LUA_LDFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS) .c.o: - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(LUA_CFLAGS) $(CFLAGS) -c $< -o $@ --- lpc-1.0.0.orig/lpc.c +++ lpc-1.0.0/lpc.c @@ -1,7 +1,7 @@ /* ** LuaProcessCall ** Copyright DarkGod 2007 -** +** lua 5.1/5.2 compat (c) 2014 Timo Teräs */ #include @@ -15,47 +15,98 @@ #include "lauxlib.h" #include "lualib.h" -#define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#if LUA_VERSION_NUM < 502 -static FILE *tofile (lua_State *L) { - FILE **f = topfile(L); - if (*f == NULL) - luaL_error(L, "attempt to use a closed file"); - return *f; +static int lua_absindex(lua_State *L, int idx) { + return (idx > 0 || idx <= LUA_REGISTRYINDEX)? idx : lua_gettop(L) + idx + 1; +} /* lua_absindex() */ + +static void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) { + int i, t = lua_absindex(L, -1 - nup); + + for (; l->name; l++) { + for (i = 0; i < nup; i++) + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); + lua_setfield(L, t, l->name); + } + + lua_pop(L, nup); +} /* luaL_setfuncs() */ + +#define luaL_newlibtable(L, l) \ + lua_createtable(L, 0, (sizeof (l) / sizeof *(l)) - 1) + +#define luaL_newlib(L, l) \ + (luaL_newlibtable((L), (l)), luaL_setfuncs((L), (l), 0)) + +#ifndef LUA_FILEHANDLE /* Not defined by earlier LuaJIT releases */ +#define LUA_FILEHANDLE "FILE*" +#endif + +/* + * Lua 5.1 userdata is a simple FILE *, while LuaJIT is a struct with the + * first member a FILE *, similar to Lua 5.2. + */ +typedef struct luaL_Stream { + FILE *f; +} luaL_Stream; + +static int luaL_fileresult(lua_State *L, int stat, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } } -static int pushresult (lua_State *L, int i, const char *filename) { - int en = errno; /* calls to Lua API may change this value */ - if (i) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - if (filename) - lua_pushfstring(L, "%s: %s", filename, strerror(en)); - else - lua_pushfstring(L, "%s", strerror(en)); - lua_pushinteger(L, en); - return 3; - } +#define isclosed(p) ((p)->f == NULL) +#define markclosed(p) ((p)->f = NULL) + +#else + +#define isclosed(p) ((p)->closef == NULL) +#define markclosed(p) ((p)->closef = NULL) + +#endif + +#define tolstream(L) ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + +static FILE *tofile (lua_State *L) { + luaL_Stream *p = tolstream(L); + if (isclosed(p)) + luaL_error(L, "attempt to use a closed file"); + return p->f; } -static int io_fclose (lua_State *L) { - FILE **p = topfile(L); - int ok = (fclose(*p) == 0); - *p = NULL; - return pushresult(L, ok, NULL); +static int io_fclose (lua_State *L) +{ + luaL_Stream *p = tolstream(L); + int res = fclose(p->f); + markclosed(p); + return luaL_fileresult(L, (res == 0), NULL); } -static FILE **newfile_fd(lua_State *L, int fd, const char *mode) +static luaL_Stream *newfile_fd(lua_State *L, int fd, const char *mode) { - FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); - *pf = NULL; /* file handle is currently `closed' */ + luaL_Stream *p = (luaL_Stream *) lua_newuserdata(L, sizeof(luaL_Stream)); + markclosed(p); luaL_getmetatable(L, LUA_FILEHANDLE); lua_setmetatable(L, -2); - *pf = fdopen(fd, mode); - return pf; + p->f = fdopen(fd, mode); +#if LUA_VERSION_NUM >= 502 + p->closef = &io_fclose; +#endif + return p; } static int lpc_run(lua_State *L) @@ -64,12 +115,12 @@ int p_in[2]; int pid; - if (pipe(p_out) == -1) { lua_pushnil(L); return 1; } - if (pipe(p_in) == -1) { lua_pushnil(L); return 1; } + if (pipe(p_out) == -1) goto err_noclose; + if (pipe(p_in) == -1) goto err_closeout; + if ((pid = fork()) == -1) goto err_closeinout; - if ((pid = fork()) == -1) { lua_pushnil(L); return 1; } - else if (pid == 0) - { + if (pid == 0) { + /* child */ char **args; int n = lua_gettop(L); /* number of arguments */ int i; @@ -93,20 +144,24 @@ _exit(1); return 0; } - else - { - FILE **in; - FILE **out; - /* Cleanup */ - close(p_out[0]); - close(p_in[1]); + /* Cleanup */ + close(p_out[0]); + close(p_in[1]); + lua_pushnumber(L, pid); + newfile_fd(L, p_out[1], "w"); + newfile_fd(L, p_in[0], "r"); + return 3; - lua_pushnumber(L, pid); - out = newfile_fd(L, p_out[1], "w"); - in = newfile_fd(L, p_in[0], "r"); - return 3; - } +err_closeinout: + close(p_in[0]); + close(p_in[1]); +err_closeout: + close(p_out[0]); + close(p_out[1]); +err_noclose: + lua_pushnil(L); + return 1; } static int lpc_wait(lua_State *L) @@ -116,13 +171,9 @@ int nonblock = luaL_optinteger(L, 2, 0); if (waitpid(pid, &ret, (nonblock == 1) ? WNOHANG : 0) == pid) - { lua_pushnumber(L, ret); - } else - { lua_pushnil(L); - } return 1; } @@ -141,13 +192,9 @@ FD_SET(fileno(f), &rfds); retval = select(1 + fileno(f), &rfds, NULL, NULL, &tv); if (retval == 1) - { lua_pushboolean(L, 1); - } else - { lua_pushnil(L); - } return 1; } @@ -166,13 +213,9 @@ FD_SET(fileno(f), &wfds); retval = select(1 + fileno(f), NULL, &wfds, NULL, &tv); if (retval == 1) - { lua_pushboolean(L, 1); - } else - { lua_pushboolean(L, 0); - } return 1; } @@ -192,7 +235,7 @@ lua_settable (L, -3); } -static const struct luaL_reg lpclib[] = +static const struct luaL_Reg lpclib[] = { {"run", lpc_run}, {"wait", lpc_wait}, @@ -207,15 +250,15 @@ static void createmeta(lua_State *L) { - luaL_getmetatable(L, LUA_FILEHANDLE); /* get IO's metatable for file handles */ - luaL_register(L, NULL, io_add_flib); /* file methods */ + luaL_getmetatable(L, LUA_FILEHANDLE); /* get IO's metatable for file handles */ + luaL_setfuncs(L, io_add_flib, 0); /* file methods */ } - int luaopen_lpc (lua_State *L) { createmeta(L); +#if LUA_VERSION_NUM < 502 luaL_openlib(L, "lpc", lpclib, 0); /* create environment for 'run' */ @@ -225,6 +268,9 @@ lua_setfield(L, -2, "__close"); lua_setfenv(L, -2); lua_pop(L, 1); /* pop 'run' */ +#else + luaL_newlib(L, lpclib); +#endif set_info(L); return 1;