The small oddity in the Unix exec*() family

February 2, 2021

When I recently wrote about find's -exec option, I casually talked about 'the exec() family of system calls'. This is an odd phrasing and sort of an odd thing to say about Unix system calls, because they don't usually come in families. So let's list off the exec() family:

execv() execve() execvp() execvpe()
execl() execlp() execle()

(This is the list on Linux and OpenBSD; the FreeBSD list has execvP() but not execvpe(). The POSIX version leaves out execvpe() and adds fexecve(), which I don't quite put into this exec() family.)

One of these things is not like the others. Out of the entire list of at least six exec() functions, generally only execve() is a system call; the other exec*() functions are library functions layered on top of it. That there are convenient library functions layered on top of a system call (or a bunch of them) isn't odd; that's what all of stdio is, for example. What makes this situation feel odd is that the names are so close to each other. I have a decent memory for Unix libc function names and most of the time I probably couldn't pick the actual exec() system call out of a lineup like this.

(Right now it's very much in my memory that execve() is the underlying system call on most Unixes, of course.)

This multiplicity goes all the way back to V7 Unix, which documents all of execl(), execv(), execle(), and execve() in its exec(2) manpage. In V7, as is the case today, the underlying system call is execve(), although it had a different system call name. Even V6 had execl() and execv() in the V6 exec(2) manpage.

(The V6 system call was just called exec and took only the program to be executed and argv. When V7 added the environment, it kept the V6 exec call but added a new exece system call that took the environment (well, envp) as an additional argument.)

PS: Some Unixes have underlying system calls that are variants of each other, due to the slow growth and improvement in the system call API over time (for example, to add 64-bit variants of what used to be 32-bit calls). However, usually you only use and think about the most recent version of the system call; they aren't a family of variants the way the exec() family is.

Written on 02 February 2021.
« Go 1.16 will make system calls through libc on OpenBSD
Junk email as a cover for more nefarious things »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Feb 2 23:47:51 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.