aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@calcurse.org>2021-04-04 10:43:26 -0400
committerLukas Fleischer <lfleischer@calcurse.org>2021-04-04 12:15:26 -0400
commit5710a8bd7fc3d5a3e46f108c16199ed7553515f0 (patch)
tree456e0ed7aeff549d0177f02f225821c4edde9b12 /src
parentf41955e491476dfb844f28f46523d0430d27c88a (diff)
downloadcalcurse-5710a8bd7fc3d5a3e46f108c16199ed7553515f0.tar.gz
calcurse-5710a8bd7fc3d5a3e46f108c16199ed7553515f0.zip
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 <lfleischer@calcurse.org>
Diffstat (limited to 'src')
-rw-r--r--src/calcurse.h6
-rw-r--r--src/hooks.c4
-rw-r--r--src/ui-day.c4
-rw-r--r--src/ui-todo.c4
-rw-r--r--src/utils.c33
-rw-r--r--src/wins.c4
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();
}