1 /* Capture output from a subprocess.
2 Copyright (C) 2017-2020 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 <https://www.gnu.org/licenses/>. */
19 #include <support/subprocess.h>
20 #include <support/capture_subprocess.h>
24 #include <support/check.h>
25 #include <support/xunistd.h>
26 #include <support/xsocket.h>
27 #include <support/xspawn.h>
30 transfer (const char *what
, struct pollfd
*pfd
, struct xmemstream
*stream
)
32 if (pfd
->revents
!= 0)
35 ssize_t ret
= TEMP_FAILURE_RETRY (read (pfd
->fd
, buf
, sizeof (buf
)));
38 support_record_failure ();
39 printf ("error: reading from subprocess %s: %m", what
);
45 /* EOF reached. Stop listening. */
50 /* Store the data just read. */
51 TEST_VERIFY (fwrite (buf
, ret
, 1, stream
->out
) == 1);
56 support_capture_poll (struct support_capture_subprocess
*result
,
57 struct support_subprocess
*proc
)
59 struct pollfd fds
[2] =
61 { .fd
= proc
->stdout_pipe
[0], .events
= POLLIN
},
62 { .fd
= proc
->stderr_pipe
[0], .events
= POLLIN
},
68 transfer ("stdout", &fds
[0], &result
->out
);
69 transfer ("stderr", &fds
[1], &result
->err
);
71 while (fds
[0].events
!= 0 || fds
[1].events
!= 0);
73 xfclose_memstream (&result
->out
);
74 xfclose_memstream (&result
->err
);
76 result
->status
= support_process_wait (proc
);
79 struct support_capture_subprocess
80 support_capture_subprocess (void (*callback
) (void *), void *closure
)
82 struct support_capture_subprocess result
;
83 xopen_memstream (&result
.out
);
84 xopen_memstream (&result
.err
);
86 struct support_subprocess proc
= support_subprocess (callback
, closure
);
88 support_capture_poll (&result
, &proc
);
92 struct support_capture_subprocess
93 support_capture_subprogram (const char *file
, char *const argv
[])
95 struct support_capture_subprocess result
;
96 xopen_memstream (&result
.out
);
97 xopen_memstream (&result
.err
);
99 struct support_subprocess proc
= support_subprogram (file
, argv
);
101 support_capture_poll (&result
, &proc
);
106 support_capture_subprocess_free (struct support_capture_subprocess
*p
)
108 free (p
->out
.buffer
);
109 free (p
->err
.buffer
);