Veja um exemplo mínimo de modificação de descritores de arquivos de um processo gerado, salvo como foo.c :
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <spawn.h>
int main(int argc, char* argv[], char *env[])
{
int ret;
pid_t child_pid;
posix_spawn_file_actions_t child_fd_actions;
if (ret = posix_spawn_file_actions_init (&child_fd_actions))
perror ("posix_spawn_file_actions_init"), exit(ret);
if (ret = posix_spawn_file_actions_addopen (&child_fd_actions, 1, "/tmp/foo-log",
O_WRONLY | O_CREAT | O_TRUNC, 0644))
perror ("posix_spawn_file_actions_addopen"), exit(ret);
if (ret = posix_spawn_file_actions_adddup2 (&child_fd_actions, 1, 2))
perror ("posix_spawn_file_actions_adddup2"), exit(ret);
if (ret = posix_spawnp (&child_pid, "date", &child_fd_actions, NULL, argv, env))
perror ("posix_spawn"), exit(ret);
}
O que isso faz?
- O terceiro parâmetro de
posix_spwané um ponteiro do tipoposix_spawn_file_actions_t(um que você forneceu comoNULL).posix_spawnabrirá, fechará ou duplicará os descritores de arquivos herdados do processo de chamada, conforme especificado pelo objetoposix_spawn_file_actions_t. - Portanto, começamos com um objeto
posix_spawn_file_actions_t(chiild_fd_actions) e inicializamos composix_spawn_file_actions_init(). - Agora, as funções
posix_spawn_file_actions_{addopen,addclose,addup2}podem ser usadas para abrir, fechar ou duplicar descritores de arquivos (depois das funçõesopen(3),close(3)edup2(3)) respectivamente. - Então,
posix_spawn_file_actions_addopenum arquivo em/tmp/foo-logpara o descritor de arquivo1(também conhecido como stdout). - Então,
posix_spawn_file_actions_adddup2fd2(também conhecido comostderr) para fd 1. - Observe que nada foi aberto ou enganado ainda . As duas últimas funções simplesmente alteraram o objeto
child_fd_actionspara observar que essas ações devem ser tomadas. - E, finalmente, usamos
posix_spawncom o objetochild_fd_actions.
Teste:
$ make foo
cc foo.c -o foo
$ ./foo
$ cat /tmp/foo-log
Sun Jan 3 03:48:17 IST 2016
$ ./foo +'%F %R'
$ cat /tmp/foo-log
2016-01-03 03:48
$ ./foo -d 'foo'
$ cat /tmp/foo-log
./foo: invalid date ‘foo’
Como você pode ver, stdout e stderr do processo gerado foram para /tmp/foo-log .