[PATCH 4/6] pipeio: Add fwts_pipe_open_rw
Jeremy Kerr
jk at ozlabs.org
Fri Apr 22 05:41:10 UTC 2016
This change introduces a function to open a process pipe that supports
both reading and writing (ie, we open pipes for both stdin and stdout of
the child process).
We do this by extending and renaming the existing fwts_pipe_open_ro,
then use the new function to implement fwts_pipe_open_ro.
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
---
src/lib/include/fwts_pipeio.h | 2 ++
src/lib/src/fwts_pipeio.c | 74 ++++++++++++++++++++++++++++++++++---------
2 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/src/lib/include/fwts_pipeio.h b/src/lib/include/fwts_pipeio.h
index e27d90b..e2d498a 100644
--- a/src/lib/include/fwts_pipeio.h
+++ b/src/lib/include/fwts_pipeio.h
@@ -31,6 +31,8 @@
#define FWTS_EXEC_ERROR (127)
int fwts_pipe_open_ro(const char *command, pid_t *childpid, int *fd);
+int fwts_pipe_open_rw(const char *command, pid_t *childpid, int *in_fd,
+ int *out_fd);
int fwts_pipe_read(const int fd, char **out_buf, ssize_t *out_len);
int fwts_pipe_close(const int fd, const pid_t pid);
int fwts_pipe_exec(const char *command, fwts_list **list, int *status);
diff --git a/src/lib/src/fwts_pipeio.c b/src/lib/src/fwts_pipeio.c
index 64fc91d..bb51515 100644
--- a/src/lib/src/fwts_pipeio.c
+++ b/src/lib/src/fwts_pipeio.c
@@ -24,6 +24,7 @@
#include <signal.h>
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -40,48 +41,91 @@
#include "fwts.h"
/*
- * fwts_pipe_open_ro()
+ * fwts_pipe_open_rw()
* execl a command, return pid in *childpid and a pipe connected
- * to stdout in *fd. Return value < 0 indicates error.
+ * to stdout in *in_fd, and stdout in *out_fd. Return value < 0
+ * indicates error.
*/
-int fwts_pipe_open_ro(const char *command, pid_t *childpid, int *fd)
+int fwts_pipe_open_rw(const char *command, pid_t *childpid,
+ int *in_fd, int *out_fd)
{
- int pipefds[2];
+ int out_pipefds[2];
+ int in_pipefds[2];
pid_t pid;
FILE *fp;
- if (pipe(pipefds) < 0)
- return -1;
+ if (in_fd != NULL) {
+ if (pipe(in_pipefds) < 0)
+ return -1;
+ } else {
+ in_pipefds[0] = open("/dev/null", O_RDONLY);
+ in_pipefds[1] = -1;
+ }
+
+ if (out_fd != NULL) {
+ if (pipe(out_pipefds) < 0)
+ goto err_close_in;
+ } else {
+ out_pipefds[0] = -1;
+ out_pipefds[1] = open("/dev/null", O_WRONLY);
+ }
pid = fork();
switch (pid) {
case -1:
/* Ooops */
- close(pipefds[0]);
- close(pipefds[1]);
- return -1;
+ goto err_close_out;
case 0:
/* Child */
if ((fp = freopen("/dev/null", "w", stderr)) == NULL) {
fprintf(stderr, "Cannot redirect stderr\n");
}
- if (pipefds[0] != STDOUT_FILENO) {
- dup2(pipefds[1], STDOUT_FILENO);
- close(pipefds[1]);
+ if (out_pipefds[0] != STDOUT_FILENO) {
+ dup2(out_pipefds[1], STDOUT_FILENO);
+ close(out_pipefds[1]);
}
- close(pipefds[0]);
+ if (in_pipefds[1] != STDIN_FILENO) {
+ dup2(in_pipefds[0], STDIN_FILENO);
+ close(in_pipefds[0]);
+ }
+
+ close(out_pipefds[0]);
+ close(in_pipefds[1]);
execl(_PATH_BSHELL, "sh", "-c", command, NULL);
if (fp)
fclose(fp);
_exit(FWTS_EXEC_ERROR);
default:
/* Parent */
- close(pipefds[1]);
+ close(out_pipefds[1]);
+ close(in_pipefds[0]);
+
*childpid = pid;
- *fd = pipefds[0];
+ if (out_fd)
+ *out_fd = out_pipefds[0];
+ if (in_fd)
+ *in_fd = in_pipefds[1];
return 0;
}
+
+err_close_in:
+ close(in_pipefds[0]);
+ close(in_pipefds[1]);
+err_close_out:
+ close(out_pipefds[0]);
+ close(out_pipefds[1]);
+ return -1;
+}
+
+/*
+ * fwts_pipe_open_ro()
+ * execl a command, return pid in *childpid and a pipe connected
+ * to stdout in *fd. Return value < 0 indicates error.
+ */
+int fwts_pipe_open_ro(const char *command, pid_t *childpid, int *fd)
+{
+ return fwts_pipe_open_rw(command, childpid, NULL, fd);
}
/*
--
2.5.0
More information about the fwts-devel
mailing list