1 /* Capture output from a subprocess.
2 Copyright (C) 2017 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
);
65 TEST_VERIFY (fflush (stdout
) == 0);
66 TEST_VERIFY (fflush (stderr
) == 0);
71 xclose (stdout_pipe
[0]);
72 xclose (stderr_pipe
[0]);
73 xdup2 (stdout_pipe
[1], STDOUT_FILENO
);
74 xdup2 (stderr_pipe
[1], STDERR_FILENO
);
78 xclose (stdout_pipe
[1]);
79 xclose (stderr_pipe
[1]);
81 struct pollfd fds
[2] =
83 { .fd
= stdout_pipe
[0], .events
= POLLIN
},
84 { .fd
= stderr_pipe
[0], .events
= POLLIN
},
90 transfer ("stdout", &fds
[0], &result
.out
);
91 transfer ("stderr", &fds
[1], &result
.err
);
93 while (fds
[0].events
!= 0 || fds
[1].events
!= 0);
94 xclose (stdout_pipe
[0]);
95 xclose (stderr_pipe
[0]);
97 xfclose_memstream (&result
.out
);
98 xfclose_memstream (&result
.err
);
99 xwaitpid (pid
, &result
.status
, 0);
104 support_capture_subprocess_free (struct support_capture_subprocess
*p
)
106 free (p
->out
.buffer
);
107 free (p
->err
.buffer
);