2 * Copyright © 2018 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include "piglit-subprocess.h"
33 #include <sys/types.h>
39 stream_data(pid_t pid
,
48 size_t buf_size
= 128;
50 *output
= malloc(buf_size
);
55 struct pollfd pollfds
[2];
58 pollfds
[n_pollfds
].fd
= to_child
;
59 pollfds
[n_pollfds
].events
= POLLOUT
;
60 pollfds
[n_pollfds
].revents
= 0;
64 pollfds
[n_pollfds
].fd
= from_child
;
65 pollfds
[n_pollfds
].events
= POLLIN
;
66 pollfds
[n_pollfds
].revents
= 0;
69 int res
= poll(pollfds
, n_pollfds
, INT_MAX
);
74 fprintf(stderr
, "poll: %s\n", strerror(errno
));
79 for (int i
= 0; i
< n_pollfds
; i
++) {
80 if (pollfds
[i
].revents
&
81 ~(POLLIN
| POLLOUT
| POLLHUP
)) {
86 if (pollfds
[i
].fd
== from_child
&&
88 if (buf_size
- *output_size
< 128) {
90 *output
= realloc(*output
, buf_size
);
92 res
= read(from_child
,
93 *output
+ *output_size
,
94 buf_size
- *output_size
);
100 } else if (res
== 0) {
107 } else if (pollfds
[i
].fd
== to_child
&&
108 pollfds
[i
].revents
) {
109 res
= write(to_child
, input
, input_size
);
117 if (input_size
<= 0) {
137 piglit_subprocess(char * const *arguments
,
139 const uint8_t *input
,
147 if (pipe(stdin_pipe
) == -1) {
148 fprintf(stderr
, "pipe: %s\n", strerror(errno
));
151 if (pipe(stdout_pipe
) == -1) {
152 fprintf(stderr
, "pipe: %s\n", strerror(errno
));
153 close(stdin_pipe
[0]);
154 close(stdin_pipe
[1]);
161 fprintf(stderr
, "fork failed: %s\n", strerror(errno
));
163 } else if (pid
== 0) {
164 dup2(stdin_pipe
[0], STDIN_FILENO
);
165 dup2(stdout_pipe
[1], STDOUT_FILENO
);
166 for (int i
= 3; i
< 256; i
++)
168 execvp(arguments
[0], arguments
);
169 fprintf(stderr
, "%s: %s\n", arguments
[0], strerror(errno
));
172 close(stdin_pipe
[0]);
173 close(stdout_pipe
[1]);
175 bool ret
= stream_data(pid
,
179 output_size
, output
);
182 while (waitpid(pid
, &status
, 0 /* options */) == -1);
184 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) {
197 piglit_subprocess(char * const *arguments
,
199 const uint8_t *input
,
203 fprintf(stderr
, "piglit_subprocess is not implemented on Windows\n");