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