Skip to content

Commit

Permalink
lua: fix SIGINT handling
Browse files Browse the repository at this point in the history
Tarantool console quits if you type Ctrl+C.
This patch fixes console behavior on sending SIGINT. Console discards the current input on typing Ctrl+C and invites user to the new line.

In daemon mode the process will exit after receiving SIGINT.

Fixes #2717
  • Loading branch information
vr009 committed Dec 4, 2021
1 parent 71a789f commit 63dccbf
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,31 @@ signal_cb(ev_loop *loop, struct ev_signal *w, int revents)
tarantool_exit(0);
}

static void
signal_sigint_cb(ev_loop *loop, struct ev_signal *w, int revents)
{
(void) loop;
(void) w;
(void) revents;

/**
* If running in daemon mode, tarantool exits on SIGINT
*/
if (pid_file)
tarantool_exit(0);

/**
* Setting prompt explicitly every time, cause of
* need to return from search mode
*/
rl_set_prompt("tarantool>");
write(STDOUT_FILENO, "\n", sizeof("\n")-1);
RL_UNSETSTATE(RL_STATE_ISEARCH | RL_STATE_NSEARCH | RL_STATE_SEARCH);
rl_on_new_line();
rl_replace_line("", 0);
rl_redisplay();
}

static void
signal_sigwinch_cb(ev_loop *loop, struct ev_signal *w, int revents)
{
Expand Down Expand Up @@ -251,7 +276,7 @@ signal_init(void)
crash_signal_init();

ev_signal_init(&ev_sigs[0], sig_checkpoint, SIGUSR1);
ev_signal_init(&ev_sigs[1], signal_cb, SIGINT);
ev_signal_init(&ev_sigs[1], signal_sigint_cb, SIGINT);
ev_signal_init(&ev_sigs[2], signal_cb, SIGTERM);
ev_signal_init(&ev_sigs[3], signal_sigwinch_cb, SIGWINCH);
ev_signal_init(&ev_sigs[4], say_logrotate, SIGHUP);
Expand Down
46 changes: 46 additions & 0 deletions test/app-tap/gh-2717-no-quit-sigint.test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env tarantool

local fiber = require('fiber')
local tap = require('tap')
local popen = require('popen')

--
-- gh-2717: tarantool console quit on sigint
--

local TARANTOOL_PATH = arg[-1]

local res = tap.test('gh-2717', function(test)
print(TARANTOOL_PATH)

test:plan(3)
local prompt = "tarantool>"
local ph = popen.shell(TARANTOOL_PATH .. " -i", 'r')
assert(ph.pid, "popen error while executing" .. TARANTOOL_PATH)

fiber.sleep(0.5)
ph:signal(popen.signal.SIGINT)
fiber.sleep(0.5)

local output = ph:read()
test:like(ph:info().status.state, popen.state.ALIVE, "process is still alive after SIGINT ")

ph:close()
print(output)
test:like(output, prompt .. " \n" .. prompt, "SIGINT doesn't kill tarantool on interactive mode ")
ph:close()

-- Check if daemon process exits after SIGINT

local phd = popen.shell(TARANTOOL_PATH .. " -e 'box.cfg{listen=3310, pid_file=\'file\'}
local fiber = require(\'fiber\') fiber.sleep(1)'", 'r')
assert(phd.pid, "popen error while executing" .. TARANTOOL_PATH)

fiber.sleep(0.5)
phd:signal(popen.signal.SIGINT)
fiber.sleep(0.5)

test:like(phd:info().status.state, popen.state.EXITED, "daemon process exited after SIGINT ")
phd:close()
end)
os.exit(res and 0 or 1)

0 comments on commit 63dccbf

Please sign in to comment.