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