Repository: celix Updated Branches: refs/heads/develop 2a50dd28c -> 000259361
Fixed messed-up terminal by shell when celix does not exit normally. Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/00025936 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/00025936 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/00025936 Branch: refs/heads/develop Commit: 000259361ec8a67a811da181763ecb9b562e5386 Parents: 2a50dd2 Author: Erjan Altena <[email protected]> Authored: Wed Mar 28 20:14:38 2018 +0200 Committer: Erjan Altena <[email protected]> Committed: Wed Mar 28 20:14:38 2018 +0200 ---------------------------------------------------------------------- shell_tui/private/src/shell_tui.c | 54 ++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/00025936/shell_tui/private/src/shell_tui.c ---------------------------------------------------------------------- diff --git a/shell_tui/private/src/shell_tui.c b/shell_tui/private/src/shell_tui.c index 28bedaa..2ceb21a 100644 --- a/shell_tui/private/src/shell_tui.c +++ b/shell_tui/private/src/shell_tui.c @@ -73,17 +73,30 @@ typedef struct shell_context { history_t* hist; } shell_context_t; +struct OriginalSettings { + struct termios term_org; + struct sigaction oldSigIntAction; + struct sigaction oldSigSegvAction; + struct sigaction oldSigAbrtAction; + struct sigaction oldSigQuitAction; + +}; + // static function declarations static void remove_newlines(char* line); static void clearLine(); static void cursorLeft(int n); static void writeLine(const char*line, int pos); static int autoComplete(shell_service_pt shellSvc, char *in, int cursorPos, size_t maxLen); +static void shellSigHandler(int sig, siginfo_t *info, void* ptr); static void* shellTui_runnable(void *data); static void shellTui_parseInputForControl(shell_tui_t* shellTui, shell_context_t* ctx); static void shellTui_parseInput(shell_tui_t* shellTui, shell_context_t* ctx); static void writePrompt(void); +// Unfortunately has to be static, it is not possible to pass user defined data to the handler +static struct OriginalSettings originalSettings; + shell_tui_t* shellTui_create(bool useAnsiControlSequences) { shell_tui_t* result = calloc(1, sizeof(*result)); if (result != NULL) { @@ -139,6 +152,19 @@ celix_status_t shellTui_setShell(shell_tui_t* shellTui, shell_service_t* svc) { return CELIX_SUCCESS; } +static void shellSigHandler(int sig, siginfo_t *info, void* ptr) { + tcsetattr(STDIN_FILENO, TCSANOW, &originalSettings.term_org); + if (sig == SIGINT) { + originalSettings.oldSigIntAction.sa_sigaction(sig, info, ptr); + } else if (sig == SIGSEGV){ + originalSettings.oldSigSegvAction.sa_sigaction(sig, info, ptr); + } else if (sig == SIGABRT){ + originalSettings.oldSigAbrtAction.sa_sigaction(sig, info, ptr); + } else if (sig == SIGQUIT){ + originalSettings.oldSigQuitAction.sa_sigaction(sig, info, ptr); + } +} + static void* shellTui_runnable(void *data) { shell_tui_t* shellTui = (shell_tui_t*) data; @@ -147,12 +173,24 @@ static void* shellTui_runnable(void *data) { memset(&ctx, 0, sizeof(ctx)); ctx.hist = historyCreate(); - struct termios term_org, term_new; + struct termios term_new; if (shellTui->useAnsiControlSequences) { - tcgetattr(STDIN_FILENO, &term_org); - - - term_new = term_org; + sigaction(SIGINT, NULL, &originalSettings.oldSigIntAction); + sigaction(SIGSEGV, NULL, &originalSettings.oldSigSegvAction); + sigaction(SIGABRT, NULL, &originalSettings.oldSigAbrtAction); + sigaction(SIGQUIT, NULL, &originalSettings.oldSigQuitAction); + struct sigaction newAction; + memset(&newAction, 0, sizeof(newAction)); + newAction.sa_flags = SA_SIGINFO; + newAction.sa_sigaction = shellSigHandler; + sigaction(SIGINT, &newAction, NULL); + sigaction(SIGSEGV, &newAction, NULL); + sigaction(SIGABRT, &newAction, NULL); + sigaction(SIGQUIT, &newAction, NULL); + tcgetattr(STDIN_FILENO, &originalSettings.term_org); + + + term_new = originalSettings.term_org; term_new.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term_new); } @@ -186,7 +224,11 @@ static void* shellTui_runnable(void *data) { historyDestroy(ctx.hist); if (shellTui->useAnsiControlSequences) { - tcsetattr(STDIN_FILENO, TCSANOW, &term_org); + tcsetattr(STDIN_FILENO, TCSANOW, &originalSettings.term_org); + sigaction(SIGINT, &originalSettings.oldSigIntAction, NULL); + sigaction(SIGSEGV, &originalSettings.oldSigSegvAction, NULL); + sigaction(SIGABRT, &originalSettings.oldSigAbrtAction, NULL); + sigaction(SIGQUIT, &originalSettings.oldSigQuitAction, NULL); }
