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_spawn
abrirá, 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_addopen
um arquivo em/tmp/foo-log
para o descritor de arquivo1
(também conhecido como stdout). - Então,
posix_spawn_file_actions_adddup2
fd2
(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_actions
para observar que essas ações devem ser tomadas. - E, finalmente, usamos
posix_spawn
com 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
.