Да, ты можешь. Определить правильный список действий в файле 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}функции используются для обозначения того, что происходит с каким дескриптором.