|
@@ -19,6 +19,13 @@
|
|
|
#include <signal.h>
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
+
|
|
|
+static void sigignore(int signo)
|
|
|
+{
|
|
|
+ signo = signo;
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
static int clish_shell_lock(const char *lock_path)
|
|
|
{
|
|
@@ -87,8 +94,6 @@ int clish_shell_execute(clish_context_t *context, char **out)
|
|
|
int result = 0;
|
|
|
char *lock_path = clish_shell__get_lockfile(this);
|
|
|
int lock_fd = -1;
|
|
|
- sigset_t old_sigs;
|
|
|
- struct sigaction old_sigint, old_sigquit, old_sighup;
|
|
|
clish_view_t *cur_view = clish_shell__get_view(this);
|
|
|
unsigned int saved_wdog_timeout = this->wdog_timeout;
|
|
|
|
|
@@ -116,42 +121,10 @@ int clish_shell_execute(clish_context_t *context, char **out)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- if (!clish_command__get_interrupt(cmd)) {
|
|
|
- struct sigaction sa;
|
|
|
- sigset_t sigs;
|
|
|
- sa.sa_flags = 0;
|
|
|
- sigemptyset(&sa.sa_mask);
|
|
|
- sa.sa_handler = SIG_IGN;
|
|
|
- sigaction(SIGINT, &sa, &old_sigint);
|
|
|
- sigaction(SIGQUIT, &sa, &old_sigquit);
|
|
|
- sigaction(SIGHUP, &sa, &old_sighup);
|
|
|
- sigemptyset(&sigs);
|
|
|
- sigaddset(&sigs, SIGINT);
|
|
|
- sigaddset(&sigs, SIGQUIT);
|
|
|
- sigaddset(&sigs, SIGHUP);
|
|
|
- sigprocmask(SIG_BLOCK, &sigs, &old_sigs);
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
clish_context__set_action(context, clish_command__get_action(cmd));
|
|
|
- result = clish_shell_exec_action(context, out);
|
|
|
-
|
|
|
-
|
|
|
- if (!clish_command__get_interrupt(cmd)) {
|
|
|
- sigprocmask(SIG_SETMASK, &old_sigs, NULL);
|
|
|
-
|
|
|
- sigaction restore) for previously blocked and
|
|
|
- pending signals? The simple test is working well.
|
|
|
- I don't want to use sigtimedwait() function bacause
|
|
|
- it needs a realtime extensions. The sigpending() with
|
|
|
- the sleep() is not nice too. Report bug if clish will
|
|
|
- get the SIGINT after non-interruptable action.
|
|
|
- */
|
|
|
- sigaction(SIGINT, &old_sigint, NULL);
|
|
|
- sigaction(SIGQUIT, &old_sigquit, NULL);
|
|
|
- sigaction(SIGHUP, &old_sighup, NULL);
|
|
|
- }
|
|
|
+ result = clish_shell_exec_action(context, out,
|
|
|
+ clish_command__get_interrupt(cmd));
|
|
|
|
|
|
|
|
|
if (!result)
|
|
@@ -310,7 +283,7 @@ stdout_error:
|
|
|
}
|
|
|
|
|
|
|
|
|
-int clish_shell_exec_action(clish_context_t *context, char **out)
|
|
|
+int clish_shell_exec_action(clish_context_t *context, char **out, bool_t intr)
|
|
|
{
|
|
|
int result = -1;
|
|
|
clish_sym_t *sym;
|
|
@@ -318,6 +291,10 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
|
|
|
void *func = NULL;
|
|
|
const clish_action_t *action = clish_context__get_action(context);
|
|
|
clish_shell_t *shell = clish_context__get_shell(context);
|
|
|
+
|
|
|
+ struct sigaction old_sigint, old_sigquit, old_sighup;
|
|
|
+ struct sigaction sa;
|
|
|
+ sigset_t old_sigs;
|
|
|
|
|
|
if (!(sym = clish_action__get_builtin(action)))
|
|
|
return 0;
|
|
@@ -329,6 +306,27 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
|
|
|
}
|
|
|
script = clish_shell_expand(clish_action__get_script(action), SHELL_VAR_ACTION, context);
|
|
|
|
|
|
+
|
|
|
+ * The SIG_IGN is not a case because it will be inherited
|
|
|
+ * while a fork(). It's necessary to ignore signals because
|
|
|
+ * the klish itself and ACTION script share the same terminal.
|
|
|
+ */
|
|
|
+ sa.sa_flags = 0;
|
|
|
+ sigemptyset(&sa.sa_mask);
|
|
|
+ sa.sa_handler = sigignore;
|
|
|
+ sigaction(SIGINT, &sa, &old_sigint);
|
|
|
+ sigaction(SIGQUIT, &sa, &old_sigquit);
|
|
|
+ sigaction(SIGHUP, &sa, &old_sighup);
|
|
|
+
|
|
|
+ if (!intr) {
|
|
|
+ sigset_t sigs;
|
|
|
+ sigemptyset(&sigs);
|
|
|
+ sigaddset(&sigs, SIGINT);
|
|
|
+ sigaddset(&sigs, SIGQUIT);
|
|
|
+ sigaddset(&sigs, SIGHUP);
|
|
|
+ sigprocmask(SIG_BLOCK, &sigs, &old_sigs);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
if (clish_sym__get_api(sym) == CLISH_SYM_API_SIMPLE) {
|
|
@@ -344,6 +342,22 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
|
|
|
context, script, out);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ if (!intr) {
|
|
|
+ sigprocmask(SIG_SETMASK, &old_sigs, NULL);
|
|
|
+
|
|
|
+ sigaction restore) for previously blocked and
|
|
|
+ pending signals? The simple test is working well.
|
|
|
+ I don't want to use sigtimedwait() function because
|
|
|
+ it needs a realtime extensions. The sigpending() with
|
|
|
+ the sleep() is not nice too. Report bug if clish will
|
|
|
+ get the SIGINT after non-interruptable action.
|
|
|
+ */
|
|
|
+ }
|
|
|
+ sigaction(SIGINT, &old_sigint, NULL);
|
|
|
+ sigaction(SIGQUIT, &old_sigquit, NULL);
|
|
|
+ sigaction(SIGHUP, &old_sighup, NULL);
|
|
|
+
|
|
|
lub_string_free(script);
|
|
|
|
|
|
return result;
|