HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

popen with array of arguments

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withpopenargumentsarray

Problem

It seems like there's no good library function I can use for popen with array of arguments instead of single shell-interpreted shell. So I implemented my own one: c h.

popen_arr.h

#pragma once

struct FILE;

// Implemented by Vitaly _Vi Shukela in 2013, License=MIT

/**
* Fork and exec the program, enabling stdio access to stdin and stdout of the program
* You may close opened streams with fclose.
* Note: the procedure does no signal handling except of signal(SIGPIPE, SIG_IGN);
* You should waitpid for the returned PID to collect the zombie or use signal(SIGCHLD, SIG_IGN);
*
* @arg in stdin of the program, to be written to. If NULL then not redirected
* @arg out stdout of the program, to be read from. If NULL then not redirected
* @arg program full path of the program, without reference to $PATH
* @arg argv NULL terminated array of strings, program arguments (includiong program name)
* @arg envp NULL terminated array of environment variables, NULL => preserve environment
* @return PID of the program or -1 if failed
*/
int popen2_arr (FILE** in, FILE** out, const char* program, const char* const argv[], const char* const envp[]);

/** like popen2_arr, but uses execvp/execvpe instead of execve/execv, so looks up $PATH */
int popen2_arr_p(FILE** in, FILE** out, const char* program, const char* const argv[], const char* const envp[]);

/**
* Simplified interface to popen2_arr.
* You may close the returned stream with fclose.
* Note: the procedure does no signal handling except of signal(SIGPIPE, SIG_IGN);
* You should wait(2) after closing the descriptor to collect zombie process or use signal(SIGCHLD, SIG_IGN)
*
* @arg program program name, can rely on $PATH
* @arg argv program arguments, NULL-terminated const char* array
* @arg pipe_into_program 1 to be like popen(...,"w"), 0 to be like popen(...,"r")
* @return FILE* instance or NULL if error
*/
FILE* popen_arr(const char* program, const char* const argv[], int pipe_into_program);


popen_arr.c

```
#define _

Solution

The function popen_arr would resemble popen more closely if it
took a 'mode' parameter in the same way, instead of your pipe_into_program:

FILE* popen_arr(const char* program,
                const char* const argv[], 
                const char *mode);


where mode is "r", "w" or "r+".

And popen manages bidirectional operation using just one FILE * whereas
your popen2_* functions take two.

Personally, I would simplify things by omitting the environment parameters.

The bidirectional link you create is perhaps easier to create with
socketpair.

fdopen failure is caught in the if(in) case but not in the if(out)
case.

You also need an analogue of pclose that closes the pipes and waits for the
child process to exit (using wait etc).

You also omit any handling of SIGCHLD, which is sent of the death of the child process.

On your formatting, your spacing is inconsistent and there is often
insufficient spacing, eg around operators (=, != etc) and after keywords (eg
after if).

Code Snippets

FILE* popen_arr(const char* program,
                const char* const argv[], 
                const char *mode);

Context

StackExchange Code Review Q#31063, answer score: 2

Revisions (0)

No revisions yet.