xref: /freebsd/contrib/atf/atf-c/check.c (revision c243e4902be8df1e643c76b5f18b68bb77cc5268)
1*c243e490SMarcel Moolenaar /*
2*c243e490SMarcel Moolenaar  * Automated Testing Framework (atf)
3*c243e490SMarcel Moolenaar  *
4*c243e490SMarcel Moolenaar  * Copyright (c) 2008 The NetBSD Foundation, Inc.
5*c243e490SMarcel Moolenaar  * All rights reserved.
6*c243e490SMarcel Moolenaar  *
7*c243e490SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
8*c243e490SMarcel Moolenaar  * modification, are permitted provided that the following conditions
9*c243e490SMarcel Moolenaar  * are met:
10*c243e490SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
11*c243e490SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
12*c243e490SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
13*c243e490SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
14*c243e490SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
15*c243e490SMarcel Moolenaar  *
16*c243e490SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17*c243e490SMarcel Moolenaar  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18*c243e490SMarcel Moolenaar  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19*c243e490SMarcel Moolenaar  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*c243e490SMarcel Moolenaar  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21*c243e490SMarcel Moolenaar  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*c243e490SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23*c243e490SMarcel Moolenaar  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*c243e490SMarcel Moolenaar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25*c243e490SMarcel Moolenaar  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26*c243e490SMarcel Moolenaar  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27*c243e490SMarcel Moolenaar  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*c243e490SMarcel Moolenaar  */
29*c243e490SMarcel Moolenaar 
30*c243e490SMarcel Moolenaar #include <sys/wait.h>
31*c243e490SMarcel Moolenaar 
32*c243e490SMarcel Moolenaar #include <errno.h>
33*c243e490SMarcel Moolenaar #include <fcntl.h>
34*c243e490SMarcel Moolenaar #include <stdio.h>
35*c243e490SMarcel Moolenaar #include <stdlib.h>
36*c243e490SMarcel Moolenaar #include <string.h>
37*c243e490SMarcel Moolenaar #include <unistd.h>
38*c243e490SMarcel Moolenaar 
39*c243e490SMarcel Moolenaar #include "atf-c/build.h"
40*c243e490SMarcel Moolenaar #include "atf-c/check.h"
41*c243e490SMarcel Moolenaar #include "atf-c/config.h"
42*c243e490SMarcel Moolenaar #include "atf-c/defs.h"
43*c243e490SMarcel Moolenaar #include "atf-c/error.h"
44*c243e490SMarcel Moolenaar #include "atf-c/utils.h"
45*c243e490SMarcel Moolenaar 
46*c243e490SMarcel Moolenaar #include "detail/dynstr.h"
47*c243e490SMarcel Moolenaar #include "detail/fs.h"
48*c243e490SMarcel Moolenaar #include "detail/list.h"
49*c243e490SMarcel Moolenaar #include "detail/process.h"
50*c243e490SMarcel Moolenaar #include "detail/sanity.h"
51*c243e490SMarcel Moolenaar 
52*c243e490SMarcel Moolenaar /* ---------------------------------------------------------------------
53*c243e490SMarcel Moolenaar  * Auxiliary functions.
54*c243e490SMarcel Moolenaar  * --------------------------------------------------------------------- */
55*c243e490SMarcel Moolenaar 
56*c243e490SMarcel Moolenaar static
57*c243e490SMarcel Moolenaar atf_error_t
58*c243e490SMarcel Moolenaar create_tmpdir(atf_fs_path_t *dir)
59*c243e490SMarcel Moolenaar {
60*c243e490SMarcel Moolenaar     atf_error_t err;
61*c243e490SMarcel Moolenaar 
62*c243e490SMarcel Moolenaar     err = atf_fs_path_init_fmt(dir, "%s/check.XXXXXX",
63*c243e490SMarcel Moolenaar                                atf_config_get("atf_workdir"));
64*c243e490SMarcel Moolenaar     if (atf_is_error(err))
65*c243e490SMarcel Moolenaar         goto out;
66*c243e490SMarcel Moolenaar 
67*c243e490SMarcel Moolenaar     err = atf_fs_mkdtemp(dir);
68*c243e490SMarcel Moolenaar     if (atf_is_error(err)) {
69*c243e490SMarcel Moolenaar         atf_fs_path_fini(dir);
70*c243e490SMarcel Moolenaar         goto out;
71*c243e490SMarcel Moolenaar     }
72*c243e490SMarcel Moolenaar 
73*c243e490SMarcel Moolenaar     INV(!atf_is_error(err));
74*c243e490SMarcel Moolenaar out:
75*c243e490SMarcel Moolenaar     return err;
76*c243e490SMarcel Moolenaar }
77*c243e490SMarcel Moolenaar 
78*c243e490SMarcel Moolenaar static
79*c243e490SMarcel Moolenaar void
80*c243e490SMarcel Moolenaar cleanup_tmpdir(const atf_fs_path_t *dir, const atf_fs_path_t *outfile,
81*c243e490SMarcel Moolenaar                const atf_fs_path_t *errfile)
82*c243e490SMarcel Moolenaar {
83*c243e490SMarcel Moolenaar     {
84*c243e490SMarcel Moolenaar         atf_error_t err = atf_fs_unlink(outfile);
85*c243e490SMarcel Moolenaar         if (atf_is_error(err)) {
86*c243e490SMarcel Moolenaar             INV(atf_error_is(err, "libc") &&
87*c243e490SMarcel Moolenaar                 atf_libc_error_code(err) == ENOENT);
88*c243e490SMarcel Moolenaar             atf_error_free(err);
89*c243e490SMarcel Moolenaar         } else
90*c243e490SMarcel Moolenaar             INV(!atf_is_error(err));
91*c243e490SMarcel Moolenaar     }
92*c243e490SMarcel Moolenaar 
93*c243e490SMarcel Moolenaar     {
94*c243e490SMarcel Moolenaar         atf_error_t err = atf_fs_unlink(errfile);
95*c243e490SMarcel Moolenaar         if (atf_is_error(err)) {
96*c243e490SMarcel Moolenaar             INV(atf_error_is(err, "libc") &&
97*c243e490SMarcel Moolenaar                 atf_libc_error_code(err) == ENOENT);
98*c243e490SMarcel Moolenaar             atf_error_free(err);
99*c243e490SMarcel Moolenaar         } else
100*c243e490SMarcel Moolenaar             INV(!atf_is_error(err));
101*c243e490SMarcel Moolenaar     }
102*c243e490SMarcel Moolenaar 
103*c243e490SMarcel Moolenaar     {
104*c243e490SMarcel Moolenaar         atf_error_t err = atf_fs_rmdir(dir);
105*c243e490SMarcel Moolenaar         INV(!atf_is_error(err));
106*c243e490SMarcel Moolenaar     }
107*c243e490SMarcel Moolenaar }
108*c243e490SMarcel Moolenaar 
109*c243e490SMarcel Moolenaar static
110*c243e490SMarcel Moolenaar int
111*c243e490SMarcel Moolenaar const_execvp(const char *file, const char *const *argv)
112*c243e490SMarcel Moolenaar {
113*c243e490SMarcel Moolenaar #define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
114*c243e490SMarcel Moolenaar     return execvp(file, UNCONST(argv));
115*c243e490SMarcel Moolenaar #undef UNCONST
116*c243e490SMarcel Moolenaar }
117*c243e490SMarcel Moolenaar 
118*c243e490SMarcel Moolenaar static
119*c243e490SMarcel Moolenaar atf_error_t
120*c243e490SMarcel Moolenaar init_sb(const atf_fs_path_t *path, atf_process_stream_t *sb)
121*c243e490SMarcel Moolenaar {
122*c243e490SMarcel Moolenaar     atf_error_t err;
123*c243e490SMarcel Moolenaar 
124*c243e490SMarcel Moolenaar     if (path == NULL)
125*c243e490SMarcel Moolenaar         err = atf_process_stream_init_inherit(sb);
126*c243e490SMarcel Moolenaar     else
127*c243e490SMarcel Moolenaar         err = atf_process_stream_init_redirect_path(sb, path);
128*c243e490SMarcel Moolenaar 
129*c243e490SMarcel Moolenaar     return err;
130*c243e490SMarcel Moolenaar }
131*c243e490SMarcel Moolenaar 
132*c243e490SMarcel Moolenaar static
133*c243e490SMarcel Moolenaar atf_error_t
134*c243e490SMarcel Moolenaar init_sbs(const atf_fs_path_t *outfile, atf_process_stream_t *outsb,
135*c243e490SMarcel Moolenaar          const atf_fs_path_t *errfile, atf_process_stream_t *errsb)
136*c243e490SMarcel Moolenaar {
137*c243e490SMarcel Moolenaar     atf_error_t err;
138*c243e490SMarcel Moolenaar 
139*c243e490SMarcel Moolenaar     err = init_sb(outfile, outsb);
140*c243e490SMarcel Moolenaar     if (atf_is_error(err))
141*c243e490SMarcel Moolenaar         goto out;
142*c243e490SMarcel Moolenaar 
143*c243e490SMarcel Moolenaar     err = init_sb(errfile, errsb);
144*c243e490SMarcel Moolenaar     if (atf_is_error(err)) {
145*c243e490SMarcel Moolenaar         atf_process_stream_fini(outsb);
146*c243e490SMarcel Moolenaar         goto out;
147*c243e490SMarcel Moolenaar     }
148*c243e490SMarcel Moolenaar 
149*c243e490SMarcel Moolenaar out:
150*c243e490SMarcel Moolenaar     return err;
151*c243e490SMarcel Moolenaar }
152*c243e490SMarcel Moolenaar 
153*c243e490SMarcel Moolenaar struct exec_data {
154*c243e490SMarcel Moolenaar     const char *const *m_argv;
155*c243e490SMarcel Moolenaar };
156*c243e490SMarcel Moolenaar 
157*c243e490SMarcel Moolenaar static void exec_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
158*c243e490SMarcel Moolenaar 
159*c243e490SMarcel Moolenaar static
160*c243e490SMarcel Moolenaar void
161*c243e490SMarcel Moolenaar exec_child(void *v)
162*c243e490SMarcel Moolenaar {
163*c243e490SMarcel Moolenaar     struct exec_data *ea = v;
164*c243e490SMarcel Moolenaar 
165*c243e490SMarcel Moolenaar     const_execvp(ea->m_argv[0], ea->m_argv);
166*c243e490SMarcel Moolenaar     fprintf(stderr, "execvp(%s) failed: %s\n", ea->m_argv[0], strerror(errno));
167*c243e490SMarcel Moolenaar     exit(127);
168*c243e490SMarcel Moolenaar }
169*c243e490SMarcel Moolenaar 
170*c243e490SMarcel Moolenaar static
171*c243e490SMarcel Moolenaar atf_error_t
172*c243e490SMarcel Moolenaar fork_and_wait(const char *const *argv, const atf_fs_path_t *outfile,
173*c243e490SMarcel Moolenaar               const atf_fs_path_t *errfile, atf_process_status_t *status)
174*c243e490SMarcel Moolenaar {
175*c243e490SMarcel Moolenaar     atf_error_t err;
176*c243e490SMarcel Moolenaar     atf_process_child_t child;
177*c243e490SMarcel Moolenaar     atf_process_stream_t outsb, errsb;
178*c243e490SMarcel Moolenaar     struct exec_data ea = { argv };
179*c243e490SMarcel Moolenaar 
180*c243e490SMarcel Moolenaar     err = init_sbs(outfile, &outsb, errfile, &errsb);
181*c243e490SMarcel Moolenaar     if (atf_is_error(err))
182*c243e490SMarcel Moolenaar         goto out;
183*c243e490SMarcel Moolenaar 
184*c243e490SMarcel Moolenaar     err = atf_process_fork(&child, exec_child, &outsb, &errsb, &ea);
185*c243e490SMarcel Moolenaar     if (atf_is_error(err))
186*c243e490SMarcel Moolenaar         goto out_sbs;
187*c243e490SMarcel Moolenaar 
188*c243e490SMarcel Moolenaar     err = atf_process_child_wait(&child, status);
189*c243e490SMarcel Moolenaar 
190*c243e490SMarcel Moolenaar out_sbs:
191*c243e490SMarcel Moolenaar     atf_process_stream_fini(&errsb);
192*c243e490SMarcel Moolenaar     atf_process_stream_fini(&outsb);
193*c243e490SMarcel Moolenaar out:
194*c243e490SMarcel Moolenaar     return err;
195*c243e490SMarcel Moolenaar }
196*c243e490SMarcel Moolenaar 
197*c243e490SMarcel Moolenaar static
198*c243e490SMarcel Moolenaar void
199*c243e490SMarcel Moolenaar update_success_from_status(const char *progname,
200*c243e490SMarcel Moolenaar                            const atf_process_status_t *status, bool *success)
201*c243e490SMarcel Moolenaar {
202*c243e490SMarcel Moolenaar     bool s = atf_process_status_exited(status) &&
203*c243e490SMarcel Moolenaar              atf_process_status_exitstatus(status) == EXIT_SUCCESS;
204*c243e490SMarcel Moolenaar 
205*c243e490SMarcel Moolenaar     if (atf_process_status_exited(status)) {
206*c243e490SMarcel Moolenaar         if (atf_process_status_exitstatus(status) == EXIT_SUCCESS)
207*c243e490SMarcel Moolenaar             INV(s);
208*c243e490SMarcel Moolenaar         else {
209*c243e490SMarcel Moolenaar             INV(!s);
210*c243e490SMarcel Moolenaar             fprintf(stderr, "%s failed with exit code %d\n", progname,
211*c243e490SMarcel Moolenaar                     atf_process_status_exitstatus(status));
212*c243e490SMarcel Moolenaar         }
213*c243e490SMarcel Moolenaar     } else if (atf_process_status_signaled(status)) {
214*c243e490SMarcel Moolenaar         INV(!s);
215*c243e490SMarcel Moolenaar         fprintf(stderr, "%s failed due to signal %d%s\n", progname,
216*c243e490SMarcel Moolenaar                 atf_process_status_termsig(status),
217*c243e490SMarcel Moolenaar                 atf_process_status_coredump(status) ? " (core dumped)" : "");
218*c243e490SMarcel Moolenaar     } else {
219*c243e490SMarcel Moolenaar         INV(!s);
220*c243e490SMarcel Moolenaar         fprintf(stderr, "%s failed due to unknown reason\n", progname);
221*c243e490SMarcel Moolenaar     }
222*c243e490SMarcel Moolenaar 
223*c243e490SMarcel Moolenaar     *success = s;
224*c243e490SMarcel Moolenaar }
225*c243e490SMarcel Moolenaar 
226*c243e490SMarcel Moolenaar static
227*c243e490SMarcel Moolenaar atf_error_t
228*c243e490SMarcel Moolenaar array_to_list(const char *const *a, atf_list_t *l)
229*c243e490SMarcel Moolenaar {
230*c243e490SMarcel Moolenaar     atf_error_t err;
231*c243e490SMarcel Moolenaar 
232*c243e490SMarcel Moolenaar     err = atf_list_init(l);
233*c243e490SMarcel Moolenaar     if (atf_is_error(err))
234*c243e490SMarcel Moolenaar         goto out;
235*c243e490SMarcel Moolenaar 
236*c243e490SMarcel Moolenaar     while (*a != NULL) {
237*c243e490SMarcel Moolenaar         char *item = strdup(*a);
238*c243e490SMarcel Moolenaar         if (item == NULL) {
239*c243e490SMarcel Moolenaar             err = atf_no_memory_error();
240*c243e490SMarcel Moolenaar             goto out;
241*c243e490SMarcel Moolenaar         }
242*c243e490SMarcel Moolenaar 
243*c243e490SMarcel Moolenaar         err = atf_list_append(l, item, true);
244*c243e490SMarcel Moolenaar         if (atf_is_error(err))
245*c243e490SMarcel Moolenaar             goto out;
246*c243e490SMarcel Moolenaar 
247*c243e490SMarcel Moolenaar         a++;
248*c243e490SMarcel Moolenaar     }
249*c243e490SMarcel Moolenaar 
250*c243e490SMarcel Moolenaar out:
251*c243e490SMarcel Moolenaar     return err;
252*c243e490SMarcel Moolenaar }
253*c243e490SMarcel Moolenaar 
254*c243e490SMarcel Moolenaar static void
255*c243e490SMarcel Moolenaar print_array(const char *const *array, const char *pfx)
256*c243e490SMarcel Moolenaar {
257*c243e490SMarcel Moolenaar     const char *const *ptr;
258*c243e490SMarcel Moolenaar 
259*c243e490SMarcel Moolenaar     printf("%s", pfx);
260*c243e490SMarcel Moolenaar     for (ptr = array; *ptr != NULL; ptr++)
261*c243e490SMarcel Moolenaar         printf(" %s", *ptr);
262*c243e490SMarcel Moolenaar     printf("\n");
263*c243e490SMarcel Moolenaar }
264*c243e490SMarcel Moolenaar 
265*c243e490SMarcel Moolenaar static
266*c243e490SMarcel Moolenaar atf_error_t
267*c243e490SMarcel Moolenaar check_build_run(const char *const *argv, bool *success)
268*c243e490SMarcel Moolenaar {
269*c243e490SMarcel Moolenaar     atf_error_t err;
270*c243e490SMarcel Moolenaar     atf_process_status_t status;
271*c243e490SMarcel Moolenaar 
272*c243e490SMarcel Moolenaar     print_array(argv, ">");
273*c243e490SMarcel Moolenaar 
274*c243e490SMarcel Moolenaar     err = fork_and_wait(argv, NULL, NULL, &status);
275*c243e490SMarcel Moolenaar     if (atf_is_error(err))
276*c243e490SMarcel Moolenaar         goto out;
277*c243e490SMarcel Moolenaar 
278*c243e490SMarcel Moolenaar     update_success_from_status(argv[0], &status, success);
279*c243e490SMarcel Moolenaar     atf_process_status_fini(&status);
280*c243e490SMarcel Moolenaar 
281*c243e490SMarcel Moolenaar     INV(!atf_is_error(err));
282*c243e490SMarcel Moolenaar out:
283*c243e490SMarcel Moolenaar     return err;
284*c243e490SMarcel Moolenaar }
285*c243e490SMarcel Moolenaar 
286*c243e490SMarcel Moolenaar /* ---------------------------------------------------------------------
287*c243e490SMarcel Moolenaar  * The "atf_check_result" type.
288*c243e490SMarcel Moolenaar  * --------------------------------------------------------------------- */
289*c243e490SMarcel Moolenaar 
290*c243e490SMarcel Moolenaar struct atf_check_result_impl {
291*c243e490SMarcel Moolenaar     atf_list_t m_argv;
292*c243e490SMarcel Moolenaar     atf_fs_path_t m_dir;
293*c243e490SMarcel Moolenaar     atf_fs_path_t m_stdout;
294*c243e490SMarcel Moolenaar     atf_fs_path_t m_stderr;
295*c243e490SMarcel Moolenaar     atf_process_status_t m_status;
296*c243e490SMarcel Moolenaar };
297*c243e490SMarcel Moolenaar 
298*c243e490SMarcel Moolenaar static
299*c243e490SMarcel Moolenaar atf_error_t
300*c243e490SMarcel Moolenaar atf_check_result_init(atf_check_result_t *r, const char *const *argv,
301*c243e490SMarcel Moolenaar                       const atf_fs_path_t *dir)
302*c243e490SMarcel Moolenaar {
303*c243e490SMarcel Moolenaar     atf_error_t err;
304*c243e490SMarcel Moolenaar 
305*c243e490SMarcel Moolenaar     r->pimpl = malloc(sizeof(struct atf_check_result_impl));
306*c243e490SMarcel Moolenaar     if (r->pimpl == NULL)
307*c243e490SMarcel Moolenaar         return atf_no_memory_error();
308*c243e490SMarcel Moolenaar 
309*c243e490SMarcel Moolenaar     err = array_to_list(argv, &r->pimpl->m_argv);
310*c243e490SMarcel Moolenaar     if (atf_is_error(err))
311*c243e490SMarcel Moolenaar         goto out;
312*c243e490SMarcel Moolenaar 
313*c243e490SMarcel Moolenaar     err = atf_fs_path_copy(&r->pimpl->m_dir, dir);
314*c243e490SMarcel Moolenaar     if (atf_is_error(err))
315*c243e490SMarcel Moolenaar         goto err_argv;
316*c243e490SMarcel Moolenaar 
317*c243e490SMarcel Moolenaar     err = atf_fs_path_init_fmt(&r->pimpl->m_stdout, "%s/stdout",
318*c243e490SMarcel Moolenaar                                atf_fs_path_cstring(dir));
319*c243e490SMarcel Moolenaar     if (atf_is_error(err))
320*c243e490SMarcel Moolenaar         goto err_dir;
321*c243e490SMarcel Moolenaar 
322*c243e490SMarcel Moolenaar     err = atf_fs_path_init_fmt(&r->pimpl->m_stderr, "%s/stderr",
323*c243e490SMarcel Moolenaar                                atf_fs_path_cstring(dir));
324*c243e490SMarcel Moolenaar     if (atf_is_error(err))
325*c243e490SMarcel Moolenaar         goto err_stdout;
326*c243e490SMarcel Moolenaar 
327*c243e490SMarcel Moolenaar     INV(!atf_is_error(err));
328*c243e490SMarcel Moolenaar     goto out;
329*c243e490SMarcel Moolenaar 
330*c243e490SMarcel Moolenaar err_stdout:
331*c243e490SMarcel Moolenaar     atf_fs_path_fini(&r->pimpl->m_stdout);
332*c243e490SMarcel Moolenaar err_dir:
333*c243e490SMarcel Moolenaar     atf_fs_path_fini(&r->pimpl->m_dir);
334*c243e490SMarcel Moolenaar err_argv:
335*c243e490SMarcel Moolenaar     atf_list_fini(&r->pimpl->m_argv);
336*c243e490SMarcel Moolenaar out:
337*c243e490SMarcel Moolenaar     return err;
338*c243e490SMarcel Moolenaar }
339*c243e490SMarcel Moolenaar 
340*c243e490SMarcel Moolenaar void
341*c243e490SMarcel Moolenaar atf_check_result_fini(atf_check_result_t *r)
342*c243e490SMarcel Moolenaar {
343*c243e490SMarcel Moolenaar     atf_process_status_fini(&r->pimpl->m_status);
344*c243e490SMarcel Moolenaar 
345*c243e490SMarcel Moolenaar     cleanup_tmpdir(&r->pimpl->m_dir, &r->pimpl->m_stdout,
346*c243e490SMarcel Moolenaar                    &r->pimpl->m_stderr);
347*c243e490SMarcel Moolenaar     atf_fs_path_fini(&r->pimpl->m_stdout);
348*c243e490SMarcel Moolenaar     atf_fs_path_fini(&r->pimpl->m_stderr);
349*c243e490SMarcel Moolenaar     atf_fs_path_fini(&r->pimpl->m_dir);
350*c243e490SMarcel Moolenaar 
351*c243e490SMarcel Moolenaar     atf_list_fini(&r->pimpl->m_argv);
352*c243e490SMarcel Moolenaar 
353*c243e490SMarcel Moolenaar     free(r->pimpl);
354*c243e490SMarcel Moolenaar }
355*c243e490SMarcel Moolenaar 
356*c243e490SMarcel Moolenaar const char *
357*c243e490SMarcel Moolenaar atf_check_result_stdout(const atf_check_result_t *r)
358*c243e490SMarcel Moolenaar {
359*c243e490SMarcel Moolenaar     return atf_fs_path_cstring(&r->pimpl->m_stdout);
360*c243e490SMarcel Moolenaar }
361*c243e490SMarcel Moolenaar 
362*c243e490SMarcel Moolenaar const char *
363*c243e490SMarcel Moolenaar atf_check_result_stderr(const atf_check_result_t *r)
364*c243e490SMarcel Moolenaar {
365*c243e490SMarcel Moolenaar     return atf_fs_path_cstring(&r->pimpl->m_stderr);
366*c243e490SMarcel Moolenaar }
367*c243e490SMarcel Moolenaar 
368*c243e490SMarcel Moolenaar bool
369*c243e490SMarcel Moolenaar atf_check_result_exited(const atf_check_result_t *r)
370*c243e490SMarcel Moolenaar {
371*c243e490SMarcel Moolenaar     return atf_process_status_exited(&r->pimpl->m_status);
372*c243e490SMarcel Moolenaar }
373*c243e490SMarcel Moolenaar 
374*c243e490SMarcel Moolenaar int
375*c243e490SMarcel Moolenaar atf_check_result_exitcode(const atf_check_result_t *r)
376*c243e490SMarcel Moolenaar {
377*c243e490SMarcel Moolenaar     return atf_process_status_exitstatus(&r->pimpl->m_status);
378*c243e490SMarcel Moolenaar }
379*c243e490SMarcel Moolenaar 
380*c243e490SMarcel Moolenaar bool
381*c243e490SMarcel Moolenaar atf_check_result_signaled(const atf_check_result_t *r)
382*c243e490SMarcel Moolenaar {
383*c243e490SMarcel Moolenaar     return atf_process_status_signaled(&r->pimpl->m_status);
384*c243e490SMarcel Moolenaar }
385*c243e490SMarcel Moolenaar 
386*c243e490SMarcel Moolenaar int
387*c243e490SMarcel Moolenaar atf_check_result_termsig(const atf_check_result_t *r)
388*c243e490SMarcel Moolenaar {
389*c243e490SMarcel Moolenaar     return atf_process_status_termsig(&r->pimpl->m_status);
390*c243e490SMarcel Moolenaar }
391*c243e490SMarcel Moolenaar 
392*c243e490SMarcel Moolenaar /* ---------------------------------------------------------------------
393*c243e490SMarcel Moolenaar  * Free functions.
394*c243e490SMarcel Moolenaar  * --------------------------------------------------------------------- */
395*c243e490SMarcel Moolenaar 
396*c243e490SMarcel Moolenaar /* XXX: This function shouldn't be in this module.  It messes with stdout
397*c243e490SMarcel Moolenaar  * and stderr, and it provides a very high-end interface.  This belongs,
398*c243e490SMarcel Moolenaar  * probably, somewhere related to test cases (such as in the tc module). */
399*c243e490SMarcel Moolenaar atf_error_t
400*c243e490SMarcel Moolenaar atf_check_build_c_o(const char *sfile,
401*c243e490SMarcel Moolenaar                     const char *ofile,
402*c243e490SMarcel Moolenaar                     const char *const optargs[],
403*c243e490SMarcel Moolenaar                     bool *success)
404*c243e490SMarcel Moolenaar {
405*c243e490SMarcel Moolenaar     atf_error_t err;
406*c243e490SMarcel Moolenaar     char **argv;
407*c243e490SMarcel Moolenaar 
408*c243e490SMarcel Moolenaar     err = atf_build_c_o(sfile, ofile, optargs, &argv);
409*c243e490SMarcel Moolenaar     if (atf_is_error(err))
410*c243e490SMarcel Moolenaar         goto out;
411*c243e490SMarcel Moolenaar 
412*c243e490SMarcel Moolenaar     err = check_build_run((const char *const *)argv, success);
413*c243e490SMarcel Moolenaar 
414*c243e490SMarcel Moolenaar     atf_utils_free_charpp(argv);
415*c243e490SMarcel Moolenaar out:
416*c243e490SMarcel Moolenaar     return err;
417*c243e490SMarcel Moolenaar }
418*c243e490SMarcel Moolenaar 
419*c243e490SMarcel Moolenaar atf_error_t
420*c243e490SMarcel Moolenaar atf_check_build_cpp(const char *sfile,
421*c243e490SMarcel Moolenaar                     const char *ofile,
422*c243e490SMarcel Moolenaar                     const char *const optargs[],
423*c243e490SMarcel Moolenaar                     bool *success)
424*c243e490SMarcel Moolenaar {
425*c243e490SMarcel Moolenaar     atf_error_t err;
426*c243e490SMarcel Moolenaar     char **argv;
427*c243e490SMarcel Moolenaar 
428*c243e490SMarcel Moolenaar     err = atf_build_cpp(sfile, ofile, optargs, &argv);
429*c243e490SMarcel Moolenaar     if (atf_is_error(err))
430*c243e490SMarcel Moolenaar         goto out;
431*c243e490SMarcel Moolenaar 
432*c243e490SMarcel Moolenaar     err = check_build_run((const char *const *)argv, success);
433*c243e490SMarcel Moolenaar 
434*c243e490SMarcel Moolenaar     atf_utils_free_charpp(argv);
435*c243e490SMarcel Moolenaar out:
436*c243e490SMarcel Moolenaar     return err;
437*c243e490SMarcel Moolenaar }
438*c243e490SMarcel Moolenaar 
439*c243e490SMarcel Moolenaar atf_error_t
440*c243e490SMarcel Moolenaar atf_check_build_cxx_o(const char *sfile,
441*c243e490SMarcel Moolenaar                       const char *ofile,
442*c243e490SMarcel Moolenaar                       const char *const optargs[],
443*c243e490SMarcel Moolenaar                       bool *success)
444*c243e490SMarcel Moolenaar {
445*c243e490SMarcel Moolenaar     atf_error_t err;
446*c243e490SMarcel Moolenaar     char **argv;
447*c243e490SMarcel Moolenaar 
448*c243e490SMarcel Moolenaar     err = atf_build_cxx_o(sfile, ofile, optargs, &argv);
449*c243e490SMarcel Moolenaar     if (atf_is_error(err))
450*c243e490SMarcel Moolenaar         goto out;
451*c243e490SMarcel Moolenaar 
452*c243e490SMarcel Moolenaar     err = check_build_run((const char *const *)argv, success);
453*c243e490SMarcel Moolenaar 
454*c243e490SMarcel Moolenaar     atf_utils_free_charpp(argv);
455*c243e490SMarcel Moolenaar out:
456*c243e490SMarcel Moolenaar     return err;
457*c243e490SMarcel Moolenaar }
458*c243e490SMarcel Moolenaar 
459*c243e490SMarcel Moolenaar atf_error_t
460*c243e490SMarcel Moolenaar atf_check_exec_array(const char *const *argv, atf_check_result_t *r)
461*c243e490SMarcel Moolenaar {
462*c243e490SMarcel Moolenaar     atf_error_t err;
463*c243e490SMarcel Moolenaar     atf_fs_path_t dir;
464*c243e490SMarcel Moolenaar 
465*c243e490SMarcel Moolenaar     err = create_tmpdir(&dir);
466*c243e490SMarcel Moolenaar     if (atf_is_error(err))
467*c243e490SMarcel Moolenaar         goto out;
468*c243e490SMarcel Moolenaar 
469*c243e490SMarcel Moolenaar     err = atf_check_result_init(r, argv, &dir);
470*c243e490SMarcel Moolenaar     if (atf_is_error(err)) {
471*c243e490SMarcel Moolenaar         atf_error_t err2 = atf_fs_rmdir(&dir);
472*c243e490SMarcel Moolenaar         INV(!atf_is_error(err2));
473*c243e490SMarcel Moolenaar         goto out;
474*c243e490SMarcel Moolenaar     }
475*c243e490SMarcel Moolenaar 
476*c243e490SMarcel Moolenaar     err = fork_and_wait(argv, &r->pimpl->m_stdout, &r->pimpl->m_stderr,
477*c243e490SMarcel Moolenaar                         &r->pimpl->m_status);
478*c243e490SMarcel Moolenaar     if (atf_is_error(err)) {
479*c243e490SMarcel Moolenaar         atf_check_result_fini(r);
480*c243e490SMarcel Moolenaar         goto out;
481*c243e490SMarcel Moolenaar     }
482*c243e490SMarcel Moolenaar 
483*c243e490SMarcel Moolenaar     INV(!atf_is_error(err));
484*c243e490SMarcel Moolenaar 
485*c243e490SMarcel Moolenaar     atf_fs_path_fini(&dir);
486*c243e490SMarcel Moolenaar out:
487*c243e490SMarcel Moolenaar     return err;
488*c243e490SMarcel Moolenaar }
489