-exec
команды find
и
ненароком упомянул о семействе системных вызовов
exec()
. Это странное выражение, обычно о Unix-вызовах
так не говорят, так как они, как правило, не объединяются в некие
семейства. Но в данном случае речь идёт о целом наборе схожих
механизмов. Перечислим их:
execv() execve() execvp() execvpe()execl() execlp() execle()
(Этот список выглядит именно так в Linux и в OpenBSD; подобный список, составленный для FreeBSD, включал бы в себя
execvP()
, а не execvpe()
. В
POSIX-версии подобного списка нет вызова
execvpe()
, но есть вызов fexecve()
,
который я не вполне готов включить в семейство вызовов
exec()
.)Одна из этих команд не похожа на другие. На самом деле, во всём этом списке, включающем в себя, как минимум, шесть
exec()
-функций, лишь execve()
относится к
системным вызовам; остальные exec*()
-функции это
просто библиотечные функции, в основе которых лежит
execve()
. То, что существуют удобные библиотечные
функции, основанные на системном вызове (или на нескольких
вызовах), не является чем-то необычным; так, например, устроено всё
то, что имеет отношение к stdio
. Но всё это выглядит
несколько странно из-за того, что имена функций весьма близки друг
к другу. У меня хорошая память на имена libc
-функций
Unix, но я, вероятно, в большинстве случаев, не смог бы выделить из
вышеприведённого списка настоящий системный вызов
exec()
.(Сейчас-то я, конечно, хорошо помню о том, что
execve()
это системный вызов, который, в большинстве
Unix-дистрибутивов, лежит в основе
exec*()
-функций.)Такое множество функций со схожими именами существует со времён V7 Unix, где документация по
execl()
,
execv()
, execle()
и execve()
размещена в справочном файле
exec(2). В V7, по состоянию на сегодняшний день, базовым
системным вызовом является execve()
, хотя ему
назначено другое имя. Даже в V6 execl()
и
execv()
описаны в единственном справочном файле
exec(2).(Соответствующий системный вызов V6 был назван
exec
и
принимал лишь программу, которую нужно выполнить, и
argv
. Когда в V7 появилось такое понятие, как
окружение, там сохранился системный вызов exec
из V6,
который, в качестве дополнительного аргумента, принимал
envp
.)P.S. В некоторых дистрибутивах Unix есть базовые системные вызовы, которые, по сути, являются разновидностями одного и того же вызова. Такая ситуация сложилась из-за того, что API системных вызовов развивался и совершенствовался достаточно длительное время. Например, подобное могло произойти при добавлении в систему 64-битных вариантов вызовов, которые раньше были 32-битными. Правда, обычно в сознании людей присутствуют лишь самые свежие версии системных вызовов; они не представлены некими семействами разновидностей какого-то вызова и в этом смысле не похожи на семейство
exec()
.Встречались ли вы с какими-то странностями, касающимися именования сущностей в Unix?