int execve(const char *filename, char *const argv[], char *const envp[]);
ОПИСАНИЕ
execve()
выполняет программу, заданную параметром
filename.
Программа должна быть или двоичным исполняемым файлом, или скриптом,
начинающимся со строки вида "#! интерпретатор [аргументы]".
В последнем случае интерпретатор -- это правильный путь к исполняемому
файлу, который не является скриптом; этот файл будет выполнен как
интерпретатор [arg] filename.
argv
-- это массив строк, аргументов новой программы.
envp
-- это массив строк в формате
key=value,
которые передаются новой программе в качестве окружения
(environment). Как
argv,
так и
envp
завершаются нулевым указателем. К массиву аргументов и к окружению
можно обратиться из функции
main(),
которая объявлена как
int main(int argc, char *argv[], char *envp[]).
execve()
не возвращает управление при успешном выполнении, а код, данные, bss
и стек вызвавшего процесса перезаписываются
кодом, данными и стеком загруженной программы. Новая программа также
наследует от вызвавшего процесса его идентификатор и открытые файловые
дескрипторы, на которых не было флага закрыть-при-exec (close-on-exec,
COE). Сигналы, ожидающие обработки, удаляются. Переопределённые
обработчики сигналов возвращаются в значение по умолчанию.
Обработчик сигнала SIGCHLD (когда установлен в SIG_IGN) может быть
сброшен или не сброшен в SIG_DFL.
Если текущая программа выполнялась под управлением ptrace, то после
успешного
execve()
ей посылается сигнал
SIGTRAP.
Если на файле программы
filename
установлен setuid-бит, то фактический идентификатор пользователя
вызывавшего процесса меняется на идентификатор владельца файла
программы. Точно так же, если на файле программы установлен
setgid-бит, то фактический идентификатор группы устанавливается в
группу файла программы.
Если исполняемый файл является динамически-скомпонованным файлом в
формате a.out, содержащим заглушки для вызова разделяемых библиотек,
то в начале выполнения этого файла вызывается динамический компоновщик
ld.so(8),
который загружает библиотеки и компонует их с исполняемым файлом.
Если исполняемый файл является динамически-скомпонованным файлом в
формате ELF, то для загрузки разделяемых библиотек используется
интерпретатор, указанные в сегменте PT_INTERP. Обычно это
/lib/ld-linux.so.1
для программ, скомпилированных под Linux libc версии 5, или же
/lib/ld-linux.so.2
для программ, скомпилированных под GNU libc версии 2.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном завершении
execve()
не возвращает управление, при ошибке возвращается -1, а значение
errno
устанавливается должным образом.
КОДЫ ОШИБОК
EACCES
Интерпретатор файла или скрипта не является обычным файлом.
EACCES
Нет прав на выполнение файла, скрипта или ELF-интерпретатора.
EACCES
Файловая система смонтирована с флагом
noexec.
EPERM
Файловая система смонтирована с флагом
nosuid,
пользователь не является суперпользователем, а на файле установлен
бит setuid или setgid.
EPERM
Процесс работает под отладчиком, пользователь не является
суперпользователем, а на файле установлен бит setuid или setgid.
E2BIG
Список аргументов слишком велик.
ENOEXEC
Исполняемый файл в неизвестном формате, для другой архитектуры, или же
встречены какие-то ошибки, препятствующие его выполнению.
EFAULT
filename
указывает за пределы доступного адресного пространства.
ENAMETOOLONG
filename
слишком длинное.
ENOENT
Файл
filename,
или интерпретатор скрипта или ELF-файла не существует, или же не
найдена разделяемая библиотека, требуемая файлу или интерпретатору.
ENOMEM
Недостаточно памяти в ядре.
ENOTDIR
Компонент пути
filename,
или интерпретатору скрипта или ELF-интерпретатору не является каталогом.
EACCES
Нет прав на поиск в одном из каталогов по пути к
filename,
или имени интерпретатора скрипта или ELF-интерпретатора.
ELOOP
Слишком много символьных ссылок встречено при поиске
filename,
или интерпретатора скрипта или ELF-интерпретатора.
ETXTBSY
Исполняемый файл открыт для записи одним или более процессами.
EIO
Произошла ошибка ввода-вывода.
ENFILE
Достигнут системный лимит на общее количество открытых файлов.
EMFILE
Процесс уже открыл максимально доступное количество открытых файлов.
EINVAL
Исполняемый файл в формате ELF содержит более одного сегмента
PT_INTERP (то есть, в нем указано более одного интерпретатора).
EISDIR
ELF-интерпретатор является каталогом.
ELIBBAD
ELF-интерпретатор имеет неизвестный формат.
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, SVID, X/OPEN, BSD 4.3. POSIX не документирует поведение,
связанное с #!, но в остальном совершенно совместимо. SVr4
документирует дополнительные коды ошибок
EAGAIN, EINTR, ELIBACC, ENOLINK, EMULTIHOP; POSIX не документирует
коды ошибок
ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL,
EISDIR и ELIBBAD.
ЗАМЕЧАНИЯ
SUID и SGID процессы не могут быть оттрассированы ptrace()d.
Linux игнорирует SUID и SGID биты на скриптах.
Результат монтирования файловой системы с опцией
nosuid
различается в зависимости от версий ядра Linux:
некоторые ядра будут отвергать выполнение SUID/SGID программ, когда
это должно дать пользователю те возможности, которыми он уже не
обладается (и возвращать EPERM), некоторые ядра будут просто
игнорировать SUID/SGID биты, но успешно производить запуск программы.
Первая строка (строка с #!) исполняемого скрипта не может быть длиннее
127 символов.