是的你可以。定义posix生成文件操作的正确列表绝对是正确的方法。
例:
#include <errno.h>
#include <fcntl.h>
#include <spawn.h>
#include <stdio.h>
#include <string.h>
#define CHECK_ERROR(R, MSG) do { if (R) { fprintf(stderr, "%s: %s\n",
(MSG), strerror(R)); return 1; } } while (0)
extern char **environ;
int main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "Call: %s OUTFILE COMMAND [ARG]...\n", argv[0]);
return 2;
}
const char *out_filename = argv[1];
char **child_argv = argv+2;
posix_spawn_file_actions_t as;
int r = posix_spawn_file_actions_init(&as);
CHECK_ERROR(r, "actions init");
r = posix_spawn_file_actions_addopen(&as, 1, out_filename,
O_CREAT | O_TRUNC | O_WRONLY, 0644);
CHECK_ERROR(r, "addopen");
r = posix_spawn_file_actions_adddup2(&as, 1, 2);
CHECK_ERROR(r, "adddup2");
pid_t child_pid;
r = posix_spawnp(&child_pid, child_argv[0], &as, NULL,
child_argv, environ);
CHECK_ERROR(r, "spawnp");
r = posix_spawn_file_actions_destroy(&as);
CHECK_ERROR(r, "actions destroy");
return 0;
}
编译测试:
$ cc -Wall -g -o spawnp spawnp.c
$ ./spawnp log date -I
$ cat log
2018-11-03
$ ./a.out log dat
spawnp: No such file or directory
请注意,这些posix_spawn
函数未设置errno,与大多数其他UNIX函数不同,它们返回错误代码。因此,我们不能使用,perror()
而必须使用strerror()
。
我们使用两个生成文件操作:addopen和addup2。addopen与正常情况类似,open()
但是您还可以指定一个文件描述符,如果该文件描述符已经打开,则会自动关闭(此处为1,即stdout)。addup2的效果与相似dup2()
,即在将1复制到2之前,原子关闭了目标文件描述符(此处为2,即stderr)。这些操作仅在创建的子级中执行posix_spawn
,即在其执行指定命令之前。
就像fork()
,posix_spawn()
并posix_spawnp()
立即返回父级。因此,我们必须使用waitid()
或waitpid()
明确等待child_pid
的终止。
posix_spwan
是类型的指针posix_spawn_file_actions_t
(您已将其指定为NULL
)。posix_spawn
将打开,关闭或复制从posix_spawn_file_actions_t
对象指定的调用过程继承的文件描述符。该posix_spawn_file_actions_{addclose,adddup2}
函数用于指示哪个fd发生了什么。