1 /* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2012 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles Zhang <charles@NetBSD.org> and 9 * Martin Husemann <martin@NetBSD.org>. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 #include <atf-c.h> 35 #include <spawn.h> 36 #include <string.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <errno.h> 40 #include <sys/wait.h> 41 42 ATF_TC(t_spawn_ls); 43 44 ATF_TC_HEAD(t_spawn_ls, tc) 45 { 46 atf_tc_set_md_var(tc, "descr", 47 "Tests a simple posix_spawn executing /bin/ls"); 48 } 49 50 ATF_TC_BODY(t_spawn_ls, tc) 51 { 52 char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; 53 int err; 54 55 err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL); 56 ATF_REQUIRE(err == 0); 57 } 58 59 ATF_TC(t_spawnp_ls); 60 61 ATF_TC_HEAD(t_spawnp_ls, tc) 62 { 63 atf_tc_set_md_var(tc, "descr", 64 "Tests a simple posix_spawnp executing ls via $PATH"); 65 } 66 67 ATF_TC_BODY(t_spawnp_ls, tc) 68 { 69 char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; 70 int err; 71 72 err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL); 73 ATF_REQUIRE(err == 0); 74 } 75 76 ATF_TC(t_spawn_zero); 77 78 ATF_TC_HEAD(t_spawn_zero, tc) 79 { 80 atf_tc_set_md_var(tc, "descr", 81 "posix_spawn an invalid binary"); 82 } 83 84 ATF_TC_BODY(t_spawn_zero, tc) 85 { 86 char buf[FILENAME_MAX]; 87 char * const args[] = { __UNCONST("h_zero"), NULL }; 88 int err; 89 90 snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); 91 err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); 92 ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); 93 } 94 95 ATF_TC(t_spawn_missing); 96 97 ATF_TC_HEAD(t_spawn_missing, tc) 98 { 99 atf_tc_set_md_var(tc, "descr", 100 "posix_spawn a non existant binary"); 101 } 102 103 ATF_TC_BODY(t_spawn_missing, tc) 104 { 105 char buf[FILENAME_MAX]; 106 char * const args[] = { __UNCONST("h_nonexist"), NULL }; 107 int err; 108 109 snprintf(buf, sizeof buf, "%s/h_nonexist", 110 atf_tc_get_config_var(tc, "srcdir")); 111 err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); 112 ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); 113 } 114 115 ATF_TC(t_spawn_nonexec); 116 117 ATF_TC_HEAD(t_spawn_nonexec, tc) 118 { 119 atf_tc_set_md_var(tc, "descr", 120 "posix_spawn a script with non existing interpreter"); 121 } 122 123 ATF_TC_BODY(t_spawn_nonexec, tc) 124 { 125 char buf[FILENAME_MAX]; 126 char * const args[] = { __UNCONST("h_nonexec"), NULL }; 127 int err; 128 129 snprintf(buf, sizeof buf, "%s/h_nonexec", 130 atf_tc_get_config_var(tc, "srcdir")); 131 err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); 132 ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); 133 } 134 135 ATF_TC(t_spawn_child); 136 137 ATF_TC_HEAD(t_spawn_child, tc) 138 { 139 atf_tc_set_md_var(tc, "descr", 140 "posix_spawn a child and get it's return code"); 141 } 142 143 ATF_TC_BODY(t_spawn_child, tc) 144 { 145 char buf[FILENAME_MAX]; 146 char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; 147 char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; 148 char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; 149 int err, status; 150 pid_t pid; 151 152 snprintf(buf, sizeof buf, "%s/h_spawn", 153 atf_tc_get_config_var(tc, "srcdir")); 154 155 err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); 156 ATF_REQUIRE(err == 0); 157 ATF_REQUIRE(pid > 0); 158 waitpid(pid, &status, 0); 159 ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); 160 161 err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); 162 ATF_REQUIRE(err == 0); 163 ATF_REQUIRE(pid > 0); 164 waitpid(pid, &status, 0); 165 ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); 166 167 err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); 168 ATF_REQUIRE(err == 0); 169 ATF_REQUIRE(pid > 0); 170 waitpid(pid, &status, 0); 171 ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); 172 } 173 174 ATF_TP_ADD_TCS(tp) 175 { 176 ATF_TP_ADD_TC(tp, t_spawn_ls); 177 ATF_TP_ADD_TC(tp, t_spawnp_ls); 178 ATF_TP_ADD_TC(tp, t_spawn_zero); 179 ATF_TP_ADD_TC(tp, t_spawn_missing); 180 ATF_TP_ADD_TC(tp, t_spawn_nonexec); 181 ATF_TP_ADD_TC(tp, t_spawn_child); 182 183 return atf_no_error(); 184 } 185