Skip to content

updated for 5.2 #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions lsignal.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define LUA_LIB_NAME "signal"
#define LUA_LIB_VERSION "1.2.0"
#define LUA_SIGNAL_NAME "LUA_SIGNAL"
#define LUA_SIGNAL_ENV 1

#if !(defined(_POSIX_SOURCE) || defined(sun) || defined(__sun))
#define INCLUDE_KILL 1
Expand Down Expand Up @@ -218,7 +219,7 @@ static int get_signal (lua_State *L, int idx)
return (int) lua_tointeger(L, idx);
case LUA_TSTRING:
lua_pushvalue(L, idx);
lua_rawget(L, LUA_ENVIRONINDEX);
lua_rawget(L, lua_upvalueindex(LUA_SIGNAL_ENV));
if (!lua_isnumber(L, -1))
return luaL_argerror(L, idx, "invalid signal string");
lua_replace(L, idx);
Expand Down Expand Up @@ -264,26 +265,26 @@ static int l_signal (lua_State *L)
option = (luaL_checktype(L, 2, LUA_TFUNCTION), SET);

lua_pushvalue(L, 1);
lua_rawget(L, LUA_ENVIRONINDEX); /* return old handler */
lua_rawget(L, lua_upvalueindex(LUA_SIGNAL_ENV)); /* return old handler */

lua_pushvalue(L, 1);
switch (option)
{
case IGNORE:
lua_pushnil(L);
lua_rawset(L, LUA_ENVIRONINDEX);
lua_rawset(L, lua_upvalueindex(LUA_SIGNAL_ENV));
signal(sig, SIG_IGN);
signal_stack[sig+signal_stack_top] = signal_stack[sig] = 0;
break;
case DEFAULT:
lua_pushnil(L);
lua_rawset(L, LUA_ENVIRONINDEX);
lua_rawset(L, lua_upvalueindex(LUA_SIGNAL_ENV));
signal(sig, SIG_DFL);
signal_stack[sig+signal_stack_top] = signal_stack[sig] = 0;
break;
case SET:
lua_pushvalue(L, 2);
lua_rawset(L, LUA_ENVIRONINDEX);
lua_rawset(L, lua_upvalueindex(LUA_SIGNAL_ENV));

#if USE_SIGACTION
{
Expand Down Expand Up @@ -391,16 +392,33 @@ int luaopen_signal (lua_State *L)
luaL_error(L, "library should be opened by the main thread");

/* environment */
lua_newtable(L);
lua_replace(L, LUA_ENVIRONINDEX);
lua_pushvalue(L, LUA_ENVIRONINDEX);
lua_setfield(L, LUA_REGISTRYINDEX, LUA_SIGNAL_NAME); /* for hooks */
lua_pushstring(L, "shared signal table"); // debugging
lua_newtable(L); /* Create a table that will hold all of our hooks */
int upvalue_stackpos = lua_gettop(L); // save the stack location for later
lua_pushvalue(L, -1); // disposable copy
lua_setfield(L, LUA_REGISTRYINDEX, LUA_SIGNAL_NAME);

/* register the library */
#if LUA_VERSION_NUM == 501
lua_pushvalue(L, upvalue_stackpos); // third copy
luaI_openlib(L, LUA_LIB_NAME, lib, 1);
int rettable_stackpos = lua_gettop(L);
#else
luaL_newlibtable(L, lib); /* Create a new table sized for the functions in lib */
int rettable_stackpos = lua_gettop(L);
lua_pushvalue(L, upvalue_stackpos); // third copy
luaL_setfuncs(L, lib, 1); /* Register one upvalue for every function in lib */
#endif

/* add the library */
luaL_register(L, LUA_LIB_NAME, lib);
lua_pushliteral(L, LUA_LIB_VERSION);
lua_setfield(L, -2, "version");

#if 0
assert(lua_istable(L, rettable_stackpos));
lua_rawget(L, rettable_stackpos);
assert(lua_isfunction(L, -1));
lua_pop(L, 1);
#endif

/* Set up signal handlers */
for (i = 0, max_signal = 0; lua_signals[i].name != NULL; i++)
if (lua_signals[i].sig > max_signal)
max_signal = lua_signals[i].sig+1; /* +1 !!! (for < loops) */
Expand All @@ -409,27 +427,29 @@ int luaopen_signal (lua_State *L)
lua_newtable(L);
lua_pushcfunction(L, library_gc);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2); /* when userdata is gc'd, close library */
assert(lua_istable(L, rettable_stackpos));
lua_setmetatable(L, rettable_stackpos); /* when userdata is gc'd, close library */
memset((void *) signal_stack, 0, sizeof(volatile sig_atomic_t)*max_signal*2);
signal_stack_top = max_signal;
lua_pushboolean(L, 1);
lua_rawset(L, LUA_ENVIRONINDEX);

while (i--) /* i set from previous for loop */
{
lua_pushstring(L, lua_signals[i].name);
lua_pushinteger(L, lua_signals[i].sig);
lua_rawset(L, LUA_ENVIRONINDEX); /* add copy to environment table */
lua_pushstring(L, lua_signals[i].name);
lua_pushinteger(L, lua_signals[i].sig);
lua_settable(L, -3); /* add copy to signal table */
assert(lua_istable(L, upvalue_stackpos));
lua_rawset(L, upvalue_stackpos); /* add copy to environment table */
}


/* set default interrupt handler */
lua_getfield(L, -1, "signal");
assert(lua_istable(L, rettable_stackpos));
lua_getfield(L, rettable_stackpos, "signal");
assert(lua_isfunction(L, -1));
lua_pushinteger(L, SIGINT);
lua_pushcfunction(L, interrupted);
lua_call(L, 2, 0);


assert(lua_istable(L, rettable_stackpos));
lua_pushvalue(L, rettable_stackpos);
return 1;
}
3 changes: 2 additions & 1 deletion test.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "signal"
local signal = require "signal"


signal.signal("SIGTERM", function(n, i) print("signal handler", n, i); end);

Expand Down