Да, ты можешь. Определить правильный список действий в файле posix spawn определенно стоит.
Пример:
#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()
.
Мы используем два действия spawn file: addopen и addup2. Addopen похож на обычный, open()
но вы также указываете дескриптор файла, который автоматически закрывается, если он уже открыт (здесь 1, т.е. stdout). Addup2 имеет аналогичные эффекты dup2()
, т. Е. Дескриптор целевого файла (здесь 2, то есть stderr) атомарно закрывается до того, как 1 дублируется до 2. Эти действия выполняются только в дочернем объекте, созданном , т. Е. Непосредственно 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}
функции используются для обозначения того, что происходит с каким дескриптором.