111be35a1SLionel Sambuc /*
211be35a1SLionel Sambuc * Automated Testing Framework (atf)
311be35a1SLionel Sambuc *
411be35a1SLionel Sambuc * Copyright (c) 2008 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc * All rights reserved.
611be35a1SLionel Sambuc *
711be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without
811be35a1SLionel Sambuc * modification, are permitted provided that the following conditions
911be35a1SLionel Sambuc * are met:
1011be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
1111be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer.
1211be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
1311be35a1SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
1411be35a1SLionel Sambuc * documentation and/or other materials provided with the distribution.
1511be35a1SLionel Sambuc *
1611be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
1711be35a1SLionel Sambuc * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1811be35a1SLionel Sambuc * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1911be35a1SLionel Sambuc * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2011be35a1SLionel Sambuc * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
2111be35a1SLionel Sambuc * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2211be35a1SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2311be35a1SLionel Sambuc * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2411be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2511be35a1SLionel Sambuc * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2611be35a1SLionel Sambuc * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
2711be35a1SLionel Sambuc * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2811be35a1SLionel Sambuc */
2911be35a1SLionel Sambuc
3011be35a1SLionel Sambuc #include <sys/wait.h>
3111be35a1SLionel Sambuc
3211be35a1SLionel Sambuc #include <errno.h>
3311be35a1SLionel Sambuc #include <fcntl.h>
3411be35a1SLionel Sambuc #include <stdio.h>
3511be35a1SLionel Sambuc #include <stdlib.h>
3611be35a1SLionel Sambuc #include <string.h>
3711be35a1SLionel Sambuc #include <unistd.h>
3811be35a1SLionel Sambuc
3911be35a1SLionel Sambuc #include "atf-c/build.h"
4011be35a1SLionel Sambuc #include "atf-c/check.h"
4111be35a1SLionel Sambuc #include "atf-c/config.h"
4211be35a1SLionel Sambuc #include "atf-c/defs.h"
4311be35a1SLionel Sambuc #include "atf-c/error.h"
4411be35a1SLionel Sambuc #include "atf-c/utils.h"
4511be35a1SLionel Sambuc
4611be35a1SLionel Sambuc #include "detail/dynstr.h"
4711be35a1SLionel Sambuc #include "detail/fs.h"
4811be35a1SLionel Sambuc #include "detail/list.h"
4911be35a1SLionel Sambuc #include "detail/process.h"
5011be35a1SLionel Sambuc #include "detail/sanity.h"
5111be35a1SLionel Sambuc
5211be35a1SLionel Sambuc /* ---------------------------------------------------------------------
5311be35a1SLionel Sambuc * Auxiliary functions.
5411be35a1SLionel Sambuc * --------------------------------------------------------------------- */
5511be35a1SLionel Sambuc
5611be35a1SLionel Sambuc static
5711be35a1SLionel Sambuc atf_error_t
create_tmpdir(atf_fs_path_t * dir)5811be35a1SLionel Sambuc create_tmpdir(atf_fs_path_t *dir)
5911be35a1SLionel Sambuc {
6011be35a1SLionel Sambuc atf_error_t err;
6111be35a1SLionel Sambuc
6211be35a1SLionel Sambuc err = atf_fs_path_init_fmt(dir, "%s/check.XXXXXX",
6311be35a1SLionel Sambuc atf_config_get("atf_workdir"));
6411be35a1SLionel Sambuc if (atf_is_error(err))
6511be35a1SLionel Sambuc goto out;
6611be35a1SLionel Sambuc
6711be35a1SLionel Sambuc err = atf_fs_mkdtemp(dir);
6811be35a1SLionel Sambuc if (atf_is_error(err)) {
6911be35a1SLionel Sambuc atf_fs_path_fini(dir);
7011be35a1SLionel Sambuc goto out;
7111be35a1SLionel Sambuc }
7211be35a1SLionel Sambuc
7311be35a1SLionel Sambuc INV(!atf_is_error(err));
7411be35a1SLionel Sambuc out:
7511be35a1SLionel Sambuc return err;
7611be35a1SLionel Sambuc }
7711be35a1SLionel Sambuc
7811be35a1SLionel Sambuc static
7911be35a1SLionel Sambuc void
cleanup_tmpdir(const atf_fs_path_t * dir,const atf_fs_path_t * outfile,const atf_fs_path_t * errfile)8011be35a1SLionel Sambuc cleanup_tmpdir(const atf_fs_path_t *dir, const atf_fs_path_t *outfile,
8111be35a1SLionel Sambuc const atf_fs_path_t *errfile)
8211be35a1SLionel Sambuc {
8311be35a1SLionel Sambuc {
8411be35a1SLionel Sambuc atf_error_t err = atf_fs_unlink(outfile);
8511be35a1SLionel Sambuc if (atf_is_error(err)) {
8611be35a1SLionel Sambuc INV(atf_error_is(err, "libc") &&
8711be35a1SLionel Sambuc atf_libc_error_code(err) == ENOENT);
8811be35a1SLionel Sambuc atf_error_free(err);
8911be35a1SLionel Sambuc } else
9011be35a1SLionel Sambuc INV(!atf_is_error(err));
9111be35a1SLionel Sambuc }
9211be35a1SLionel Sambuc
9311be35a1SLionel Sambuc {
9411be35a1SLionel Sambuc atf_error_t err = atf_fs_unlink(errfile);
9511be35a1SLionel Sambuc if (atf_is_error(err)) {
9611be35a1SLionel Sambuc INV(atf_error_is(err, "libc") &&
9711be35a1SLionel Sambuc atf_libc_error_code(err) == ENOENT);
9811be35a1SLionel Sambuc atf_error_free(err);
9911be35a1SLionel Sambuc } else
10011be35a1SLionel Sambuc INV(!atf_is_error(err));
10111be35a1SLionel Sambuc }
10211be35a1SLionel Sambuc
10311be35a1SLionel Sambuc {
104*3260d16fSLionel Sambuc #if defined(__minix) && !defined(NDEBUG)
105*3260d16fSLionel Sambuc atf_error_t err =
106*3260d16fSLionel Sambuc #endif /* defined(__minix) && !defined(NDEBUG) */
107*3260d16fSLionel Sambuc atf_fs_rmdir(dir);
10811be35a1SLionel Sambuc INV(!atf_is_error(err));
10911be35a1SLionel Sambuc }
11011be35a1SLionel Sambuc }
11111be35a1SLionel Sambuc
11211be35a1SLionel Sambuc static
11311be35a1SLionel Sambuc int
const_execvp(const char * file,const char * const * argv)11411be35a1SLionel Sambuc const_execvp(const char *file, const char *const *argv)
11511be35a1SLionel Sambuc {
11611be35a1SLionel Sambuc #define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
11711be35a1SLionel Sambuc return execvp(file, UNCONST(argv));
11811be35a1SLionel Sambuc #undef UNCONST
11911be35a1SLionel Sambuc }
12011be35a1SLionel Sambuc
12111be35a1SLionel Sambuc static
12211be35a1SLionel Sambuc atf_error_t
init_sb(const atf_fs_path_t * path,atf_process_stream_t * sb)12311be35a1SLionel Sambuc init_sb(const atf_fs_path_t *path, atf_process_stream_t *sb)
12411be35a1SLionel Sambuc {
12511be35a1SLionel Sambuc atf_error_t err;
12611be35a1SLionel Sambuc
12711be35a1SLionel Sambuc if (path == NULL)
12811be35a1SLionel Sambuc err = atf_process_stream_init_inherit(sb);
12911be35a1SLionel Sambuc else
13011be35a1SLionel Sambuc err = atf_process_stream_init_redirect_path(sb, path);
13111be35a1SLionel Sambuc
13211be35a1SLionel Sambuc return err;
13311be35a1SLionel Sambuc }
13411be35a1SLionel Sambuc
13511be35a1SLionel Sambuc static
13611be35a1SLionel Sambuc 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)13711be35a1SLionel Sambuc init_sbs(const atf_fs_path_t *outfile, atf_process_stream_t *outsb,
13811be35a1SLionel Sambuc const atf_fs_path_t *errfile, atf_process_stream_t *errsb)
13911be35a1SLionel Sambuc {
14011be35a1SLionel Sambuc atf_error_t err;
14111be35a1SLionel Sambuc
14211be35a1SLionel Sambuc err = init_sb(outfile, outsb);
14311be35a1SLionel Sambuc if (atf_is_error(err))
14411be35a1SLionel Sambuc goto out;
14511be35a1SLionel Sambuc
14611be35a1SLionel Sambuc err = init_sb(errfile, errsb);
14711be35a1SLionel Sambuc if (atf_is_error(err)) {
14811be35a1SLionel Sambuc atf_process_stream_fini(outsb);
14911be35a1SLionel Sambuc goto out;
15011be35a1SLionel Sambuc }
15111be35a1SLionel Sambuc
15211be35a1SLionel Sambuc out:
15311be35a1SLionel Sambuc return err;
15411be35a1SLionel Sambuc }
15511be35a1SLionel Sambuc
15611be35a1SLionel Sambuc struct exec_data {
15711be35a1SLionel Sambuc const char *const *m_argv;
15811be35a1SLionel Sambuc };
15911be35a1SLionel Sambuc
16011be35a1SLionel Sambuc static void exec_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
16111be35a1SLionel Sambuc
16211be35a1SLionel Sambuc static
16311be35a1SLionel Sambuc void
exec_child(void * v)16411be35a1SLionel Sambuc exec_child(void *v)
16511be35a1SLionel Sambuc {
16611be35a1SLionel Sambuc struct exec_data *ea = v;
16711be35a1SLionel Sambuc
16811be35a1SLionel Sambuc const_execvp(ea->m_argv[0], ea->m_argv);
16911be35a1SLionel Sambuc fprintf(stderr, "execvp(%s) failed: %s\n", ea->m_argv[0], strerror(errno));
17011be35a1SLionel Sambuc exit(127);
17111be35a1SLionel Sambuc }
17211be35a1SLionel Sambuc
17311be35a1SLionel Sambuc static
17411be35a1SLionel Sambuc 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)17511be35a1SLionel Sambuc fork_and_wait(const char *const *argv, const atf_fs_path_t *outfile,
17611be35a1SLionel Sambuc const atf_fs_path_t *errfile, atf_process_status_t *status)
17711be35a1SLionel Sambuc {
17811be35a1SLionel Sambuc atf_error_t err;
17911be35a1SLionel Sambuc atf_process_child_t child;
18011be35a1SLionel Sambuc atf_process_stream_t outsb, errsb;
18111be35a1SLionel Sambuc struct exec_data ea = { argv };
18211be35a1SLionel Sambuc
18311be35a1SLionel Sambuc err = init_sbs(outfile, &outsb, errfile, &errsb);
18411be35a1SLionel Sambuc if (atf_is_error(err))
18511be35a1SLionel Sambuc goto out;
18611be35a1SLionel Sambuc
18711be35a1SLionel Sambuc err = atf_process_fork(&child, exec_child, &outsb, &errsb, &ea);
18811be35a1SLionel Sambuc if (atf_is_error(err))
18911be35a1SLionel Sambuc goto out_sbs;
19011be35a1SLionel Sambuc
19111be35a1SLionel Sambuc err = atf_process_child_wait(&child, status);
19211be35a1SLionel Sambuc
19311be35a1SLionel Sambuc out_sbs:
19411be35a1SLionel Sambuc atf_process_stream_fini(&errsb);
19511be35a1SLionel Sambuc atf_process_stream_fini(&outsb);
19611be35a1SLionel Sambuc out:
19711be35a1SLionel Sambuc return err;
19811be35a1SLionel Sambuc }
19911be35a1SLionel Sambuc
20011be35a1SLionel Sambuc static
20111be35a1SLionel Sambuc void
update_success_from_status(const char * progname,const atf_process_status_t * status,bool * success)20211be35a1SLionel Sambuc update_success_from_status(const char *progname,
20311be35a1SLionel Sambuc const atf_process_status_t *status, bool *success)
20411be35a1SLionel Sambuc {
20511be35a1SLionel Sambuc bool s = atf_process_status_exited(status) &&
20611be35a1SLionel Sambuc atf_process_status_exitstatus(status) == EXIT_SUCCESS;
20711be35a1SLionel Sambuc
20811be35a1SLionel Sambuc if (atf_process_status_exited(status)) {
20911be35a1SLionel Sambuc if (atf_process_status_exitstatus(status) == EXIT_SUCCESS)
21011be35a1SLionel Sambuc INV(s);
21111be35a1SLionel Sambuc else {
21211be35a1SLionel Sambuc INV(!s);
21311be35a1SLionel Sambuc fprintf(stderr, "%s failed with exit code %d\n", progname,
21411be35a1SLionel Sambuc atf_process_status_exitstatus(status));
21511be35a1SLionel Sambuc }
21611be35a1SLionel Sambuc } else if (atf_process_status_signaled(status)) {
21711be35a1SLionel Sambuc INV(!s);
21811be35a1SLionel Sambuc fprintf(stderr, "%s failed due to signal %d%s\n", progname,
21911be35a1SLionel Sambuc atf_process_status_termsig(status),
22011be35a1SLionel Sambuc atf_process_status_coredump(status) ? " (core dumped)" : "");
22111be35a1SLionel Sambuc } else {
22211be35a1SLionel Sambuc INV(!s);
22311be35a1SLionel Sambuc fprintf(stderr, "%s failed due to unknown reason\n", progname);
22411be35a1SLionel Sambuc }
22511be35a1SLionel Sambuc
22611be35a1SLionel Sambuc *success = s;
22711be35a1SLionel Sambuc }
22811be35a1SLionel Sambuc
22911be35a1SLionel Sambuc static
23011be35a1SLionel Sambuc atf_error_t
array_to_list(const char * const * a,atf_list_t * l)23111be35a1SLionel Sambuc array_to_list(const char *const *a, atf_list_t *l)
23211be35a1SLionel Sambuc {
23311be35a1SLionel Sambuc atf_error_t err;
23411be35a1SLionel Sambuc
23511be35a1SLionel Sambuc err = atf_list_init(l);
23611be35a1SLionel Sambuc if (atf_is_error(err))
23711be35a1SLionel Sambuc goto out;
23811be35a1SLionel Sambuc
23911be35a1SLionel Sambuc while (*a != NULL) {
24011be35a1SLionel Sambuc char *item = strdup(*a);
24111be35a1SLionel Sambuc if (item == NULL) {
24211be35a1SLionel Sambuc err = atf_no_memory_error();
24311be35a1SLionel Sambuc goto out;
24411be35a1SLionel Sambuc }
24511be35a1SLionel Sambuc
24611be35a1SLionel Sambuc err = atf_list_append(l, item, true);
24711be35a1SLionel Sambuc if (atf_is_error(err))
24811be35a1SLionel Sambuc goto out;
24911be35a1SLionel Sambuc
25011be35a1SLionel Sambuc a++;
25111be35a1SLionel Sambuc }
25211be35a1SLionel Sambuc
25311be35a1SLionel Sambuc out:
25411be35a1SLionel Sambuc return err;
25511be35a1SLionel Sambuc }
25611be35a1SLionel Sambuc
25711be35a1SLionel Sambuc static void
print_array(const char * const * array,const char * pfx)25811be35a1SLionel Sambuc print_array(const char *const *array, const char *pfx)
25911be35a1SLionel Sambuc {
26011be35a1SLionel Sambuc const char *const *ptr;
26111be35a1SLionel Sambuc
26211be35a1SLionel Sambuc printf("%s", pfx);
26311be35a1SLionel Sambuc for (ptr = array; *ptr != NULL; ptr++)
26411be35a1SLionel Sambuc printf(" %s", *ptr);
26511be35a1SLionel Sambuc printf("\n");
26611be35a1SLionel Sambuc }
26711be35a1SLionel Sambuc
26811be35a1SLionel Sambuc static
26911be35a1SLionel Sambuc atf_error_t
check_build_run(const char * const * argv,bool * success)27011be35a1SLionel Sambuc check_build_run(const char *const *argv, bool *success)
27111be35a1SLionel Sambuc {
27211be35a1SLionel Sambuc atf_error_t err;
27311be35a1SLionel Sambuc atf_process_status_t status;
27411be35a1SLionel Sambuc
27511be35a1SLionel Sambuc print_array(argv, ">");
27611be35a1SLionel Sambuc
27711be35a1SLionel Sambuc err = fork_and_wait(argv, NULL, NULL, &status);
27811be35a1SLionel Sambuc if (atf_is_error(err))
27911be35a1SLionel Sambuc goto out;
28011be35a1SLionel Sambuc
28111be35a1SLionel Sambuc update_success_from_status(argv[0], &status, success);
28211be35a1SLionel Sambuc atf_process_status_fini(&status);
28311be35a1SLionel Sambuc
28411be35a1SLionel Sambuc INV(!atf_is_error(err));
28511be35a1SLionel Sambuc out:
28611be35a1SLionel Sambuc return err;
28711be35a1SLionel Sambuc }
28811be35a1SLionel Sambuc
28911be35a1SLionel Sambuc /* ---------------------------------------------------------------------
29011be35a1SLionel Sambuc * The "atf_check_result" type.
29111be35a1SLionel Sambuc * --------------------------------------------------------------------- */
29211be35a1SLionel Sambuc
29311be35a1SLionel Sambuc struct atf_check_result_impl {
29411be35a1SLionel Sambuc atf_list_t m_argv;
29511be35a1SLionel Sambuc atf_fs_path_t m_dir;
29611be35a1SLionel Sambuc atf_fs_path_t m_stdout;
29711be35a1SLionel Sambuc atf_fs_path_t m_stderr;
29811be35a1SLionel Sambuc atf_process_status_t m_status;
29911be35a1SLionel Sambuc };
30011be35a1SLionel Sambuc
30111be35a1SLionel Sambuc static
30211be35a1SLionel Sambuc atf_error_t
atf_check_result_init(atf_check_result_t * r,const char * const * argv,const atf_fs_path_t * dir)30311be35a1SLionel Sambuc atf_check_result_init(atf_check_result_t *r, const char *const *argv,
30411be35a1SLionel Sambuc const atf_fs_path_t *dir)
30511be35a1SLionel Sambuc {
30611be35a1SLionel Sambuc atf_error_t err;
30711be35a1SLionel Sambuc
30811be35a1SLionel Sambuc r->pimpl = malloc(sizeof(struct atf_check_result_impl));
30911be35a1SLionel Sambuc if (r->pimpl == NULL)
31011be35a1SLionel Sambuc return atf_no_memory_error();
31111be35a1SLionel Sambuc
31211be35a1SLionel Sambuc err = array_to_list(argv, &r->pimpl->m_argv);
31311be35a1SLionel Sambuc if (atf_is_error(err))
31411be35a1SLionel Sambuc goto out;
31511be35a1SLionel Sambuc
31611be35a1SLionel Sambuc err = atf_fs_path_copy(&r->pimpl->m_dir, dir);
31711be35a1SLionel Sambuc if (atf_is_error(err))
31811be35a1SLionel Sambuc goto err_argv;
31911be35a1SLionel Sambuc
32011be35a1SLionel Sambuc err = atf_fs_path_init_fmt(&r->pimpl->m_stdout, "%s/stdout",
32111be35a1SLionel Sambuc atf_fs_path_cstring(dir));
32211be35a1SLionel Sambuc if (atf_is_error(err))
32311be35a1SLionel Sambuc goto err_dir;
32411be35a1SLionel Sambuc
32511be35a1SLionel Sambuc err = atf_fs_path_init_fmt(&r->pimpl->m_stderr, "%s/stderr",
32611be35a1SLionel Sambuc atf_fs_path_cstring(dir));
32711be35a1SLionel Sambuc if (atf_is_error(err))
32811be35a1SLionel Sambuc goto err_stdout;
32911be35a1SLionel Sambuc
33011be35a1SLionel Sambuc INV(!atf_is_error(err));
33111be35a1SLionel Sambuc goto out;
33211be35a1SLionel Sambuc
33311be35a1SLionel Sambuc err_stdout:
33411be35a1SLionel Sambuc atf_fs_path_fini(&r->pimpl->m_stdout);
33511be35a1SLionel Sambuc err_dir:
33611be35a1SLionel Sambuc atf_fs_path_fini(&r->pimpl->m_dir);
33711be35a1SLionel Sambuc err_argv:
33811be35a1SLionel Sambuc atf_list_fini(&r->pimpl->m_argv);
33911be35a1SLionel Sambuc out:
34011be35a1SLionel Sambuc return err;
34111be35a1SLionel Sambuc }
34211be35a1SLionel Sambuc
34311be35a1SLionel Sambuc void
atf_check_result_fini(atf_check_result_t * r)34411be35a1SLionel Sambuc atf_check_result_fini(atf_check_result_t *r)
34511be35a1SLionel Sambuc {
34611be35a1SLionel Sambuc atf_process_status_fini(&r->pimpl->m_status);
34711be35a1SLionel Sambuc
34811be35a1SLionel Sambuc cleanup_tmpdir(&r->pimpl->m_dir, &r->pimpl->m_stdout,
34911be35a1SLionel Sambuc &r->pimpl->m_stderr);
35011be35a1SLionel Sambuc atf_fs_path_fini(&r->pimpl->m_stdout);
35111be35a1SLionel Sambuc atf_fs_path_fini(&r->pimpl->m_stderr);
35211be35a1SLionel Sambuc atf_fs_path_fini(&r->pimpl->m_dir);
35311be35a1SLionel Sambuc
35411be35a1SLionel Sambuc atf_list_fini(&r->pimpl->m_argv);
35511be35a1SLionel Sambuc
35611be35a1SLionel Sambuc free(r->pimpl);
35711be35a1SLionel Sambuc }
35811be35a1SLionel Sambuc
35911be35a1SLionel Sambuc const char *
atf_check_result_stdout(const atf_check_result_t * r)36011be35a1SLionel Sambuc atf_check_result_stdout(const atf_check_result_t *r)
36111be35a1SLionel Sambuc {
36211be35a1SLionel Sambuc return atf_fs_path_cstring(&r->pimpl->m_stdout);
36311be35a1SLionel Sambuc }
36411be35a1SLionel Sambuc
36511be35a1SLionel Sambuc const char *
atf_check_result_stderr(const atf_check_result_t * r)36611be35a1SLionel Sambuc atf_check_result_stderr(const atf_check_result_t *r)
36711be35a1SLionel Sambuc {
36811be35a1SLionel Sambuc return atf_fs_path_cstring(&r->pimpl->m_stderr);
36911be35a1SLionel Sambuc }
37011be35a1SLionel Sambuc
37111be35a1SLionel Sambuc bool
atf_check_result_exited(const atf_check_result_t * r)37211be35a1SLionel Sambuc atf_check_result_exited(const atf_check_result_t *r)
37311be35a1SLionel Sambuc {
37411be35a1SLionel Sambuc return atf_process_status_exited(&r->pimpl->m_status);
37511be35a1SLionel Sambuc }
37611be35a1SLionel Sambuc
37711be35a1SLionel Sambuc int
atf_check_result_exitcode(const atf_check_result_t * r)37811be35a1SLionel Sambuc atf_check_result_exitcode(const atf_check_result_t *r)
37911be35a1SLionel Sambuc {
38011be35a1SLionel Sambuc return atf_process_status_exitstatus(&r->pimpl->m_status);
38111be35a1SLionel Sambuc }
38211be35a1SLionel Sambuc
38311be35a1SLionel Sambuc bool
atf_check_result_signaled(const atf_check_result_t * r)38411be35a1SLionel Sambuc atf_check_result_signaled(const atf_check_result_t *r)
38511be35a1SLionel Sambuc {
38611be35a1SLionel Sambuc return atf_process_status_signaled(&r->pimpl->m_status);
38711be35a1SLionel Sambuc }
38811be35a1SLionel Sambuc
38911be35a1SLionel Sambuc int
atf_check_result_termsig(const atf_check_result_t * r)39011be35a1SLionel Sambuc atf_check_result_termsig(const atf_check_result_t *r)
39111be35a1SLionel Sambuc {
39211be35a1SLionel Sambuc return atf_process_status_termsig(&r->pimpl->m_status);
39311be35a1SLionel Sambuc }
39411be35a1SLionel Sambuc
39511be35a1SLionel Sambuc /* ---------------------------------------------------------------------
39611be35a1SLionel Sambuc * Free functions.
39711be35a1SLionel Sambuc * --------------------------------------------------------------------- */
39811be35a1SLionel Sambuc
39911be35a1SLionel Sambuc /* XXX: This function shouldn't be in this module. It messes with stdout
40011be35a1SLionel Sambuc * and stderr, and it provides a very high-end interface. This belongs,
40111be35a1SLionel Sambuc * probably, somewhere related to test cases (such as in the tc module). */
40211be35a1SLionel Sambuc atf_error_t
atf_check_build_c_o(const char * sfile,const char * ofile,const char * const optargs[],bool * success)40311be35a1SLionel Sambuc atf_check_build_c_o(const char *sfile,
40411be35a1SLionel Sambuc const char *ofile,
40511be35a1SLionel Sambuc const char *const optargs[],
40611be35a1SLionel Sambuc bool *success)
40711be35a1SLionel Sambuc {
40811be35a1SLionel Sambuc atf_error_t err;
40911be35a1SLionel Sambuc char **argv;
41011be35a1SLionel Sambuc
41111be35a1SLionel Sambuc err = atf_build_c_o(sfile, ofile, optargs, &argv);
41211be35a1SLionel Sambuc if (atf_is_error(err))
41311be35a1SLionel Sambuc goto out;
41411be35a1SLionel Sambuc
41511be35a1SLionel Sambuc err = check_build_run((const char *const *)argv, success);
41611be35a1SLionel Sambuc
41711be35a1SLionel Sambuc atf_utils_free_charpp(argv);
41811be35a1SLionel Sambuc out:
41911be35a1SLionel Sambuc return err;
42011be35a1SLionel Sambuc }
42111be35a1SLionel Sambuc
42211be35a1SLionel Sambuc atf_error_t
atf_check_build_cpp(const char * sfile,const char * ofile,const char * const optargs[],bool * success)42311be35a1SLionel Sambuc atf_check_build_cpp(const char *sfile,
42411be35a1SLionel Sambuc const char *ofile,
42511be35a1SLionel Sambuc const char *const optargs[],
42611be35a1SLionel Sambuc bool *success)
42711be35a1SLionel Sambuc {
42811be35a1SLionel Sambuc atf_error_t err;
42911be35a1SLionel Sambuc char **argv;
43011be35a1SLionel Sambuc
43111be35a1SLionel Sambuc err = atf_build_cpp(sfile, ofile, optargs, &argv);
43211be35a1SLionel Sambuc if (atf_is_error(err))
43311be35a1SLionel Sambuc goto out;
43411be35a1SLionel Sambuc
43511be35a1SLionel Sambuc err = check_build_run((const char *const *)argv, success);
43611be35a1SLionel Sambuc
43711be35a1SLionel Sambuc atf_utils_free_charpp(argv);
43811be35a1SLionel Sambuc out:
43911be35a1SLionel Sambuc return err;
44011be35a1SLionel Sambuc }
44111be35a1SLionel Sambuc
44211be35a1SLionel Sambuc atf_error_t
atf_check_build_cxx_o(const char * sfile,const char * ofile,const char * const optargs[],bool * success)44311be35a1SLionel Sambuc atf_check_build_cxx_o(const char *sfile,
44411be35a1SLionel Sambuc const char *ofile,
44511be35a1SLionel Sambuc const char *const optargs[],
44611be35a1SLionel Sambuc bool *success)
44711be35a1SLionel Sambuc {
44811be35a1SLionel Sambuc atf_error_t err;
44911be35a1SLionel Sambuc char **argv;
45011be35a1SLionel Sambuc
45111be35a1SLionel Sambuc err = atf_build_cxx_o(sfile, ofile, optargs, &argv);
45211be35a1SLionel Sambuc if (atf_is_error(err))
45311be35a1SLionel Sambuc goto out;
45411be35a1SLionel Sambuc
45511be35a1SLionel Sambuc err = check_build_run((const char *const *)argv, success);
45611be35a1SLionel Sambuc
45711be35a1SLionel Sambuc atf_utils_free_charpp(argv);
45811be35a1SLionel Sambuc out:
45911be35a1SLionel Sambuc return err;
46011be35a1SLionel Sambuc }
46111be35a1SLionel Sambuc
46211be35a1SLionel Sambuc atf_error_t
atf_check_exec_array(const char * const * argv,atf_check_result_t * r)46311be35a1SLionel Sambuc atf_check_exec_array(const char *const *argv, atf_check_result_t *r)
46411be35a1SLionel Sambuc {
46511be35a1SLionel Sambuc atf_error_t err;
46611be35a1SLionel Sambuc atf_fs_path_t dir;
46711be35a1SLionel Sambuc
46811be35a1SLionel Sambuc err = create_tmpdir(&dir);
46911be35a1SLionel Sambuc if (atf_is_error(err))
47011be35a1SLionel Sambuc goto out;
47111be35a1SLionel Sambuc
47211be35a1SLionel Sambuc err = atf_check_result_init(r, argv, &dir);
47311be35a1SLionel Sambuc if (atf_is_error(err)) {
474*3260d16fSLionel Sambuc #if defined(__minix) && !defined(NDEBUG)
475*3260d16fSLionel Sambuc atf_error_t err2 =
476*3260d16fSLionel Sambuc #endif /* defined(__minix) && !defined(NDEBUG) */
477*3260d16fSLionel Sambuc atf_fs_rmdir(&dir);
47811be35a1SLionel Sambuc INV(!atf_is_error(err2));
47911be35a1SLionel Sambuc goto out;
48011be35a1SLionel Sambuc }
48111be35a1SLionel Sambuc
48211be35a1SLionel Sambuc err = fork_and_wait(argv, &r->pimpl->m_stdout, &r->pimpl->m_stderr,
48311be35a1SLionel Sambuc &r->pimpl->m_status);
48411be35a1SLionel Sambuc if (atf_is_error(err)) {
48511be35a1SLionel Sambuc atf_check_result_fini(r);
48611be35a1SLionel Sambuc goto out;
48711be35a1SLionel Sambuc }
48811be35a1SLionel Sambuc
48911be35a1SLionel Sambuc INV(!atf_is_error(err));
49011be35a1SLionel Sambuc
49111be35a1SLionel Sambuc atf_fs_path_fini(&dir);
49211be35a1SLionel Sambuc out:
49311be35a1SLionel Sambuc return err;
49411be35a1SLionel Sambuc }
495