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 #include "safe_macros.h"
48 
49 #undef DEBUG			/* change this to #define if needed */
50 
51 void setup(void);
52 void cleanup(void);
53 
54 char *TCID = "execve05";
55 int TST_TOTAL = 1;
56 
57 int iterations;
58 char *fname1;
59 char *fname2;
60 char *prog;
61 char *av[6];
62 char *ev[1];
63 
usage(void)64 void usage(void)
65 {
66 	tst_brkm(TBROK, NULL, "usage: %s <iters> <fname1> <fname2> <count>",
67 		 TCID);
68 }
69 
main(int ac,char ** av)70 int main(int ac, char **av)
71 {
72 	char iter[20];
73 	int count, i, nchild, status;
74 	pid_t pid;
75 
76 	int lc;
77 
78 	tst_parse_opts(ac, av, NULL, NULL);
79 
80 	setup();
81 
82 	if (ac != 5)
83 		usage();
84 
85 	for (lc = 0; TEST_LOOPING(lc); lc++) {
86 
87 		tst_count = 0;
88 
89 		prog = av[0];
90 		iterations = atoi(av[1]);
91 		fname1 = av[2];
92 		fname2 = av[3];
93 		count = atoi(av[4]);
94 #ifdef DEBUG
95 		tst_resm(TINFO, "Entered %s %d %s %s %d -- pid = %d", prog,
96 			 iterations, fname1, fname2, count, getpid());
97 #endif
98 
99 		if (iterations == 0) {
100 			tst_resm(TPASS, "Test DONE, pid %d, -- %s %d %s %s",
101 				 getpid(), prog, iterations, fname1, fname2);
102 			tst_exit();
103 		}
104 
105 		if (!count) {
106 			sprintf(iter, "%d", iterations - 1);
107 			av[0] = fname1;
108 			av[1] = iter;
109 			av[2] = fname1;
110 			av[3] = fname2;
111 			av[4] = "0";
112 			av[5] = 0;
113 			ev[0] = 0;
114 #ifdef DEBUG
115 			tst_resm(TINFO, "doing execve(%s, av, ev)", fname1);
116 			tst_resm(TINFO, "av[0,1,2,3,4] = %s, %s, %s, %s, %s",
117 				 av[0], av[1], av[2], av[3], av[4]);
118 #endif
119 			(void)execve(fname1, av, ev);
120 			tst_resm(TFAIL, "Execve fail, %s, errno=%d", fname1,
121 				 errno);
122 		}
123 
124 		nchild = count * 2;
125 
126 		sprintf(iter, "%d", iterations);
127 		for (i = 0; i < count; i++) {
128 
129 			pid = FORK_OR_VFORK();
130 			if (pid == -1) {
131 				perror("fork failed");
132 				exit(1);
133 			} else if (pid == 0) {
134 				av[0] = fname1;
135 				av[1] = iter;
136 				av[2] = fname1;
137 				av[3] = fname2;
138 				av[4] = "0";
139 				av[5] = 0;
140 				ev[0] = 0;
141 				(void)execve(fname1, av, ev);
142 				perror("execve failed");
143 				exit(2);
144 			}
145 #ifdef DEBUG
146 			tst_resm(TINFO, "Main - started pid %d", pid);
147 #endif
148 			SAFE_WAIT(cleanup, &status);
149 			if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
150 				tst_resm(TFAIL, "child exited abnormally");
151 
152 			pid = FORK_OR_VFORK();
153 			if (pid == -1) {
154 				perror("Fork failed");
155 				exit(1);
156 			} else if (pid == 0) {
157 				av[0] = fname2;
158 				av[1] = iter;
159 				av[2] = fname2;
160 				av[3] = fname1;
161 				av[4] = "0";
162 				av[5] = 0;
163 				ev[0] = 0;
164 				execve(fname2, av, ev);
165 				perror("execve failed");
166 				exit(2);
167 			}
168 #ifdef DEBUG
169 			tst_resm(TINFO, "Main - started pid %d", pid);
170 #endif
171 			SAFE_WAIT(cleanup, &status);
172 			if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
173 				tst_resm(TFAIL, "child exited abnormally");
174 
175 		}
176 
177 		if (wait(&status) != -1)
178 			tst_brkm(TBROK, cleanup,
179 				 "leftover children haven't exited yet");
180 
181 	}
182 	cleanup();
183 
184 	tst_exit();
185 }
186 
setup(void)187 void setup(void)
188 {
189 
190 	tst_sig(FORK, DEF_HANDLER, cleanup);
191 
192 	TEST_PAUSE;
193 
194 	umask(0);
195 }
196 
cleanup(void)197 void cleanup(void)
198 {
199 }
200