t_spawn.c revision 313498
1/* $NetBSD: t_spawn.c,v 1.2 2014/10/18 08:33:30 snj 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 42ATF_TC(t_spawn_ls); 43 44ATF_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 50ATF_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 59ATF_TC(t_spawnp_ls); 60 61ATF_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 67ATF_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 76ATF_TC(t_spawn_zero); 77 78ATF_TC_HEAD(t_spawn_zero, tc) 79{ 80 atf_tc_set_md_var(tc, "descr", 81 "posix_spawn an invalid binary"); 82} 83 84ATF_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 95ATF_TC(t_spawn_missing); 96 97ATF_TC_HEAD(t_spawn_missing, tc) 98{ 99 atf_tc_set_md_var(tc, "descr", 100 "posix_spawn a non existant binary"); 101} 102 103ATF_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 115ATF_TC(t_spawn_nonexec); 116 117ATF_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 123ATF_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 135ATF_TC(t_spawn_child); 136 137ATF_TC_HEAD(t_spawn_child, tc) 138{ 139 atf_tc_set_md_var(tc, "descr", 140 "posix_spawn a child and get its return code"); 141} 142 143ATF_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 174ATF_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