From 193ad3415a0e76bf046bfcc3f03dd65742f18589 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 4 Apr 2021 11:26:46 -0400 Subject: Redirect standard descriptors for hook/notify commands Disconnect stdin, stdout and stderr when running an external hook or notification command. The previous solution of appending "<&- >&- 2>&-" to the shell command line does not work if the command includes pipes. Use shell_exec() in notify_launch_cmd() instead of a custom (and incomplete) reimplementation of that command. Partially addresses GitHub issue #326. Signed-off-by: Lukas Fleischer --- src/calcurse.h | 1 - src/hooks.c | 13 +++++-------- src/notify.c | 23 ++++++----------------- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/calcurse.h b/src/calcurse.h index b006a77..ad6353c 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -671,7 +671,6 @@ struct nbar { char datefmt[BUFSIZ]; /* format for displaying date */ char timefmt[BUFSIZ]; /* format for displaying time */ char cmd[BUFSIZ]; /* notification command */ - const char *shell; /* user shell to launch notif. cmd */ unsigned notify_all; /* notify all appointments */ pthread_mutex_t mutex; }; diff --git a/src/hooks.c b/src/hooks.c index cf1db5e..35d8a1a 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -41,20 +41,18 @@ int run_hook(const char *name) { - char *hook_path = NULL, *hook_cmd = NULL, *mesg; + char *hook_path = NULL, *mesg; + int pid, pin, pout, perr, ret = -127; char const *arg[2]; - int pid, ret = -127; asprintf(&hook_path, "%s/%s", path_hooks, name); if (!io_file_exists(hook_path)) goto cleanup; - - asprintf(&hook_cmd, "%s <&- >&- 2>&-", hook_path); - arg[0] = hook_cmd; + arg[0] = hook_path; arg[1] = NULL; - if ((pid = shell_exec(NULL, NULL, NULL, *arg, arg))) { - ret = child_wait(NULL, NULL, NULL, pid); + if ((pid = shell_exec(&pin, &pout, &perr, *arg, arg))) { + ret = child_wait(&pin, &pout, &perr, pid); if (ret > 0 && WIFEXITED(ret)) { asprintf(&mesg, "%s hook: exit status %d", name, @@ -71,6 +69,5 @@ int run_hook(const char *name) cleanup: mem_free(hook_path); - mem_free(hook_cmd); return ret; } diff --git a/src/notify.c b/src/notify.c index 036af0f..b73c369 100644 --- a/src/notify.c +++ b/src/notify.c @@ -137,9 +137,6 @@ void notify_init_vars(void) strncpy(nbar.cmd, cmd, BUFSIZ); nbar.cmd[BUFSIZ - 1] = '\0'; - if ((nbar.shell = getenv("SHELL")) == NULL) - nbar.shell = "/bin/sh"; - nbar.notify_all = 0; pthread_attr_init(&detached_thread_attr); @@ -216,26 +213,18 @@ void notify_reinit_bar(void) /* Launch user defined command as a notification. */ unsigned notify_launch_cmd(void) { - int pid; + char const *arg[2] = { nbar.cmd, NULL }; + int pid, pin, pout, perr; if (notify_app.state & APOINT_NOTIFIED) return 1; notify_app.state |= APOINT_NOTIFIED; - pid = fork(); - - if (pid < 0) { - ERROR_MSG(_("error while launching command: could not fork")); - return 0; - } else if (pid == 0) { - /* Child: launch user defined command */ - if (execlp(nbar.shell, nbar.shell, "-c", nbar.cmd, NULL) < - 0) { - ERROR_MSG(_("error while launching command")); - _exit(1); - } - _exit(0); + if ((pid = shell_exec(&pin, &pout, &perr, *arg, arg))) { + close(pin); + close(pout); + close(perr); } return 1; -- cgit v1.2.3-54-g00ecf