server: Improve signal handling under Linux
Commit5087a955
added custom signal handlers for the openocd server process. Before this commit, when openocd is run as a background process having the same controlling terminal as gdb, Control-C would be handled by gdb to stop target execution and return to the gdb prompt. However, after commit5087a955
, the SIGINT caused by pressing Control-C also terminates openocd, effectively crashing the debugging session. The only way to avoid this is run openocd in a different controling terminal or to detach openocd from its controlling terminal, thus losing all job control for the openocd process. This patch improves the server's handling of POSIX signals: 1) Keyboard generated signals (INT and QUIT) are ignored when server process has is no controlling terminal. 2) SIGHUP and SIGPIPE are handled to ensure that .quit functions for each interface are called if user's logs out of X session or there is a network failure. SIG_INT & SIG_QUIT still stop openocd when it is running in the foreground. Change-Id: I03ad645e62408fdaf4edc49a3550b89b287eda10 Signed-off-by: Brent Roman <genosensor@gmail.com> Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/3963 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
e59bb6c285
commit
c584686fd1
|
@ -505,7 +505,7 @@ int server_loop(struct command_context *command_context)
|
||||||
for (service = services; service; service = service->next) {
|
for (service = services; service; service = service->next) {
|
||||||
/* handle new connections on listeners */
|
/* handle new connections on listeners */
|
||||||
if ((service->fd != -1)
|
if ((service->fd != -1)
|
||||||
&& (FD_ISSET(service->fd, &read_fds))) {
|
&& (FD_ISSET(service->fd, &read_fds))) {
|
||||||
if (service->max_connections != 0)
|
if (service->max_connections != 0)
|
||||||
add_connection(service, command_context);
|
add_connection(service, command_context);
|
||||||
else {
|
else {
|
||||||
|
@ -563,21 +563,36 @@ int server_loop(struct command_context *command_context)
|
||||||
return shutdown_openocd != 2 ? ERROR_OK : ERROR_FAIL;
|
return shutdown_openocd != 2 ? ERROR_OK : ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sig_handler(int sig)
|
||||||
|
{
|
||||||
|
/* store only first signal that hits us */
|
||||||
|
if (!shutdown_openocd) {
|
||||||
|
last_signal = sig;
|
||||||
|
shutdown_openocd = 1;
|
||||||
|
LOG_DEBUG("Terminating on Signal %d", sig);
|
||||||
|
} else
|
||||||
|
LOG_DEBUG("Ignored extra Signal %d", sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
|
BOOL WINAPI ControlHandler(DWORD dwCtrlType)
|
||||||
{
|
{
|
||||||
shutdown_openocd = 1;
|
shutdown_openocd = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static void sigkey_handler(int sig)
|
||||||
|
{
|
||||||
|
/* ignore keystroke generated signals if not in foreground process group */
|
||||||
|
|
||||||
|
if (tcgetpgrp(STDIN_FILENO) > 0)
|
||||||
|
sig_handler(sig);
|
||||||
|
else
|
||||||
|
LOG_DEBUG("Ignored Signal %d", sig);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void sig_handler(int sig)
|
|
||||||
{
|
|
||||||
/* store only first signal that hits us */
|
|
||||||
if (!last_signal)
|
|
||||||
last_signal = sig;
|
|
||||||
shutdown_openocd = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int server_preinit(void)
|
int server_preinit(void)
|
||||||
{
|
{
|
||||||
|
@ -600,8 +615,13 @@ int server_preinit(void)
|
||||||
SetConsoleCtrlHandler(ControlHandler, TRUE);
|
SetConsoleCtrlHandler(ControlHandler, TRUE);
|
||||||
|
|
||||||
signal(SIGBREAK, sig_handler);
|
signal(SIGBREAK, sig_handler);
|
||||||
#endif
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
#else
|
||||||
|
signal(SIGHUP, sig_handler);
|
||||||
|
signal(SIGPIPE, sig_handler);
|
||||||
|
signal(SIGQUIT, sigkey_handler);
|
||||||
|
signal(SIGINT, sigkey_handler);
|
||||||
|
#endif
|
||||||
signal(SIGTERM, sig_handler);
|
signal(SIGTERM, sig_handler);
|
||||||
signal(SIGABRT, sig_handler);
|
signal(SIGABRT, sig_handler);
|
||||||
|
|
||||||
|
@ -743,7 +763,7 @@ static const struct command_registration server_command_handlers[] = {
|
||||||
.mode = COMMAND_ANY,
|
.mode = COMMAND_ANY,
|
||||||
.usage = "[name]",
|
.usage = "[name]",
|
||||||
.help = "Specify address by name on which to listen for "
|
.help = "Specify address by name on which to listen for "
|
||||||
"incoming TCP/IP connections",
|
"incoming TCP/IP connections",
|
||||||
},
|
},
|
||||||
COMMAND_REGISTRATION_DONE
|
COMMAND_REGISTRATION_DONE
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue