Tak, możesz. Zdecydowanie słuszne jest zdefiniowanie właściwej listy akcji odradzania plików posix.
Przykład:
#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;
}
Skompiluj i przetestuj:
$ 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
Zauważ, że posix_spawnfunkcje nie ustawiają errno, zamiast tego, w przeciwieństwie do większości innych funkcji UNIX, zwracają kod błędu. Dlatego nie możemy użyć, perror()ale musimy użyć czegoś takiego strerror().
Używamy dwóch akcji plików spawn: addopen i addup2. Addopen jest podobny do normalnego, open()ale określasz także deskryptor pliku, który jest automatycznie zamykany, jeśli jest już otwarty (tutaj 1, tzn. Standardowe wyjście). Addup2 ma podobne efekty dup2(), tj. Deskryptor pliku docelowego (tutaj 2, tj. Stderr) jest atomowo zamykany, zanim 1 zostanie zduplikowany do 2. Te akcje są wykonywane tylko w podrzędnym utworzonym przez posix_spawn, tj. Tuż przed wykonaniem określonego polecenia.
Jak fork(), posix_spawn()i posix_spawnp()natychmiast wrócić do rodziców. W związku z tym musimy wykorzystać waitid()lub waitpid()wyraźnie poczekać na child_pidzakończenie.
posix_spwanjest wskaźnik typuposix_spawn_file_actions_t(ten, który podałeś jakoNULL).posix_spawnotworzy, zamknie lub powieli deskryptory plików odziedziczone po procesie wywoływania określonym przezposix_spawn_file_actions_tobiekt. Teposix_spawn_file_actions_{addclose,adddup2}funkcje są używane, aby wskazać, co się dzieje, z którym fd.