/*
 * exec.c
 * exec  will execute the different exec functions depending 
 * on the argument given. 
 *
 * to compile: gcc -O -pipe exec.c -o exec 
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

/* 
 * These are defined just for simplicity. 
 * Remember, the arguments to the exec
 * functions are similar to the command line
 * arguments to a program, and are only
 * a series of strings. 
 */
#define NAMED_COM   ("/usr/bin/find")
#define PATH_COM    ("find")
#define ARGS_SIZE   (6)
#define EXEC_ARG_0  ("find")
#define EXEC_ARG_1  ("/var/")
#define EXEC_ARG_2  ("-name")
#define EXEC_ARG_3  ("core")
#define EXEC_ARG_4  ("-print")
#define PATH_ENV    ("PATH=/bin:/usr/bin")

#define EXECL       (1)
#define EXECLE      (2)
#define EXECLP      (3)
#define EXECV       (4)
#define EXECVP      (5)

extern char **environ;

/* declerations */
void do_execvp(void);
void do_execl(void);
void do_execle(void);
void do_execlp(void);
void do_execv(void);



int main(int argc, char **argv)
{
	int which;

	/* first argument is always our program name !*/
	if( argc > 1 )
	{
		which = atoi(argv[1]);
		switch( which )
		{
			case EXECL:
				do_execl();
				break;

			case EXECLE:
				do_execle();
				break;

			case EXECLP:
				do_execlp();
				break;

			case EXECV:
				do_execv();
				break;

			case EXECVP:
				do_execvp();
				break;

			default:
				printf("Must specify a value between 1 and 5\n");

		} /* switch */

		/* not reached */
		printf("exec function failed !\n");

	} /* if(argc) */

	/* FIN */
	return(0);
}

/*
 * do_execl
 * This function will demonstrate how to
 * call the execl function. Note that for this
 * function, because the list is sequential, you
 * need to know how many arguments the program 
 * will need.
 */
void do_execl()
{
	/* simply list the arguments in order */
	execl(NAMED_COM, EXEC_ARG_0, EXEC_ARG_1,EXEC_ARG_2,
			EXEC_ARG_3, EXEC_ARG_4, NULL );
}


/*
 * do_execle
 * This function will demonstrate how to
 * call the execle function and specify 
 * its environment. Setting the environment
 * is useful when you need to make sure a
 * specific path is set. 
 */
void do_execle()
{
	char *env[2] = { PATH_ENV, NULL};

	/* same as execl, except we need to specify the environment */
	execle(NAMED_COM, EXEC_ARG_0, EXEC_ARG_1,EXEC_ARG_2,
			 EXEC_ARG_3, EXEC_ARG_4, NULL, env );

}

/*
 * do_execlp
 * This function will demonstrate how to
 * call the execlp function. Note that you 
 * don't have to specify the full path to 
 * the program; the execlp function
 * will determine that from the PATH 
 * environment variable. 
 */
void do_execlp()
{
	/* simply list the arguments in order */
	execlp(PATH_COM, EXEC_ARG_0, EXEC_ARG_1,EXEC_ARG_2,
			 EXEC_ARG_3, EXEC_ARG_4, NULL );

}

/*
 * do_execv
 * This function will demonstrate how to
 * call the execv function. Note that the
 * arguments are just a NULL terminated array.
 * Therefore, you can use this function if you 
 * do not know how many arguments are needed.
 * In this case however, the number is known.
 */
void do_execv()
{
	char *args[ARGS_SIZE];

	/* Prepare our arguments */
	args[0] = EXEC_ARG_0;
	args[1] = EXEC_ARG_1;
	args[2] = EXEC_ARG_2;
	args[3] = EXEC_ARG_3;
	args[4] = EXEC_ARG_4;
	args[5] = NULL;

	/* now call execvp  */
	execv(NAMED_COM, args);

}

/*
 * do_execvp
 * This function demonstrates how to set
 * the PATH environment variable, and 
 * call the execvp function. 
 */
void do_execvp()
{
	char *args[ARGS_SIZE];

	/* Prepare our arguments */
	args[0] = EXEC_ARG_0;
	args[1] = EXEC_ARG_1;
	args[2] = EXEC_ARG_2;
	args[3] = EXEC_ARG_3;
	args[4] = EXEC_ARG_4;
	args[5] = NULL;

	/* set the PATH var in the environment */
	putenv(PATH_ENV);
	/* now call execvp  */
	execvp(PATH_COM, args);
}



syntax highlighted by Code2HTML, v. 0.9