1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * NAME 22 * execve05.c 23 * 24 * DESCRIPTION 25 * This testcase tests the basic functionality of the execve(2) system 26 * call. 27 * 28 * ALGORITHM 29 * This program also gets the names "test1", and "test2". This tests 30 * the functionality of the execve(2) system call by spawning a few 31 * children, each of which would execute "test1/test2" executables, and 32 * finally the parent ensures that they terminated correctly. 33 * 34 * USAGE 35 * execve05 20 test1 test2 4 36 * 37 * RESTRICTIONS 38 * This program does not follow the LTP format - *PLEASE FIX* 39 */ 40 41 #include <stdio.h> 42 #include <errno.h> 43 #include <sys/types.h> 44 #include <sys/stat.h> 45 #include <sys/wait.h> 46 #include "test.h" 47 48 #undef DEBUG /* change this to #define if needed */ 49 50 void setup(void); 51 void cleanup(void); 52 53 char *TCID = "execve05"; 54 int TST_TOTAL = 1; 55 56 int iterations; 57 char *fname1; 58 char *fname2; 59 char *prog; 60 char *av[6]; 61 char *ev[1]; 62 63 void usage(void) 64 { 65 tst_brkm(TBROK, NULL, "usage: %s <iters> <fname1> <fname2> <count>", 66 TCID); 67 } 68 69 int main(int ac, char **av) 70 { 71 char iter[20]; 72 int count, i, nchild, status; 73 pid_t pid; 74 75 int lc; 76 77 tst_parse_opts(ac, av, NULL, NULL); 78 79 setup(); 80 81 if (ac != 5) 82 usage(); 83 84 for (lc = 0; TEST_LOOPING(lc); lc++) { 85 86 tst_count = 0; 87 88 prog = av[0]; 89 iterations = atoi(av[1]); 90 fname1 = av[2]; 91 fname2 = av[3]; 92 count = atoi(av[4]); 93 #ifdef DEBUG 94 tst_resm(TINFO, "Entered %s %d %s %s %d -- pid = %d", prog, 95 iterations, fname1, fname2, count, getpid()); 96 #endif 97 98 if (iterations == 0) { 99 tst_resm(TPASS, "Test DONE, pid %d, -- %s %d %s %s", 100 getpid(), prog, iterations, fname1, fname2); 101 tst_exit(); 102 } 103 104 if (!count) { 105 sprintf(iter, "%d", iterations - 1); 106 av[0] = fname1; 107 av[1] = iter; 108 av[2] = fname1; 109 av[3] = fname2; 110 av[4] = "0"; 111 av[5] = 0; 112 ev[0] = 0; 113 #ifdef DEBUG 114 tst_resm(TINFO, "doing execve(%s, av, ev)", fname1); 115 tst_resm(TINFO, "av[0,1,2,3,4] = %s, %s, %s, %s, %s", 116 av[0], av[1], av[2], av[3], av[4]); 117 #endif 118 (void)execve(fname1, av, ev); 119 tst_resm(TFAIL, "Execve fail, %s, errno=%d", fname1, 120 errno); 121 } 122 123 nchild = count * 2; 124 125 sprintf(iter, "%d", iterations); 126 for (i = 0; i < count; i++) { 127 128 pid = FORK_OR_VFORK(); 129 if (pid == -1) { 130 perror("fork failed"); 131 exit(1); 132 } else if (pid == 0) { 133 av[0] = fname1; 134 av[1] = iter; 135 av[2] = fname1; 136 av[3] = fname2; 137 av[4] = "0"; 138 av[5] = 0; 139 ev[0] = 0; 140 (void)execve(fname1, av, ev); 141 perror("execve failed"); 142 exit(2); 143 } 144 #ifdef DEBUG 145 tst_resm(TINFO, "Main - started pid %d", pid); 146 #endif 147 if (wait(&status) == -1) 148 tst_brkm(TBROK | TERRNO, cleanup, 149 "wait failed"); 150 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 151 tst_resm(TFAIL, "child exited abnormally"); 152 153 pid = FORK_OR_VFORK(); 154 if (pid == -1) { 155 perror("Fork failed"); 156 exit(1); 157 } else if (pid == 0) { 158 av[0] = fname2; 159 av[1] = iter; 160 av[2] = fname2; 161 av[3] = fname1; 162 av[4] = "0"; 163 av[5] = 0; 164 ev[0] = 0; 165 execve(fname2, av, ev); 166 perror("execve failed"); 167 exit(2); 168 } 169 #ifdef DEBUG 170 tst_resm(TINFO, "Main - started pid %d", pid); 171 #endif 172 if (wait(&status) == -1) 173 tst_brkm(TBROK | TERRNO, cleanup, 174 "wait failed"); 175 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 176 tst_resm(TFAIL, "child exited abnormally"); 177 178 } 179 180 if (wait(&status) != -1) 181 tst_brkm(TBROK, cleanup, 182 "leftover children haven't exited yet"); 183 184 } 185 cleanup(); 186 187 tst_exit(); 188 } 189 190 void setup(void) 191 { 192 193 tst_sig(FORK, DEF_HANDLER, cleanup); 194 195 TEST_PAUSE; 196 197 umask(0); 198 } 199 200 void cleanup(void) 201 { 202 } 203