现在,我必须在C中启动外部进程。我目前正在使用posix_spawn来创建进程。我有必要监控过程是否已经终止。我还需要有一个标准的链接。我看过使用popen,然而,它并没有提供一个“简单”的方式获得pid。我慢慢疯了,因为在Linux中运行进程的stdout可能不会很难。
此外,还有一点,我需要帮助解密file_actions参数应该是什么意思。关于这个主题的posix_spawn的man(3)说:
如果file_actions不为NULL,那么在子进程中打开的文件描述符应该是在调用进程中打开的文件描述符,由file_actions指向的spawn文件操作对象和每个剩余的打开文件描述符的FD_CLOEXEC标志修改后。已经处理了spawn文件操作。
如果这不是一个连续句子的定义,我不知道是什么。
答案 0 :(得分:6)
由于您拥有PID(从posix_spawn
返回)并且您正在运行Linux,因此您将在/proc/<pid>/fd/1
找到该过程的标准输出。只需open
(或fopen
)文件即可阅读。
标准方法是使用fork
。使用pipe
和dup2
获取用于读取子项输出的文件描述符,如this question中所示。
答案 1 :(得分:3)
您可以使用posix_spawn,而不必使用易受竞争条件影响的特定于Linux的/proc/<pid>/fd/N
。你可以保留posix_spawn的所有好处。
你正在思考file_actions
。下面是一个示例,它使用posix_spawn和file_actions从父进程打印出Python样式的三引号中的子标题以及子函数的退出代码。
以下是示例输出的示例。
child pid: 17468
child exit status: 0
child stdout:
"""Hello World!
"""
以下是示例。
#define _DEFAULT_SOURCE
#include <spawn.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
extern char **environ;
static void dump_child_stdout(int filedes)
{
ssize_t num_read;
char buf[1];
printf("child stdout:\n\"\"\"");
for (;;)
{
num_read = read(filedes, buf, sizeof(buf));
if (num_read > 0)
{
printf("%c", buf[0]);
}
else
{
break;
}
}
printf("\"\"\"\n");
}
int main(int argc, char *argv[])
{
int status;
pid_t pid;
int out[2];
posix_spawn_file_actions_t action;
char *args[] = {"/bin/echo", "Hello World!", NULL };
posix_spawn_file_actions_init(&action);
pipe(out);
posix_spawn_file_actions_adddup2(&action, out[1], STDOUT_FILENO);
posix_spawn_file_actions_addclose(&action, out[0]);
status = posix_spawn(&pid, args[0], &action, NULL, args, environ);
if (status == 0)
{
printf("child pid: %d\n", pid);
if (waitpid(pid, &status, 0) < 0)
{
perror("waitpid");
}
else
{
if (WIFEXITED(status))
{
printf("child exit status: %d\n", WEXITSTATUS(status));
}
else
{
printf("child died an unnatural death.\n");
}
close(out[1]);
dump_child_stdout(out[0]);
}
}
else
{
fprintf(stderr, "posix_spawn: %s\n", strerror(status));
close(out[1]);
}
posix_spawn_file_actions_destroy(&action);
return 0;
}