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_spawn
fonctions 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_pid
la résiliation de.
posix_spwan
est un pointeur de typeposix_spawn_file_actions_t
(celui que vous avez donné commeNULL
).posix_spawn
ouvrira, fermera ou dupliquera les descripteurs de fichiers hérités du processus appelant comme spécifié par l'posix_spawn_file_actions_t
objet. Lesposix_spawn_file_actions_{addclose,adddup2}
fonctions sont utilisées pour indiquer ce qui arrive à quel fd.