如何移植使用系统或popen,但有参数数组?

时间:2013-09-08 14:47:30

标签: c popen argv

system / popen - portable,但使用shell - 一个字符串参数

pipe + fork + dup2 + exec - 更多代码,更不便携,但可以指定数组。

中间有什么简单的东西吗?期待像:

const char* args = {"/usr/bin/myprogram", "myprogram", "--option", NULL};
FILE* outfile = popen_read_end_args(args);
fscanf(outfile, "...");
fclose(outfile);

使用数组调用外部程序并在C中读取其输出的最佳方法是什么?是否有任何非浮动包装?

2 个答案:

答案 0 :(得分:1)

不,没有。除了system之外,ISO C没有其他方式来启动新流程。在POSIX.2008之前,POSIX没有其他方式启动流程,而不是systempopenfork(+ vfork)。

答案 1 :(得分:1)

我自己实现了这样的包装:https://github.com/vi/udpserv/blob/master/popen_arr.c

这是头文件:

/**
* For 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* argv[], const char* 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* argv[], const char* 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* argv[], int pipe_into_program);