1 /* Capture output from a subprocess.
2 Copyright (C) 2017-2019 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <support/capture_subprocess.h>
23 #include <support/check.h>
24 #include <support/xunistd.h>
25 #include <support/xsocket.h>
28 transfer (const char *what
, struct pollfd
*pfd
, struct xmemstream
*stream
)
30 if (pfd
->revents
!= 0)
33 ssize_t ret
= TEMP_FAILURE_RETRY (read (pfd
->fd
, buf
, sizeof (buf
)));
36 support_record_failure ();
37 printf ("error: reading from subprocess %s: %m", what
);
43 /* EOF reached. Stop listening. */
48 /* Store the data just read. */
49 TEST_VERIFY (fwrite (buf
, ret
, 1, stream
->out
) == 1);
53 struct support_capture_subprocess
54 support_capture_subprocess (void (*callback
) (void *), void *closure
)
56 struct support_capture_subprocess result
;
57 xopen_memstream (&result
.out
);
58 xopen_memstream (&result
.err
);
62 TEST_VERIFY (stdout_pipe
[0] > STDERR_FILENO
);
63 TEST_VERIFY (stdout_pipe
[1] > STDERR_FILENO
);
66 TEST_VERIFY (stderr_pipe
[0] > STDERR_FILENO
);
67 TEST_VERIFY (stderr_pipe
[1] > STDERR_FILENO
);
69 TEST_VERIFY (fflush (stdout
) == 0);
70 TEST_VERIFY (fflush (stderr
) == 0);
75 xclose (stdout_pipe
[0]);
76 xclose (stderr_pipe
[0]);
77 xdup2 (stdout_pipe
[1], STDOUT_FILENO
);
78 xdup2 (stderr_pipe
[1], STDERR_FILENO
);
79 xclose (stdout_pipe
[1]);
80 xclose (stderr_pipe
[1]);
84 xclose (stdout_pipe
[1]);
85 xclose (stderr_pipe
[1]);
87 struct pollfd fds
[2] =
89 { .fd
= stdout_pipe
[0], .events
= POLLIN
},
90 { .fd
= stderr_pipe
[0], .events
= POLLIN
},
96 transfer ("stdout", &fds
[0], &result
.out
);
97 transfer ("stderr", &fds
[1], &result
.err
);
99 while (fds
[0].events
!= 0 || fds
[1].events
!= 0);
100 xclose (stdout_pipe
[0]);
101 xclose (stderr_pipe
[0]);
103 xfclose_memstream (&result
.out
);
104 xfclose_memstream (&result
.err
);
105 xwaitpid (pid
, &result
.status
, 0);
110 support_capture_subprocess_free (struct support_capture_subprocess
*p
)
112 free (p
->out
.buffer
);
113 free (p
->err
.buffer
);