Home | History | Annotate | Download | only in execve
      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