table of contents
EXECVE(2) | Podręcznik programisty Linuksa | 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¶
1997-09-03 | Linux 2.0.30 |