Get output of `posix_spawn`
Here's a minimal example of modifying file descriptors of a spawned process, saved as 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);
}
What does it do?
- The third parameter of
posix_spwan
is a pointer of typeposix_spawn_file_actions_t
(one you have given asNULL
).posix_spawn
will open, close or duplicate file descriptors inherited from the calling process as specified by theposix_spawn_file_actions_t
object. - So we start with a
posix_spawn_file_actions_t
object (chiild_fd_actions
), and initialize it withposix_spawn_file_actions_init()
. - Now, the
posix_spawn_file_actions_{addopen,addclose,addup2}
functions can be used to open, close or duplicate file descriptors (after theopen(3)
,close(3)
anddup2(3)
functions) respectively. - So we
posix_spawn_file_actions_addopen
a file at/tmp/foo-log
to file descriptor1
(aka stdout). - Then we
posix_spawn_file_actions_adddup2
fd2
(akastderr
) to fd 1. - Note that nothing has been opened or duped yet. The last two functions simply changed the
child_fd_actions
object to note that these actions are to be taken. - And finally we use
posix_spawn
with thechild_fd_actions
object.
Testing it out:
$ 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’
As you can see, both stdout and stderr of the spawned process went to /tmp/foo-log
.