1

system/popen - 可移植,但使用 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 中读取其输出的最佳方法是什么?是否有任何非臃肿的包装器?

4

2 回答 2

2

我自己实现了这样的包装器: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);
于 2013-09-08T21:49:24.473 回答
1

不,没有。ISO C 除了通过system. system除了,popenfork(+vfork在 POSIX.2008 之前)之外, POSIX 没有其他方法可以启动进程。

于 2013-09-08T14:50:19.733 回答