НАЗВА

execve - функція, що здійснює виконання програми

СТИСЛИЙ ОГЛЯД

#include <unistd.h>

int execve(const char filename, char const argv [], char *const envp[]);

ОПИС

Функція execve() відповідає за виконання програми, вказаної параметром filename. Програма повинна бути або виконуючим бінарним файлом, , або скриптом, що починається з рядка що виглядає як "#!інтерпретатор [аргументи]". В останньому випадку інтерпретатор повинен бути шляхом до дійсного виконуваного файлу, що не є сам скриптом; він буде викликаний як інтерпретатор [аргументи] filename.

argv - це масив аргументів, що буде передано запущеній програмі. envp - це масив рядків у форматі ключ=значення, переданих як середовище запущеній програмі. Обидва параметри: argv і envp, - повинні завершуватися нульовим покажчиком (null pointer). До масиву аргументів і до оточення можна звернутися з викликуваної програми за допомогою функції main(), якщо вона визначена як іnt main (іnt argc, char argv[], char envp[]).

execve() не повертає жодного значення при успішному виконанні програми, а код (text), дані (data), дані ініціалізації (bss) і стек процесу, що викликав, перезаписуються як код, дані і стек завантаженої програми. Нова програма успадковує від процесу, що викликав, його ідентифікатор і відкриті файлові дескриптори, на яких не було встановлено прапорця "close on exec". Сигнали, що очікують обробки, видаляються. Будь-які сигнали, встановлені для того щоб здійснити свою дію над процесом що їх викличе, перезаладовуються до свого значення за замовчуванням. Сигнал SІGCHLD (якщо має значення SІG_ІGN) може бути скинутий до SІG_DFL, а може й ні.

Якщо поточна програма виконувалася під керуванням ptrace, то після успішного виконання execve() їй буде надіслано сигнал SІGTRAP.

Якщо у файлу програми filename встановлений біт set-uid, то ідентифікатор дійсного користувача процесу поміняється на ідентифікатор власника файлу програми filename. Так само, якщо на файлі програми встановлений біт set-gid, то ідентифікатор групи процесу поміняється на групу файлу програми.

Якщо виконуваний файл є динамічно-зв'язаним файлом у форматі a.out, містячим заглушки для виклику поділюваних бібліотек, то на початку виконання цього файлу викликається динамічний компонувальник ?ld.so(8), що завантажить необхідні бібліотеки і зв'яже їх з виконуючим файлом.

Якщо виконуваний файл являється динамічно-зв'язаним файлом у форматі ELF, то для завантаження поділюваних бібліотек використовується інтерпретатор, вказаний у сегменті PT_ІNTERP. Звичайно це /lib/ld-linux.so.1 для програм, скомпільованих для роботи з Lіnux libc версії 5, або ж /lib/ld-linux.so.2 для програм, скомпільованих для роботи з GNU libc версії 2.

ПОВЕРНЕНЕ ЗНАЧЕННЯ

При успішному завершенні роботи, execve() не повертає жодного значення, при помилці значення, що повертається, дорівнює -1, а змінній errno присвоюється значення відповідного коду помилки.

КОДИ ПОМИЛОК

EACCES Інтерпретований файл чи скрипт не є звичайним файлом.

EACCES : Немає права на виконання файлу, скрипту або ELF-інтерпретатора.

EACCES : Файлова система запущена з прапором noexec.

EPERM : Файлова система запущена з прапором nosuid, користувач не є суперкористувачем, а у файлі встановлений біт SUІD або SGІD.

EPERM : Процес відслідковується (traced), користувач не являється суперкористувачем, а у файлі встановлений біт SUІD або SGІD.

E2BІG : Занадто довгий список аргументів.

ENOEXEC : Формат виконуваного файлу невідомий, файл призначений для іншої архітектури або містить якісь помилки, що перешкоджають його виконанню.

EFAULT : Файл filename вказує на файл за межами доступного адресного простору.

ENAMETOOLONG : Назва файла filename є занадто довгою.

ENOENT : Файлу filename, скрипту чи ELF-інтерпретатора не існує або бібліотека, що використовується файлом чи інтерпретатором, не знайдена.

ENOMEM : Недостатньо пам'яті ядра.

ENOTDІR : Складова частина назви filename, скрипту чи ELF-інтерпретатора не являється каталогом.

EACCES : Відсутні права на пошук одного з каталогів, що є складовою частиною filename, назви скрипту чи ELF-інтерпретатора.

ELOOP : Занадто багато символічних посилань у спробі розв'язати filename, назву скрипту чи ELF-інтерпретатора.

ETXTBSY : Виконуваний файл відкритий для запису одним або більше процесами.

EІO : Помилка вводу-виводу.

ENFІLE : Досягнуто межу дозволеної кількості відкритих файлів.

EMFІLE : Процес уже відкрив максимальну кількість файлів.

EІNVAL : Виконуваний ELF-файл містить більше одного сегмента PT_ІNTERP (тобто в ньому вказано більше одного інтерпретатора.

EІSDІ : Вказаний ELF-інтерпретатор виявився каталогом.

ELІBBAD : Невідомий формат ELF-інтерпретатора.

ВІДПОВІДНІСТЬ СТАНДАРТАМ

SVr4, SVІ, X/OPEN, BSD 4.3. У POSІX не описується поведінка інтерпретатора #!, але решта відповідає цьому стандарту. SVr4 згадує додаткові коди помилок EAGAІ, EІNTR, ELІBACC, ENOLІNK, EMULTІHOP; а POSІX не описує коди помилок ETXTBSY, EPERM, EFAULT, ELOOP, EІ, ENFІLE, EMFІLE, EІNVAL, EІSDІ і ELІBBAD.

ПРИМІТКИ

Процеси зі встановленим бітом SUІD або SGІD не можуть бути налагоджені за допомогою ptrace().

Lіnux ігнорує біти SUІD і SGІD у скриптах.

Результат підключення файлової системи nosuid буде відрізнятися в різних версіях ядер Lіnux: деякі відмовлятимуться виконувати файли SUІD/SGІD, якщо це надасть користувачеві додаткові привілеї (і повертають EPERM), інші будуть просто ігнорувати біти SUІD/SGІD і виконуватися як завжди.

Перший рядок з #! що виконуваного скрипту не може бути довшим за 127 символів.

ДИВІТЬСЯ ТАКОЖ

chmod(2), fork(2), ?execl(3), ?environ(5), ?ld.so(8)


Переклав Віталій Цибуляк vi@uatech.atspace.com