EXECVE(2)

NAZWA
execve - uruchomienie programu

SKŁADNIA
#include <unistd.h>

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

OPIS
execve() uruchamia program wskazany przez filename. filename musi być albo wykonywalnym programem binarnym, albo skryptem powłoki, rozpoczynającym się od linii postaci "#! interpreter [arg]". W tym drugim przypadku, interpreter musi być prawidłową ścieżką do programu, a nie skryptem, który byłby uruchomiany jako interpreter [arg] filename. argv jest tablicą łańcuchów przekazywanych jako argumenty nowego programu. envp jest tablicą łańcuchów postaci klucz=wartość, która jest przekazywana jako środowisko do nowego programu. Zarówno argv, jak i envp muszą być zakończone wskaźnikiem pustym (NULL). Tablica argumentów oraz środowisko są dostępne w funkcji main wywoływanego programu, jeżeli jest ona zdefiniowana jako int main(int argc, char *argv[], char *envp[]). execve() nie powraca po pomyślnym wywołaniu, a segmenty text, data, bss oraz segment stosu procesu wywołującego zostają nadpisane przez odpowiedniki ładowanego programu. Wywoływany program dziedziczy PID procesu wywołującego i wszelkie deskryptory otwartych plików, które nie są ustawione jako "close on exec". Sygnały oczekujące na proces wywołujący zostają wyczyszczone. Sygnałom, które były przechwytywane przez proces wywołujący, zostaje przypisana ich domyślna obsługa. Sygnał SIHCHLD (jeżeli jest ustawiony na SIG_IGN) może, ale nie musi być przestawiony na SIG_DFL. Jeśli obecny program jest ptrace'owany, wysyła się mu SIGTRAP po pomyślnym execve(). Jeżeli plik programu wskazywany przez filename ma ustawiony bit set-uid, to efektywny identyfikator użytkownika procesu wywołującego jest ustawiany na właściciela pliku programu. Podobnie, jeżeli dla pliku programu ustawiony jest bit set-gid, to efektywnemu identyfikatorowi grupy procesu wywołującego jest przypisywana grupa pliku programu. Jeśli program wykonywalny jest skonsolidowany dynamicznie w formacie a.out z bibliotekami dzielonymi, na początku uruchamieina wywoływany jest konsolidator dynamiczny ld.so(8), który ładuje wszystkie biblioteki do rdzenia i konsoliduje z nimi program wykonywalny. Jeżeli program jest skonsolidowany dynamicznie jako ELF, to do załadowania potrzebnych bibliotek współdzielonych używany jest interpreter określony w segmencie PT_INTERP. Tym interpreterem jest zazwyczaj /lib/ld-linux.so.1, w wypadku programów skonsolidowanych z biblioteką libc w wersji 5, albo /lib/ld-linux.so.2 - dla programów skonsolidowanych z biblioteką GNU libc w wersji 2.

WARTOŚĆ ZWRACANA
Po pomyślnym zakończeniu execve() nie wraca, w wypadku błędu zwracane jest -1 i odpowiednio ustawiane errno .

BŁĘDY

EACCES
    Plik lub interpreter skryptu nie jest zwykłym plikiem.

EACCES
    Brak praw wykonywania dla pliku, skryptu lub intepretera ELF.

EACCES
    System plików jest zamontowany jako noexec.

EPERM
    System plików jest zamontowany jako nosuid, użytkownik nie jest superużytkownikiem, a plik ma ustawiony bit SUID lub SGID.

EPERM
    Proces jest śledzony (trace), użytkownik nie jest superużytkownikiem, a plik ma ustawiony bit SUID lub SGID.

E2BIG
    Lista argumentów jest zbyt długa.

ENOEXEC
    Nie rozpoznano formatu pliku binarnego, plik ten jest skompilowany dla innej architektury albo wystąpił jakiś inny błąd w formacie, który powoduje, że program nie może być uruchomiony.

EFAULT
    filename wskazuje poza dostępną dla użytkownika przestrzeń adresową.

ENAMETOOLONG
    filename jest zbyt długie.

ENOENT
    Plik filename, skrypt, lub intepreter ELF nie istnieje albo nie można znaleźć biblioteki współdzielonej potrzebnej do uruchomienia pliku lub interpretera.

ENOMEM
    Brak dostępnej pamięci jądra.

ENOTDIR
    Składnik ścieżki filename, ścieżki skryptu lub ścieżki interpretera ELF nie jest katalogiem.

EACCES
    Brak praw do przeszukiwania dla składnika ścieżki filename lub ścieżki interpretera skryptu.

ELOOP
    Podczas rozwiązywania filename, nazwy skryptu lub interpretera ELF napotkano zbyt wiele dowiązań symbolicznych.

ETXTBSY
    Plik wykonywalny był otwarty do zapisu przez jeden lub więcej procesów.

EIO Wystąpił błąd wejścia-wyjścia.

ENFILE
    Został osiągnięte ograniczenie liczby otwartych plików w systemie.

EMFILE
    Proces osiągnął już maksymalną liczbę otwartych plików.

EINVAL
    Plik wykonywalny w formacie ELF ma więcej niż jeden segment PT_INTERP (tzn. ma więcej niż jeden interpreter).

EISDIR
    Intepreter ELF jest katalogiem.

ELIBBAD
    Nie został rozpoznany format intepretera ELF.

ZGODNE Z
SVr4, SVID, X/OPEN, BSD 4.3. POSIX nie dokumentuje zachowania #!, lecz poza tym jest zgodny. SVr4 dokumentuje dodatkowe błędy EAGAIN, EINTR, ELIBACC, ENOLINK, EMULTIHOP; POSIX nie dokumentuje błędów ETXTBSY, EPERM, EFAULT, ELOOP, EIO, ENFILE, EMFILE, EINVAL, EISDIR i ELIBBAD.

UWAGI
Procesy ustawiające SUID lub SGID nie mogą być traktowane ptrace(). Linux ignoruje bity SUID i SGID dla skryptów. Efect zamontowania systemu plików nosuid jest różny dla różnych wersji jądra Linuksa: niektóre odmówią uruchomienia programów SUID/SGID, gdy spowodowałoby to udostępnienie użytkownikowi możliwości, którymi w danym momencie nie dysponuje (i zwrócą EPERM), inne po prostu zignorują bity SUID/SGID i wykonają exec pomyślnie. Maksymalna długość pierwszej linii skryptu powłoki, zawierającej #! wynosi 127 znaków.

ZOBACZ TAKŻE
chmod(2), fork(2), execl(3), environ(5), ld.so(8)