xref: /minix3/tests/lib/libc/gen/posix_spawn/t_spawn.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_spawn.c,v 1.2 2014/10/18 08:33:30 snj Exp $ */
211be35a1SLionel Sambuc 
311be35a1SLionel Sambuc /*-
411be35a1SLionel Sambuc  * Copyright (c) 2012 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc  * All rights reserved.
611be35a1SLionel Sambuc  *
711be35a1SLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
811be35a1SLionel Sambuc  * by Charles Zhang <charles@NetBSD.org> and
911be35a1SLionel Sambuc  * Martin Husemann <martin@NetBSD.org>.
1011be35a1SLionel Sambuc  *
1111be35a1SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
1211be35a1SLionel Sambuc  * modification, are permitted provided that the following conditions
1311be35a1SLionel Sambuc  * are met:
1411be35a1SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
1511be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
1611be35a1SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
1711be35a1SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
1811be35a1SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
1911be35a1SLionel Sambuc  *
2011be35a1SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2111be35a1SLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2211be35a1SLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2311be35a1SLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2411be35a1SLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2511be35a1SLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2611be35a1SLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2711be35a1SLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2811be35a1SLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2911be35a1SLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3011be35a1SLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
3111be35a1SLionel Sambuc  */
3211be35a1SLionel Sambuc 
3311be35a1SLionel Sambuc 
3411be35a1SLionel Sambuc #include <atf-c.h>
3511be35a1SLionel Sambuc #include <spawn.h>
3611be35a1SLionel Sambuc #include <string.h>
3711be35a1SLionel Sambuc #include <stdio.h>
3811be35a1SLionel Sambuc #include <stdlib.h>
3911be35a1SLionel Sambuc #include <errno.h>
4011be35a1SLionel Sambuc #include <sys/wait.h>
4111be35a1SLionel Sambuc 
4211be35a1SLionel Sambuc ATF_TC(t_spawn_ls);
4311be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawn_ls,tc)4411be35a1SLionel Sambuc ATF_TC_HEAD(t_spawn_ls, tc)
4511be35a1SLionel Sambuc {
4611be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
4711be35a1SLionel Sambuc 	    "Tests a simple posix_spawn executing /bin/ls");
4811be35a1SLionel Sambuc }
4911be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawn_ls,tc)5011be35a1SLionel Sambuc ATF_TC_BODY(t_spawn_ls, tc)
5111be35a1SLionel Sambuc {
5211be35a1SLionel Sambuc 	char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
5311be35a1SLionel Sambuc 	int err;
5411be35a1SLionel Sambuc 
5511be35a1SLionel Sambuc 	err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL);
5611be35a1SLionel Sambuc 	ATF_REQUIRE(err == 0);
5711be35a1SLionel Sambuc }
5811be35a1SLionel Sambuc 
5911be35a1SLionel Sambuc ATF_TC(t_spawnp_ls);
6011be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawnp_ls,tc)6111be35a1SLionel Sambuc ATF_TC_HEAD(t_spawnp_ls, tc)
6211be35a1SLionel Sambuc {
6311be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
6411be35a1SLionel Sambuc 	    "Tests a simple posix_spawnp executing ls via $PATH");
6511be35a1SLionel Sambuc }
6611be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawnp_ls,tc)6711be35a1SLionel Sambuc ATF_TC_BODY(t_spawnp_ls, tc)
6811be35a1SLionel Sambuc {
6911be35a1SLionel Sambuc 	char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
7011be35a1SLionel Sambuc 	int err;
7111be35a1SLionel Sambuc 
7211be35a1SLionel Sambuc 	err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL);
7311be35a1SLionel Sambuc 	ATF_REQUIRE(err == 0);
7411be35a1SLionel Sambuc }
7511be35a1SLionel Sambuc 
7611be35a1SLionel Sambuc ATF_TC(t_spawn_zero);
7711be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawn_zero,tc)7811be35a1SLionel Sambuc ATF_TC_HEAD(t_spawn_zero, tc)
7911be35a1SLionel Sambuc {
8011be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
8111be35a1SLionel Sambuc 	    "posix_spawn an invalid binary");
8211be35a1SLionel Sambuc }
8311be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawn_zero,tc)8411be35a1SLionel Sambuc ATF_TC_BODY(t_spawn_zero, tc)
8511be35a1SLionel Sambuc {
8611be35a1SLionel Sambuc 	char buf[FILENAME_MAX];
8711be35a1SLionel Sambuc 	char * const args[] = { __UNCONST("h_zero"), NULL };
8811be35a1SLionel Sambuc 	int err;
8911be35a1SLionel Sambuc 
9011be35a1SLionel Sambuc 	snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir"));
9111be35a1SLionel Sambuc 	err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
9211be35a1SLionel Sambuc 	ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf);
9311be35a1SLionel Sambuc }
9411be35a1SLionel Sambuc 
9511be35a1SLionel Sambuc ATF_TC(t_spawn_missing);
9611be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawn_missing,tc)9711be35a1SLionel Sambuc ATF_TC_HEAD(t_spawn_missing, tc)
9811be35a1SLionel Sambuc {
9911be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
10011be35a1SLionel Sambuc 	    "posix_spawn a non existant binary");
10111be35a1SLionel Sambuc }
10211be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawn_missing,tc)10311be35a1SLionel Sambuc ATF_TC_BODY(t_spawn_missing, tc)
10411be35a1SLionel Sambuc {
10511be35a1SLionel Sambuc 	char buf[FILENAME_MAX];
10611be35a1SLionel Sambuc 	char * const args[] = { __UNCONST("h_nonexist"), NULL };
10711be35a1SLionel Sambuc 	int err;
10811be35a1SLionel Sambuc 
10911be35a1SLionel Sambuc 	snprintf(buf, sizeof buf, "%s/h_nonexist",
11011be35a1SLionel Sambuc 	    atf_tc_get_config_var(tc, "srcdir"));
11111be35a1SLionel Sambuc 	err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
11211be35a1SLionel Sambuc 	ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
11311be35a1SLionel Sambuc }
11411be35a1SLionel Sambuc 
11511be35a1SLionel Sambuc ATF_TC(t_spawn_nonexec);
11611be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawn_nonexec,tc)11711be35a1SLionel Sambuc ATF_TC_HEAD(t_spawn_nonexec, tc)
11811be35a1SLionel Sambuc {
11911be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
12011be35a1SLionel Sambuc 	    "posix_spawn a script with non existing interpreter");
12111be35a1SLionel Sambuc }
12211be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawn_nonexec,tc)12311be35a1SLionel Sambuc ATF_TC_BODY(t_spawn_nonexec, tc)
12411be35a1SLionel Sambuc {
12511be35a1SLionel Sambuc 	char buf[FILENAME_MAX];
12611be35a1SLionel Sambuc 	char * const args[] = { __UNCONST("h_nonexec"), NULL };
12711be35a1SLionel Sambuc 	int err;
12811be35a1SLionel Sambuc 
12911be35a1SLionel Sambuc 	snprintf(buf, sizeof buf, "%s/h_nonexec",
13011be35a1SLionel Sambuc 	    atf_tc_get_config_var(tc, "srcdir"));
13111be35a1SLionel Sambuc 	err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
13211be35a1SLionel Sambuc 	ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
13311be35a1SLionel Sambuc }
13411be35a1SLionel Sambuc 
13511be35a1SLionel Sambuc ATF_TC(t_spawn_child);
13611be35a1SLionel Sambuc 
ATF_TC_HEAD(t_spawn_child,tc)13711be35a1SLionel Sambuc ATF_TC_HEAD(t_spawn_child, tc)
13811be35a1SLionel Sambuc {
13911be35a1SLionel Sambuc 	atf_tc_set_md_var(tc, "descr",
140*0a6a1f1dSLionel Sambuc 	    "posix_spawn a child and get its return code");
14111be35a1SLionel Sambuc }
14211be35a1SLionel Sambuc 
ATF_TC_BODY(t_spawn_child,tc)14311be35a1SLionel Sambuc ATF_TC_BODY(t_spawn_child, tc)
14411be35a1SLionel Sambuc {
14511be35a1SLionel Sambuc 	char buf[FILENAME_MAX];
14611be35a1SLionel Sambuc 	char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL };
14711be35a1SLionel Sambuc 	char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL };
14811be35a1SLionel Sambuc 	char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL };
14911be35a1SLionel Sambuc 	int err, status;
15011be35a1SLionel Sambuc 	pid_t pid;
15111be35a1SLionel Sambuc 
15211be35a1SLionel Sambuc 	snprintf(buf, sizeof buf, "%s/h_spawn",
15311be35a1SLionel Sambuc 	    atf_tc_get_config_var(tc, "srcdir"));
15411be35a1SLionel Sambuc 
15511be35a1SLionel Sambuc 	err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL);
15611be35a1SLionel Sambuc 	ATF_REQUIRE(err == 0);
15711be35a1SLionel Sambuc 	ATF_REQUIRE(pid > 0);
15811be35a1SLionel Sambuc 	waitpid(pid, &status, 0);
15911be35a1SLionel Sambuc 	ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
16011be35a1SLionel Sambuc 
16111be35a1SLionel Sambuc 	err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL);
16211be35a1SLionel Sambuc 	ATF_REQUIRE(err == 0);
16311be35a1SLionel Sambuc 	ATF_REQUIRE(pid > 0);
16411be35a1SLionel Sambuc 	waitpid(pid, &status, 0);
16511be35a1SLionel Sambuc 	ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1);
16611be35a1SLionel Sambuc 
16711be35a1SLionel Sambuc 	err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL);
16811be35a1SLionel Sambuc 	ATF_REQUIRE(err == 0);
16911be35a1SLionel Sambuc 	ATF_REQUIRE(pid > 0);
17011be35a1SLionel Sambuc 	waitpid(pid, &status, 0);
17111be35a1SLionel Sambuc 	ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7);
17211be35a1SLionel Sambuc }
17311be35a1SLionel Sambuc 
ATF_TP_ADD_TCS(tp)17411be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp)
17511be35a1SLionel Sambuc {
17611be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawn_ls);
17711be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawnp_ls);
17811be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawn_zero);
17911be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawn_missing);
18011be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawn_nonexec);
18111be35a1SLionel Sambuc 	ATF_TP_ADD_TC(tp, t_spawn_child);
18211be35a1SLionel Sambuc 
18311be35a1SLionel Sambuc 	return atf_no_error();
18411be35a1SLionel Sambuc }
185