Para que eu possa executar um processo no Unix / Linux usando POSIX, mas existe alguma maneira de armazenar / redirecionar o STDOUT e o STDERR do processo para um arquivo? O spawn.h
cabeçalho contém uma desaceleração posix_spawn_file_actions_adddup2
que parece relevante, mas não tenho certeza de como usá-lo.
O processo gera:
posix_spawn(&processID, (char *)"myprocess", NULL, NULL, args, environ);
O armazenamento de saída:
...?
posix_spwan
é um ponteiro do tipoposix_spawn_file_actions_t
(que você forneceu comoNULL
).posix_spawn
abrirá, fechará ou duplicará descritores de arquivo herdados do processo de chamada, conforme especificado peloposix_spawn_file_actions_t
objeto. Asposix_spawn_file_actions_{addclose,adddup2}
funções são usadas para indicar o que acontece com qual fd.Respostas:
Aqui está um exemplo mínimo de modificação de descritores de arquivo de um processo gerado, salvo como
foo.c
:O que isso faz?
posix_spwan
é um ponteiro do tipoposix_spawn_file_actions_t
(que você forneceu comoNULL
).posix_spawn
abrirá, fechará ou duplicará descritores de arquivo herdados do processo de chamada, conforme especificado peloposix_spawn_file_actions_t
objeto.posix_spawn_file_actions_t
objeto (chiild_fd_actions
) e o inicializamos composix_spawn_file_actions_init()
.posix_spawn_file_actions_{addopen,addclose,addup2}
funções podem ser usadas para descritores de arquivos abertos, próximos ou duplicados (após aopen(3)
,close(3)
edup2(3)
funções), respectivamente.posix_spawn_file_actions_addopen
um arquivo no/tmp/foo-log
descritor de arquivos1
(também conhecido como stdout).posix_spawn_file_actions_adddup2
fd2
(akastderr
) para fd 1.child_fd_actions
objeto para observar que essas ações devem ser executadas.posix_spawn
com ochild_fd_actions
objeto.Testando:
Como você pode ver, foram usados stdout e stderr do processo gerado
/tmp/foo-log
.fonte
posix_spawn*
não defina errno. Assim, você não pode usarperror()
. Use algo como emfprintf(stderr, "...: %s\n", strerror(ret))
vez disso. Além disso, a função principal está faltando umareturn 0
instrução.Sim você pode. Definindo a lista correta de ações do arquivo posix spawn definitivamente é o caminho a percorrer.
Exemplo:
Compilar e testar:
Observe que as
posix_spawn
funções não definem errno; ao contrário da maioria das outras funções UNIX, elas retornam um código de erro. Assim, não podemos usar,perror()
mas temos que usar algo parecidostrerror()
.Usamos duas ações de arquivo de reprodução: addopen e addup2. O addopen é semelhante ao normal,
open()
mas você também especifica um descritor de arquivo que é fechado automaticamente se já estiver aberto (aqui 1, isto é, stdout). O addup2 tem efeitos semelhantes adup2()
, ou seja, o descritor do arquivo de destino (aqui 2, ou seja, stderr) é fechado atomicamente antes de 1 ser duplicado para 2. Essas ações são executadas apenas no filho criado porposix_spawn
, ou seja, antes de executar o comando especificado.Como
fork()
,posix_spawn()
eposix_spawnp()
retornar imediatamente para o pai. Portanto, temos que usarwaitid()
ouwaitpid()
aguardar explicitamente achild_pid
rescisão do contrato.fonte