Reputation: 2766
I would like to prepare an old-school argument vector (argv) to use within the function
int execve(const char *filename, char *const argv[],char *const envp[]);
I tried it with the stl::vector class:
std::string arguments = std::string("arg1");
std::vector<char*> argv;
char argument[128];
strcpy(argument, arguments.c_str());
argv.push_back(argument);
argv.push_back('\0'); // finish argv with zero
Finally I pass the vector to execve()
execve("bashscriptXY", &argv[0], NULL)
The code compiles but ArgV gets "ignored" by execve(). So it seems to be wrong, what I'm trying. How should I build an argV in a efficient way with c++?
Upvotes: 5
Views: 4938
Reputation: 42257
I think the char[128] is redundant as the string local will have the same lifetime, also, try adding the program as argv[0] like rossoft said in his answer:
const std::string arguments("arg1");
std::vector<const char*> argv;
argv.push_back("bashscriptXY");
// The string will live as long as a locally allocated char*
argv.push_back(arguments.c_str());
argv.push_back(NULL); // finish argv with zero
execve(argv[0], &argv[0], NULL);
Upvotes: 5
Reputation: 340316
A few issues:
argv
array is supposed to be the program nameargv
vector can take char const*
types as execve()
doesn't modify the args (though the process that gets invoked might - but those will be copies in its own address space). So you can push c_str()
strings onto it.Try this out:
// unfortunately, execve() wants an array of `char*`, not
// am array of `char const*`.
// So we we need to make sure the string data is
// actually null terminated
inline
std::string& null_terminate( std::string& s)
{
s.append( 1, 0);
return s;
}
// ...
std::string program = std::string( "bashscriptXY");
std::string arg1("arg1");
std::string arg2("arg2");
null_terminate(program);
null_terminate(arg1);
null_terminate(arg2);
std::vector<char *> argv;
argv.push_back( &program[0]);
argv.push_back( &arg1[0]);
argv.push_back( &arg2[0]);
argv.push_back( NULL); // finish argv with zero
intptr_t result = execve( program.c_str(), &argv[0], NULL);
Upvotes: 2
Reputation: 2182
Beware that argv[0]
is always the name of the command itself. So if you want to pass 1 parameter to a program, you have to fill two elements:
argv[0]
should be "bashscriptXY
" (or whatever you want...)
argv[1] = "your_argument"
Upvotes: 5
Reputation: 1913
Unless the arguments are hard-coded, you'll have to do some dynamic memory allocation. First, create an array of character pointers for the number of arguments, then allocate memory for each argument and copy the data in.
This question is very similar and includes some code solutions.
Upvotes: 1