ACK: [PATCH 4/6] pipeio: Add fwts_pipe_open_rw

Alex Hung alex.hung at canonical.com
Wed Apr 27 04:31:36 UTC 2016


On 2016-04-22 01:41 PM, Jeremy Kerr wrote:
> 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);
>   }
>
>   /*
>


Acked-by: Alex Hung <alex.hung at canonical.com>



More information about the fwts-devel mailing list