in reply to Re^2: Set env variables as part of a command
in thread Set env variables as part of a command
So forking the process is that like creating a subshell
Excatly. That's the beauty of fork+exec, inherited from C. (Things are quite different on Windows. Perl emulates fork and exec, which makes some things quite messy.)
fork() creates an exact clone of your currently running process, including environment, file handles and all data, except for process ID and parent process ID. (Most operating systems now use a copy-on-write mechanism, so that immediately after fork(), both process use exactly the same data. The first memory write in parent or child process transparently creates a real copy of the affected memory page. But that's an implementation detail. In the old days, fork() did a complete copy.) And yes, a successful fork() returns twice: once in the parent process, returning the process ID of the child process, and once in the child process, returning 0.
exec() replaces the current process with another executable. Again, everything but the actual executable <UPDATE>and signal handlers</UPDATE> stays unchanged. Things like file handles, environment, and even the process ID stay the same. Command line arguments do change, to those passed to exec(). <UPDATE>Non-ignored signal handlers are reset to defaults.</UPDATE>
Between fork() and exec(), in the (temporary) child process, you can change every aspect of the process you want: current directory, environment, file handles (for things like redirection), current user, current group.
It's so simple that fork() does not even take arguments, and exec() just needs the name of the executable and the new command line arguments.
Compare that with CreateProcess(), requiring no less than 10 arguments, four of them pointers to structures with 2 to 18 members, so that you effectively pass more than 30 parameters to CreateProcess(). Do you think that's sufficient? No, sorry. If you want to run a process as a different user, you need another function called CreateProcessAsUser(), taking 11 arguments. Obviously, that's still not sufficient, there are two more functions CreateProcessWithLogonW() and CreateProcessWithTokenW(). Don't ask me what happens there, I simply don't want to know that.