aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@calcurse.org>2021-04-04 11:26:46 -0400
committerLukas Fleischer <lfleischer@calcurse.org>2021-04-04 12:15:31 -0400
commit193ad3415a0e76bf046bfcc3f03dd65742f18589 (patch)
tree8886dda7957bf024a0404c7834fb6fb0d43ade11
parent5710a8bd7fc3d5a3e46f108c16199ed7553515f0 (diff)
downloadcalcurse-193ad3415a0e76bf046bfcc3f03dd65742f18589.tar.gz
calcurse-193ad3415a0e76bf046bfcc3f03dd65742f18589.zip
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 <lfleischer@calcurse.org>
-rw-r--r--src/calcurse.h1
-rw-r--r--src/hooks.c13
-rw-r--r--src/notify.c23
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;