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
51void setup(void);
52void cleanup(void);
53
54char *TCID = "execve05";
55int TST_TOTAL = 1;
56
57int iterations;
58char *fname1;
59char *fname2;
60char *prog;
61char *av[6];
62char *ev[1];
63
64void usage(void)
65{
66	tst_brkm(TBROK, NULL, "usage: %s <iters> <fname1> <fname2> <count>",
67		 TCID);
68}
69
70int 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
187void setup(void)
188{
189
190	tst_sig(FORK, DEF_HANDLER, cleanup);
191
192	TEST_PAUSE;
193
194	umask(0);
195}
196
197void cleanup(void)
198{
199}
200