The small oddity in the Unix exec*()
family
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.
|
|