From 5398f3a24e988da4836f78fba62acf2ead1030b0 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 4 Apr 2021 11:53:53 -0400 Subject: Call setsid() for hook/notification commands We do not want hook or notification commands to interact with the terminal in any way. Create a new session for them. Addresses GitHub issue #326. Signed-off-by: Lukas Fleischer --- src/calcurse.h | 4 ++-- src/hooks.c | 2 +- src/notify.c | 2 +- src/ui-day.c | 2 +- src/ui-todo.c | 2 +- src/utils.c | 17 ++++++++++++----- src/wins.c | 2 +- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/calcurse.h b/src/calcurse.h index ad6353c..d5ba355 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1250,8 +1250,8 @@ int parse_date_increment(const char *, unsigned *, time_t); int parse_datetime(const char *, time_t *, time_t); void file_close(FILE *, const char *); void psleep(unsigned); -int fork_exec(int *, int *, int *, const char *, const char *const *); -int shell_exec(int *, int *, int *, const char *, const char *const *); +int fork_exec(int *, int *, int *, int, const char *, const char *const *); +int shell_exec(int *, int *, int *, int, const char *, const char *const *); int child_wait(int *, int *, int *, int); void press_any_key(void); void print_apoint(const char *, time_t, struct apoint *); diff --git a/src/hooks.c b/src/hooks.c index 35d8a1a..7bfd548 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -51,7 +51,7 @@ int run_hook(const char *name) arg[0] = hook_path; arg[1] = NULL; - if ((pid = shell_exec(&pin, &pout, &perr, *arg, arg))) { + if ((pid = shell_exec(&pin, &pout, &perr, 1, *arg, arg))) { ret = child_wait(&pin, &pout, &perr, pid); if (ret > 0 && WIFEXITED(ret)) { asprintf(&mesg, "%s hook: exit status %d", diff --git a/src/notify.c b/src/notify.c index b73c369..3491e8e 100644 --- a/src/notify.c +++ b/src/notify.c @@ -221,7 +221,7 @@ unsigned notify_launch_cmd(void) notify_app.state |= APOINT_NOTIFIED; - if ((pid = shell_exec(&pin, &pout, &perr, *arg, arg))) { + if ((pid = shell_exec(&pin, &pout, &perr, 1, *arg, arg))) { close(pin); close(pout); close(perr); diff --git a/src/ui-day.c b/src/ui-day.c index 1848c2a..0bd82bb 100644 --- a/src/ui-day.c +++ b/src/ui-day.c @@ -1067,7 +1067,7 @@ void ui_day_item_pipe(void) return; wins_prepare_external(); - if ((pid = shell_exec(NULL, &pout, NULL, *arg, arg))) { + if ((pid = shell_exec(NULL, &pout, NULL, 0, *arg, arg))) { fpout = fdopen(pout, "w"); switch (p->type) { diff --git a/src/ui-todo.c b/src/ui-todo.c index 2c9bcb0..cad89fd 100644 --- a/src/ui-todo.c +++ b/src/ui-todo.c @@ -158,7 +158,7 @@ void ui_todo_pipe(void) return; wins_prepare_external(); - if ((pid = shell_exec(NULL, &pout, NULL, *arg, arg))) { + if ((pid = shell_exec(NULL, &pout, NULL, 0, *arg, arg))) { fpout = fdopen(pout, "w"); todo_write(item, fpout); fclose(fpout); diff --git a/src/utils.c b/src/utils.c index 146d733..1a480df 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1319,9 +1319,11 @@ void psleep(unsigned secs) * * If pfdin/pfdout/pfderr point to a valid address, a pipe is created and the * appropriate file descriptors are written to pfdin/pfdout/pfderr. + * + * If new_session is non-zero, setsid() is called after forking. */ -int fork_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, - const char *const *arg) +int fork_exec(int *pfdin, int *pfdout, int *pfderr, int new_session, + const char *path, const char *const *arg) { int pin[2], pout[2], perr[2]; int pid; @@ -1355,6 +1357,11 @@ int fork_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, close(pin[1]); } + if (new_session) { + if ((setsid() < 0)) + _exit(127); + } + execvp(path, (char *const *)arg); _exit(127); } else { @@ -1393,8 +1400,8 @@ int fork_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, /* Execute an external program in a shell. */ int -shell_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, - const char *const *arg) +shell_exec(int *pfdin, int *pfdout, int *pfderr, int new_session, + const char *path, const char *const *arg) { int argc, i; const char **narg; @@ -1423,7 +1430,7 @@ shell_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, narg[3] = NULL; } - ret = fork_exec(pfdin, pfdout, pfderr, *narg, narg); + ret = fork_exec(pfdin, pfdout, pfderr, new_session, *narg, narg); if (arg0) mem_free(arg0); diff --git a/src/wins.c b/src/wins.c index b03aa25..62689d9 100644 --- a/src/wins.c +++ b/src/wins.c @@ -624,7 +624,7 @@ void wins_launch_external(const char *arg[]) int pid; wins_prepare_external(); - if ((pid = shell_exec(NULL, NULL, NULL, *arg, arg))) + if ((pid = shell_exec(NULL, NULL, NULL, 0, *arg, arg))) child_wait(NULL, NULL, NULL, pid); wins_unprepare_external(); } -- cgit v1.2.3-54-g00ecf