Before going into the details of the exec calls, we need to detour for a moment to talk about the environment of a UNIX program, since this information is passed to the exec calls either explicitly or implicitly.
The environment UNIX mantains for each user is, by definition, an array of strings, each having the form "VARIABLE=value", where both VARIABLE and value can be any string. This list contains entries like:
The environment is passed to a C program through the third (optional, and often unnoticed) argument of its main() function, whose complete prototype in traditional UNIX is:
int main(int argc, char *argv, char *envp);As every C programmer knows, the first argument is the program's arguments count, the second is the list of the arguments - including the program name on top -, and then comes the environment. So, for example, when you type at the UNIX shell prompt:
% mv Budweiser McFarlan
to rename file Budweiser as McFarlan (an unlikely promotion, indeed), the mv program - which is written in C as all UNIX commands - gets a 3 in the argc argument, the strings "mv", "Budweiser" and "McFarlan" in argv, and the user environment strings in envp. No count is passed for the number of elements stored in envp: here a convention is used, i.e. to have a NULL character pointer as the last element, so that a program scanning it from beginning to end can tell when it's finished.
If a program needs accessing the environment, it could in theory scan those strings, looking for the variable(s) it needs, then parse that string, if it finds it, and get as the value whatever follows the `=' sign. However, a much simpler way is to use the getenv() system call, which is kindly provided for this purpose. You just pass it a string with the name of the variable that you want to know about, and it returns a string (i.e. a pointer to char) with the value, or NULL it that variable is not defined in the environment. It is left as an exercise to the reader to find why the putenv() call in named so and what it does. The presence of getenv() is the reason why the third argument to main() is optional, and usually omitted. However, envp and/or the environ variable come handy when:
Before going on, let's also take a minute to remember that the environment is not the only thing that UNIX grants to a program when it starts. Among the other housekeeping chores, it automatically opens for the process three files, respectively with descriptors 0 for standard input (hence open O_RDONLY), 1 for standard output and 2 for standard error (both O_WRONLY | O_APPEND - why not just O_WRONLY?).