From 5710a8bd7fc3d5a3e46f108c16199ed7553515f0 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 4 Apr 2021 10:43:26 -0400 Subject: Add parameter to redirect stderr to shell_exec() Add a function parameter to allows redirecting stderr in addition to stdin and stdout. The parameter will be used with a follow-up change. Signed-off-by: Lukas Fleischer --- src/calcurse.h | 6 +++--- src/hooks.c | 4 ++-- src/ui-day.c | 4 ++-- src/ui-todo.c | 4 ++-- src/utils.c | 33 ++++++++++++++++++++++++++------- src/wins.c | 4 ++-- 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/calcurse.h b/src/calcurse.h index bd351d6..b006a77 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1251,9 +1251,9 @@ 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 *, const char *, const char *const *); -int shell_exec(int *, int *, const char *, const char *const *); -int child_wait(int *, int *, int); +int fork_exec(int *, int *, int *, const char *, const char *const *); +int shell_exec(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 *); void print_event(const char *, time_t, struct event *); diff --git a/src/hooks.c b/src/hooks.c index b4933af..cf1db5e 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -53,8 +53,8 @@ int run_hook(const char *name) arg[0] = hook_cmd; arg[1] = NULL; - if ((pid = shell_exec(NULL, NULL, *arg, arg))) { - ret = child_wait(NULL, NULL, pid); + if ((pid = shell_exec(NULL, NULL, NULL, *arg, arg))) { + ret = child_wait(NULL, NULL, NULL, pid); if (ret > 0 && WIFEXITED(ret)) { asprintf(&mesg, "%s hook: exit status %d", name, diff --git a/src/ui-day.c b/src/ui-day.c index ae810ed..1848c2a 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, *arg, arg))) { + if ((pid = shell_exec(NULL, &pout, NULL, *arg, arg))) { fpout = fdopen(pout, "w"); switch (p->type) { @@ -1088,7 +1088,7 @@ void ui_day_item_pipe(void) } fclose(fpout); - child_wait(NULL, &pout, pid); + child_wait(NULL, &pout, NULL, pid); press_any_key(); } wins_unprepare_external(); diff --git a/src/ui-todo.c b/src/ui-todo.c index 876f570..2c9bcb0 100644 --- a/src/ui-todo.c +++ b/src/ui-todo.c @@ -158,11 +158,11 @@ void ui_todo_pipe(void) return; wins_prepare_external(); - if ((pid = shell_exec(NULL, &pout, *arg, arg))) { + if ((pid = shell_exec(NULL, &pout, NULL, *arg, arg))) { fpout = fdopen(pout, "w"); todo_write(item, fpout); fclose(fpout); - child_wait(NULL, &pout, pid); + child_wait(NULL, &pout, NULL, pid); press_any_key(); } wins_unprepare_external(); diff --git a/src/utils.c b/src/utils.c index 114a985..146d733 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1317,21 +1317,30 @@ void psleep(unsigned secs) /* * Fork and execute an external process. * - * If pfdin and/or pfdout point to a valid address, a pipe is created and the - * appropriate file descriptors are written to pfdin/pfdout. + * If pfdin/pfdout/pfderr point to a valid address, a pipe is created and the + * appropriate file descriptors are written to pfdin/pfdout/pfderr. */ -int fork_exec(int *pfdin, int *pfdout, const char *path, +int fork_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, const char *const *arg) { - int pin[2], pout[2]; + int pin[2], pout[2], perr[2]; int pid; if (pfdin && (pipe(pin) == -1)) return 0; if (pfdout && (pipe(pout) == -1)) return 0; + if (pfderr && (pipe(perr) == -1)) + return 0; if ((pid = fork()) == 0) { + if (pfderr) { + if (dup2(perr[0], STDERR_FILENO) < 0) + _exit(127); + close(perr[0]); + close(perr[1]); + } + if (pfdout) { if (dup2(pout[0], STDIN_FILENO) < 0) _exit(127); @@ -1353,6 +1362,8 @@ int fork_exec(int *pfdin, int *pfdout, const char *path, close(pin[1]); if (pfdout) close(pout[0]); + if (pfderr) + close(perr[0]); if (pid > 0) { if (pfdin) { @@ -1363,11 +1374,17 @@ int fork_exec(int *pfdin, int *pfdout, const char *path, fcntl(pout[1], F_SETFD, FD_CLOEXEC); *pfdout = pout[1]; } + if (pfderr) { + fcntl(perr[1], F_SETFD, FD_CLOEXEC); + *pfderr = perr[1]; + } } else { if (pfdin) close(pin[0]); if (pfdout) close(pout[1]); + if (pfderr) + close(perr[1]); return 0; } } @@ -1376,7 +1393,7 @@ int fork_exec(int *pfdin, int *pfdout, const char *path, /* Execute an external program in a shell. */ int -shell_exec(int *pfdin, int *pfdout, const char *path, +shell_exec(int *pfdin, int *pfdout, int *pfderr, const char *path, const char *const *arg) { int argc, i; @@ -1406,7 +1423,7 @@ shell_exec(int *pfdin, int *pfdout, const char *path, narg[3] = NULL; } - ret = fork_exec(pfdin, pfdout, *narg, narg); + ret = fork_exec(pfdin, pfdout, pfderr, *narg, narg); if (arg0) mem_free(arg0); @@ -1416,7 +1433,7 @@ shell_exec(int *pfdin, int *pfdout, const char *path, } /* Wait for a child process to terminate. */ -int child_wait(int *pfdin, int *pfdout, int pid) +int child_wait(int *pfdin, int *pfdout, int *pfderr, int pid) { int stat; @@ -1424,6 +1441,8 @@ int child_wait(int *pfdin, int *pfdout, int pid) close(*pfdin); if (pfdout) close(*pfdout); + if (pfderr) + close(*pfderr); if (waitpid(pid, &stat, 0) == pid) return stat; diff --git a/src/wins.c b/src/wins.c index bc7e05b..b03aa25 100644 --- a/src/wins.c +++ b/src/wins.c @@ -624,8 +624,8 @@ void wins_launch_external(const char *arg[]) int pid; wins_prepare_external(); - if ((pid = shell_exec(NULL, NULL, *arg, arg))) - child_wait(NULL, NULL, pid); + if ((pid = shell_exec(NULL, NULL, NULL, *arg, arg))) + child_wait(NULL, NULL, NULL, pid); wins_unprepare_external(); } -- cgit v1.2.3-70-g09d2