The "p" suffix versions will search the directories in your PATH environment variable to find the executable. You've probably noticed that all the examples have a hard-coded location for the executable: /bin/ls and /usr/bin/spellcheck. What about other executables? Unless you want to first find out the exact path for that particular program, it would be best to have the user tell your program all the places to search for executables. The standard PATH environment variable does just that. Here's the one from a minimal system:
PATH=/proc/boot:/bin
This tells the shell that when I type a command, it should first look in the directory /proc/boot, and if it can't find the command there, it should look in the binaries directory /bin part. PATH is a colon-separated list of places to look for commands. You can add as many elements to the PATH as you want, but keep in mind that all pathname components will be searched (in order) for the executable.
If you don't know the path to the executable, then you can use the "p" variants. For example:
// Using an explicit path: execl ("/bin/ls", "/bin/ls", "-l", "-t", "-r", NULL); // Search your PATH for the executable: execlp ("ls", "ls", "-l", "-t", "-r", NULL);
If execl() can't find ls in /bin, it returns an error. The execlp() function will search all the directories specified in the PATH for ls, and will return an error only if it can't find ls in any of those directories. This is also great for multiplatform support—your program doesn't have to be coded to know about the different CPU names, it just finds the executable.
What if you do something like this?
execlp ("/bin/ls", "ls", "-l", "-t", "-r", NULL);
Does it search the environment? No. You told execlp() to use an explicit pathname, which overrides the normal PATH searching rule. If it doesn't find ls in /bin that's it, no other attempts are made (this is identical to the way execl() works in this case).
Is it dangerous to mix an explicit path with a plain command name (e.g., the path argument /bin/ls, and the command name argument ls, instead of /bin/ls)? This is usually pretty safe, because:
The only compelling reason for specifying the full pathname for the first argument is that the program can print out diagnostics including this first argument, which can instantly tell you where the program was invoked from. This may be important when the program can be found in multiple locations along the PATH.
The spawn() functions all have an extra parameter; in all the above examples, I've always specified P_WAIT. There are four flags you can pass to spawn() to change its behavior:
It's generally clearer to use the exec() call if that's what you meant—it saves the maintainer of the software from having to look up P_OVERLAY in the C Library Reference!