Skip to content

Ctrl-C Interrupt Support #1

Description

@guysv

This is a tricky feature to implement because of the fact that the popular lua consoles (lua 5.3-5.1 & luajit) implement SIGINTs poorly

For example, lets take the reference implementation lua 5.3.
here is the SIGINT handler:

static void laction (int i) {
  signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
  lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}

The handler sets the default handler (which crashes) upon activation.
Because we run in script mode (to execute ilua's interp.lua) that handler is only installed once. Because of that, If the same session will handle two SIGINTs, it will crash.

A secondary problem is that there are many lua consoles who are not even handling SIGINTs, and crash upon the signal.

There are couple of solutions I could think of:

  1. Run in console mode

Pipe the interp.script into the host lua stdin in interactive mode (after getting rid of the prompts)
e.g.

lua -i -e "_PROMPT='' _PROMPT2=''" < interp.lua

This way the lua-error-throwing SIGINT handler is installed after every evaluation, and multiple signals could be caught

The down side is that we should not allow the user to read from stdin (io.input:read) because that will mess things up.

  1. Serialize the session

We could track every evaluation request, serialize a state in the python kernel, and on SIGINT kill the lua host, launch a new one and dump the state back. Not sure this is possible though.

  1. Proxy lua host's signal()

If we could replace signal() with a function that NO-OPs on SIG_DFL, we could use the lua-error-throwing handler multiple times
i.e. Inject the lua host some library like this

void *__real_signal(int sig, void *func);

void *__wrap_signal(int sig, void *func)
{
	void *old_handler = __real_signal(sig, SIG_DFL);
	__real_signal(sig, old_handler);
	if (SIGINT == sig && SIG_DFL == func)
	{
		return old_handler;
	}
	else
	{
		return __real_signal(sig, func);
	}
}

The down-side of course is that implementing DLL injection for every platform (Windows especially) is hell.

  1. Not implementing Ctrl-C at all

We could call this a known issue, and stop bothering about it.
If we were to offer a solution anyway, we could distribute a patched lua.c (that won't reinstall default interrupt upon signal)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions