I have written child command execution code for Win32 using CreateProcess:
CreateProcessW(NULL, // app
&commandW[0], // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&startup_info, // STARTUPINFOW pointer
&process_info); // receives PROCESS_INFORMATION
This uses a “trick” and puts the whole command in the second argument, which normally only contains the arguments being passed to the program. I want to do the same thing for POSIX, but the same “trick” doesn’t work with the execlp function (and I bet all the others as well). Is there any way to still use a single std::string command and to start a process? Splitting the command into an executable filename and the arguments would be possible, but a lot of work I’d like to avoid if possible.
You could invoke a shell, and pass the big string to the shell, and let the shell deal with it. Try it yourself:
(i.e. pass two arguments, “
-c” and the big string containing the command and arguments)Even better: Make the first command
exec, which will make your new process “replace” the shell that it spawned, then no one will even know that it was launched using a shell.As pointed out in the comments by @ecatmur, this is the exact functionality of the
systemcall.But you are opening yourself up to potential (serious) problems: You now have to deal with quoting and escaping of characters. The shell can (and will) interpret any special characters unless they are escaped, and any arguments that have spaces must be properly quoted.
There is a reason that Unix-like operating systems handle arguments the way that they do.
My opinion is that the Windows method is fundamentally flawed. It’s a serious design oversight that prevents you from passing complex strings as command line arguments to other programs.