I am trying to code a program that launches a child process and the child process will execute the program with the arguments entered in the command line.
This is what the command line should look like.
./launch program arg1 arg2 arg3
argv[0] = "./launch"
argv[1] = "program" --> This is the program I want the child process to run. (program.cpp is already compiled when ./launch runs)
argv[2] = "arg1"
argv[3] = "arg2"
argv[4] = "arg3"
I want to be able to pass argv[2],argv[3],argv[4] into the child process. I do this using the execve method.
When I run "./launch program arg1 arg2 arg3 "
The child process does spawn and run but only argv[1] and argv[2] show in the child processes char*argv[].
LaunchProcess.cpp
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
pid_t spawnChild(const char* program, char** arg_list) {
pid_t ch_pid = fork();
if(ch_pid < 0){
exit(EXITFAILURE);
} else if (ch_pid >0){
std::cout <<"Spawned Child with Process Identification: " << ch_pid<< std::endl;
return ch_pid;
} else {
execve(program,arg_list,nullptr);
}
}
int main(int argc, char *argv[]){
char *arguments[argc-2];
std::string program_name = argv[1];
for (int i = 2; i < argc; i ) {
arguments[i-2] = argv[i];
//std::cout << arguments[i-2] << std::endl;
}
}
char *arg_list[] = {const_cast <char *>(program_name.data()), *arguments, nullptr};
spawnChild(program_name.c_str(), arg_list);
}
program.cpp
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i )
printf("Argument %d is %s\n", i, argv[i]);
return 0;
}
Output
Spawned Child with Process Identification: 44331
Argument 0 is program
Argument 1 is arg1
child 44331 terminated
I think I am passing in args_list into execve wrong. That would be my guess. This question may be trivial but I have been stuck on it for some time. Any help would be appreciated.
CodePudding user response:
You appear to assume that *arguments
will expand to multiple items, but this is a Python list unpacking feature that C does not have. Instead, C/C uses *
here for pointer dereferencing.
Your statement will therefore declare a nullptr-terminated list of two arguments, rather than N arguments the way you appear to intend:
char *arg_list[] = {const_cast <char *>(program_name.data()), *arguments, nullptr};
Rewrite your code to correctly build the argument list, e.g. by adding them to a std::vector<char*>
. You can use a debugger or something like for(int i=0; arg_list[i] != nullptr; i ) printf("Arg %d: %s\n", i, arg_list[i]);
to verify that the list is correct.