1*640235e2SEnji Cooper /* $NetBSD: t_spawn.c,v 1.2 2014/10/18 08:33:30 snj Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*-
457718be8SEnji Cooper * Copyright (c) 2012 The NetBSD Foundation, Inc.
557718be8SEnji Cooper * All rights reserved.
657718be8SEnji Cooper *
757718be8SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation
857718be8SEnji Cooper * by Charles Zhang <charles@NetBSD.org> and
957718be8SEnji Cooper * Martin Husemann <martin@NetBSD.org>.
1057718be8SEnji Cooper *
1157718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
1257718be8SEnji Cooper * modification, are permitted provided that the following conditions
1357718be8SEnji Cooper * are met:
1457718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
1557718be8SEnji Cooper * notice, this list of conditions and the following disclaimer.
1657718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1757718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the
1857718be8SEnji Cooper * documentation and/or other materials provided with the distribution.
1957718be8SEnji Cooper *
2057718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2157718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2257718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2357718be8SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2457718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2557718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2657718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2757718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2857718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2957718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3057718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
3157718be8SEnji Cooper */
3257718be8SEnji Cooper
3357718be8SEnji Cooper
3457718be8SEnji Cooper #include <atf-c.h>
3557718be8SEnji Cooper #include <spawn.h>
3657718be8SEnji Cooper #include <string.h>
3757718be8SEnji Cooper #include <stdio.h>
3857718be8SEnji Cooper #include <stdlib.h>
3957718be8SEnji Cooper #include <errno.h>
4057718be8SEnji Cooper #include <sys/wait.h>
4157718be8SEnji Cooper
4257718be8SEnji Cooper ATF_TC(t_spawn_ls);
4357718be8SEnji Cooper
ATF_TC_HEAD(t_spawn_ls,tc)4457718be8SEnji Cooper ATF_TC_HEAD(t_spawn_ls, tc)
4557718be8SEnji Cooper {
4657718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
4757718be8SEnji Cooper "Tests a simple posix_spawn executing /bin/ls");
4857718be8SEnji Cooper }
4957718be8SEnji Cooper
ATF_TC_BODY(t_spawn_ls,tc)5057718be8SEnji Cooper ATF_TC_BODY(t_spawn_ls, tc)
5157718be8SEnji Cooper {
5257718be8SEnji Cooper char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
5357718be8SEnji Cooper int err;
5457718be8SEnji Cooper
5557718be8SEnji Cooper err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL);
5657718be8SEnji Cooper ATF_REQUIRE(err == 0);
5757718be8SEnji Cooper }
5857718be8SEnji Cooper
5957718be8SEnji Cooper ATF_TC(t_spawnp_ls);
6057718be8SEnji Cooper
ATF_TC_HEAD(t_spawnp_ls,tc)6157718be8SEnji Cooper ATF_TC_HEAD(t_spawnp_ls, tc)
6257718be8SEnji Cooper {
6357718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
6457718be8SEnji Cooper "Tests a simple posix_spawnp executing ls via $PATH");
6557718be8SEnji Cooper }
6657718be8SEnji Cooper
ATF_TC_BODY(t_spawnp_ls,tc)6757718be8SEnji Cooper ATF_TC_BODY(t_spawnp_ls, tc)
6857718be8SEnji Cooper {
6957718be8SEnji Cooper char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
7057718be8SEnji Cooper int err;
7157718be8SEnji Cooper
7257718be8SEnji Cooper err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL);
7357718be8SEnji Cooper ATF_REQUIRE(err == 0);
7457718be8SEnji Cooper }
7557718be8SEnji Cooper
7657718be8SEnji Cooper ATF_TC(t_spawn_zero);
7757718be8SEnji Cooper
ATF_TC_HEAD(t_spawn_zero,tc)7857718be8SEnji Cooper ATF_TC_HEAD(t_spawn_zero, tc)
7957718be8SEnji Cooper {
8057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
8157718be8SEnji Cooper "posix_spawn an invalid binary");
8257718be8SEnji Cooper }
8357718be8SEnji Cooper
ATF_TC_BODY(t_spawn_zero,tc)8457718be8SEnji Cooper ATF_TC_BODY(t_spawn_zero, tc)
8557718be8SEnji Cooper {
8657718be8SEnji Cooper char buf[FILENAME_MAX];
8757718be8SEnji Cooper char * const args[] = { __UNCONST("h_zero"), NULL };
8857718be8SEnji Cooper int err;
8957718be8SEnji Cooper
9057718be8SEnji Cooper snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir"));
9157718be8SEnji Cooper err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
9257718be8SEnji Cooper ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf);
9357718be8SEnji Cooper }
9457718be8SEnji Cooper
9557718be8SEnji Cooper ATF_TC(t_spawn_missing);
9657718be8SEnji Cooper
ATF_TC_HEAD(t_spawn_missing,tc)9757718be8SEnji Cooper ATF_TC_HEAD(t_spawn_missing, tc)
9857718be8SEnji Cooper {
9957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
10057718be8SEnji Cooper "posix_spawn a non existant binary");
10157718be8SEnji Cooper }
10257718be8SEnji Cooper
ATF_TC_BODY(t_spawn_missing,tc)10357718be8SEnji Cooper ATF_TC_BODY(t_spawn_missing, tc)
10457718be8SEnji Cooper {
10557718be8SEnji Cooper char buf[FILENAME_MAX];
10657718be8SEnji Cooper char * const args[] = { __UNCONST("h_nonexist"), NULL };
10757718be8SEnji Cooper int err;
10857718be8SEnji Cooper
10957718be8SEnji Cooper snprintf(buf, sizeof buf, "%s/h_nonexist",
11057718be8SEnji Cooper atf_tc_get_config_var(tc, "srcdir"));
11157718be8SEnji Cooper err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
11257718be8SEnji Cooper ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
11357718be8SEnji Cooper }
11457718be8SEnji Cooper
11557718be8SEnji Cooper ATF_TC(t_spawn_nonexec);
11657718be8SEnji Cooper
ATF_TC_HEAD(t_spawn_nonexec,tc)11757718be8SEnji Cooper ATF_TC_HEAD(t_spawn_nonexec, tc)
11857718be8SEnji Cooper {
11957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
12057718be8SEnji Cooper "posix_spawn a script with non existing interpreter");
12157718be8SEnji Cooper }
12257718be8SEnji Cooper
ATF_TC_BODY(t_spawn_nonexec,tc)12357718be8SEnji Cooper ATF_TC_BODY(t_spawn_nonexec, tc)
12457718be8SEnji Cooper {
12557718be8SEnji Cooper char buf[FILENAME_MAX];
12657718be8SEnji Cooper char * const args[] = { __UNCONST("h_nonexec"), NULL };
12757718be8SEnji Cooper int err;
12857718be8SEnji Cooper
12957718be8SEnji Cooper snprintf(buf, sizeof buf, "%s/h_nonexec",
13057718be8SEnji Cooper atf_tc_get_config_var(tc, "srcdir"));
13157718be8SEnji Cooper err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
13257718be8SEnji Cooper ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
13357718be8SEnji Cooper }
13457718be8SEnji Cooper
13557718be8SEnji Cooper ATF_TC(t_spawn_child);
13657718be8SEnji Cooper
ATF_TC_HEAD(t_spawn_child,tc)13757718be8SEnji Cooper ATF_TC_HEAD(t_spawn_child, tc)
13857718be8SEnji Cooper {
13957718be8SEnji Cooper atf_tc_set_md_var(tc, "descr",
140*640235e2SEnji Cooper "posix_spawn a child and get its return code");
14157718be8SEnji Cooper }
14257718be8SEnji Cooper
ATF_TC_BODY(t_spawn_child,tc)14357718be8SEnji Cooper ATF_TC_BODY(t_spawn_child, tc)
14457718be8SEnji Cooper {
14557718be8SEnji Cooper char buf[FILENAME_MAX];
14657718be8SEnji Cooper char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL };
14757718be8SEnji Cooper char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL };
14857718be8SEnji Cooper char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL };
14957718be8SEnji Cooper int err, status;
15057718be8SEnji Cooper pid_t pid;
15157718be8SEnji Cooper
15257718be8SEnji Cooper snprintf(buf, sizeof buf, "%s/h_spawn",
15357718be8SEnji Cooper atf_tc_get_config_var(tc, "srcdir"));
15457718be8SEnji Cooper
15557718be8SEnji Cooper err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL);
15657718be8SEnji Cooper ATF_REQUIRE(err == 0);
15757718be8SEnji Cooper ATF_REQUIRE(pid > 0);
15857718be8SEnji Cooper waitpid(pid, &status, 0);
15957718be8SEnji Cooper ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
16057718be8SEnji Cooper
16157718be8SEnji Cooper err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL);
16257718be8SEnji Cooper ATF_REQUIRE(err == 0);
16357718be8SEnji Cooper ATF_REQUIRE(pid > 0);
16457718be8SEnji Cooper waitpid(pid, &status, 0);
16557718be8SEnji Cooper ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1);
16657718be8SEnji Cooper
16757718be8SEnji Cooper err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL);
16857718be8SEnji Cooper ATF_REQUIRE(err == 0);
16957718be8SEnji Cooper ATF_REQUIRE(pid > 0);
17057718be8SEnji Cooper waitpid(pid, &status, 0);
17157718be8SEnji Cooper ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7);
17257718be8SEnji Cooper }
17357718be8SEnji Cooper
ATF_TP_ADD_TCS(tp)17457718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
17557718be8SEnji Cooper {
17657718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawn_ls);
17757718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawnp_ls);
17857718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawn_zero);
17957718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawn_missing);
18057718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawn_nonexec);
18157718be8SEnji Cooper ATF_TP_ADD_TC(tp, t_spawn_child);
18257718be8SEnji Cooper
18357718be8SEnji Cooper return atf_no_error();
18457718be8SEnji Cooper }
185