Oui, vous pouvez. Définir la bonne liste d'actions de fichiers de réapparition posix est définitivement la voie à suivre.
Exemple:
#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;
}
Compiler et tester:
$ 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
Notez que les posix_spawnfonctions ne définissent pas errno, contrairement à la plupart des autres fonctions UNIX, elles renvoient un code d'erreur. Ainsi, nous ne pouvons pas utiliser perror()mais devons utiliser quelque chose comme strerror().
Nous utilisons deux actions de création de fichier: addopen et addup2. L'addopen est similaire à un normal open()mais vous spécifiez également un descripteur de fichier qui est automatiquement fermé s'il est déjà ouvert (ici 1, c'est-à-dire stdout). L'addup2 a des effets similaires à dup2(), c'est- à -dire que le descripteur de fichier cible (ici 2, c'est-à-dire stderr) est atomiquement fermé avant que 1 ne soit dupliqué sur 2. Ces actions ne sont exécutées que dans l'enfant créé par posix_spawn, c'est-à-dire juste avant d'exécuter la commande spécifiée.
Comme fork(), posix_spawn()et posix_spawnp()revenez immédiatement au parent. Ainsi, nous devons utiliser waitid()ou waitpid()attendre explicitement child_pidla résiliation de.
posix_spwanest un pointeur de typeposix_spawn_file_actions_t(celui que vous avez donné commeNULL).posix_spawnouvrira, fermera ou dupliquera les descripteurs de fichiers hérités du processus appelant comme spécifié par l'posix_spawn_file_actions_tobjet. Lesposix_spawn_file_actions_{addclose,adddup2}fonctions sont utilisées pour indiquer ce qui arrive à quel fd.