Так, ти можеш. Визначення правильного списку дій нерестового файлу 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. Додаток схожий на звичайний, open()але ви також вказали дескриптор файлу, який автоматично закриється, якщо він уже відкритий (тут 1, тобто stdout). Аддуп2 має подібні ефекти 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}функції використовуються для позначення того, що відбувається з яким дескриптором.