#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void
print_args(const char* where, int argc, char *argv[])
{
if (argc >= 0) {
printf("Number of arguments: %d\n", argc);
}
printf("%s these arguments and their memory locations:\n", where);
printf("via argv @ %p\n", (void *) argv);
for (int i = 0; argv[i] != NULL; i++) {
printf(" argv[%d] = %p: %s\n", i, (void *) argv[i], argv[i]);
}
printf("\n");
}
static char prog_name[] = "exec-demo";
static char from_str[] = "from";
static char exec_str[] = "exec";
static char hello_str[] = "Hello";
static char world_str[] = "World";
static char *new_argv[] = {prog_name, hello_str, world_str,
from_str, exec_str, NULL};
/*
* This is actually two programs in one. An "executor" that calls execve to
* run the "executee" program. It can tell which one it is by the number of
* arguments it receives (no arguments means it's the executor).
*/
int
main(int argc, char *argv[])
{
int dummy = 0;
if (argc == 1) {
printf("=== Executor === (stack at %p)\n\n", (void *) &dummy);
/* Mix things up a bit */
new_argv[0] = argv[0];
new_argv[2] = strdup("Universe");
print_args("Sending", -1, new_argv);
printf("Calling execve...\n\n");
execve(argv[0], new_argv, NULL);
// If execve returns, it must have failed
perror("execve");
exit(1);
} else {
printf("=== Executee === (stack at %p)\n\n", (void *) &dummy);
print_args("Received", argc, argv);
}
return 0;
}