execve(2) System Calls Manual execve(2) NAZWA execve - wykonuje program BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include int execve(const char *pathname, char *const _Nullable argv[], char *const _Nullable envp[]); OPIS execve() wykonuje program wskazywany przez pathname. Program, ktory jest aktualnie wykonywany przez proces wywolujacy jest zastepowany nowym programem, z nowo zainicjowanym stosem, kopcem i (zainicjowanymi i niezainicjowanymi) segmentami danych. pathname musi byc albo wykonywalnym plikiem binarnym, albo skryptem zaczynajacym sie od wiersza w postaci: #!interpreter [opcjonalny-parametr] Szczegoly tego ostatniego przypadku mozna znalezc ponizej w rozdziale ,,Skrypty interpretowane". argv jest tablica wskaznikow do lancuchow przekazywanych jako argumenty wiersza polecen nowego programu. Zgodnie z konwencja, pierwszy z nich (tj. argv[0]) powinien zawierac nazwe pliku skojarzonego z wykonywanym programem. Tablica argv musi byc zakonczona wskaznikiem null (dlatego w nowym programie, argv[argc] bedzie wskaznikiem null). envp jest tablica wskaznikow do lancuchow, zgodnie z konwencja, postaci klucz=wartosc, ktora jest przekazywana jako srodowisko do nowego programu. Tablica envp musi byc zakonczona wskaznikiem pustym (NULL). Niniejszy podrecznik opisuje detale linuksowego wywolania systemowego; aby zapoznac sie z przegladem nomenklatury oraz wieloma, czesto preferowanymi, standardowymi wariantami niniejszej funkcji udostepnianymi przez libc, w tym przeszukujacymi zmienna srodowiskowa PATH, zob. exec(3). Argument wektora i srodowiska moze byc dostepny z glownej funkcji nowego programu, gdy zostanie zdefiniowany jako: int main(int argc, char *argv[], char *envp[]) Prosze jednak zauwazyc, ze uzycie trzeciego argumentu glownej funkcji nie jest okreslone norma POSIX.1; zgodnie z POSIX.1, dostep do srodowiska powinien nastepowac za pomoca zewnetrznej zmiennej environ(7). W razie powodzenia execve() nie powraca, a sekcje tekstu, zainicjowanych danych, niezainicjowanych danych (bss) i stos wywolujacego procesu sa nadpisywane zgodnie z zawartoscia nowo ladowanego programu. Jesli obecny program jest sledzony za pomoca ptrace, wysyla sie mu SIGTRAP po pomyslnym execve(). Jezeli plik programu, do ktorego odnosi sie filename, ma ustawiony bit set-user-ID, to efektywny identyfikator uzytkownika procesu wywolujacego jest ustawiany na wlasciciela pliku programu. Podobnie, jezeli dla pliku programu ustawiony jest bit set-group-ID, to efektywnemu identyfikatorowi grupy procesu wywolujacego jest przypisywana grupa pliku programu. Wyzej wymienione przeksztalcenia efektywnego identyfikatora nie sa przeprowadzane (tzn. bity set-user-ID i set-group-ID sa ignorowane) jesli dowolny z ponizszych warunkow jest prawdziwy: o dla wywolujacego watku ustawiony jest atrybut no_new_privs (zob. prctl(2)); o przedmiotowy system plikow jest zamontowany z nosuid (znacznik MS_NOSUID dla mount(2)) lub o wywolujacy proces jest sledzony za pomoca ptrace. Przywileje pliku programu (zob. capabilities(7)) sa rowniez ignorowane, jesli dowolny z powyzszych warunkow jest prawdziwy. Efektywny identyfikator uzytkownika jest kopiowany do zapisanego set-user-ID; podobnie efektywny identyfikator grupy jest kopiowany do zapisanego set-group-ID. Kopiowanie odbywa sie po zmianie ktoregokolwiek z efektywnych identyfikatorow zwiazanej z bitami trybu set-user-ID i set-group-ID. Rzeczywisty identyfikator procesu i rzeczywisty identyfikator grupy, podobnie jak uzupelniajace identyfikatory grupy, pozostaja bez zmian przy wywolaniu do execve(). Jesli program wykonywalny jest skonsolidowany dynamicznie w formacie a.out z bibliotekami dzielonymi, to na poczatku uruchamiania wywolywany jest konsolidator dynamiczny ld.so(8), ktory laduje wszystkie obiekty do pamieci i konsoliduje z nimi program wykonywalny. Jezeli program jest skonsolidowany dynamicznie jako ELF, to do zaladowania potrzebnych obiektow wspoldzielonych uzywany jest interpreter okreslony w segmencie PT_INTERP. Tym interpreterem jest zazwyczaj /lib/ld-linux.so.2, w wypadku programow skonsolidowanych z glibc2 (zob. ld-linux.so(8)). Wplyw na atrybuty procesu Wszystkie atrybuty procesu sa zachowywane podczas execve(), z wyjatkiem ponizszych: o Ustawienia obslugi sygnalow, ktore sa przechwytywane, sa zmieniane na wartosci domyslne (signal(7)). o Alternatywny stos sygnalow nie jest zachowywany (sigaltstack(2)). o Mapowania pamieci nie sa zachowywane (mmap(2)) o Dolaczone segmenty pamieci dzielonej Systemu V sa odlaczane (shmat(2)). o Regiony pamieci dzielonej POSIX sa odmapowane (shm_open(3)). o Otwarte kolejki komunikatow POSIX sa zamykane (mq_overview(7)). o Otwarte semafory nazwane POSIX sa zamykane (mq_overview(7)). o Timery POSIX nie sa zachowywane (timer_create(2)). o Otwarte strumienie katalogow sa zamykane (opendir(3)). o Blokady pamieci nie sa zachowywane (mlock(2), mlockall(2)). o Zarejestrowanie funkcje wykonywanych po zakonczeniu procesu nie sa zachowywane (atexit(3), on_exit(3)). o Srodowisko zmiennoprzecinkowe jest ustawiane na domyslne (patrz fenv(3)). Atrybuty procesu w liscie przedstawionej powyzej sa okreslone w POSIX.1. Nastepujace specyficzne dla Linuksa atrybuty procesu rowniez nie sa zachowywane podczas execve(): o Atrybut ,,dumpable" (,,zrzucalny") jest ustawiany na wartosc 1, chyba ze wykonywany jest program: z set-user-ID, z set-group-ID lub z przywilejami (ang. capabilities); wowczas atrybut ten moze byc zresetowany na wartosc z /proc/sys/fs/suid_dumpable, w przypadkach opisanych odnosnie PR_SET_DUMPABLE w podreczniku prctl(2). Prosze zauwazyc, ze zmiany atrybutu ,,dumpable" moga spowodowac zmiane wlasnosci plikow w katalogu procesu /proc/pid na root:root, zgodnie z opisem w podreczniku proc(5). o Znacznik PR_SET_KEEPCAPS prctl(2) jest czyszczony. o (Od Linuksa 2.4.36 / 2.6.23) Jesli wykonywany program ma ustawiony bit set-user-ID lub set-group-ID, to jest czyszczony znacznik PR_SET_PDEATHSIG sygnalu smierci rodzica ustawiony przez prctl(2). o Nazwa procesu ustawiona przez PR_SET_NAME z prctl(2) (i wyswietlana przez ps -o comm) jest ustawiana na nazwe nowego pliku wykonywalnego. o Znacznik SECBIT_KEEP_CAPS w securebits jest czyszczony. Patrz capabilities(7). o Sygnal zakonczenia jest ustawiany na SIGCHLD (patrz clone(2)). o Tablica deskryptora plikow nie jest dzielona, co anuluje dzialanie flagi CLONE_FILES clone(2). Dalsze uwagi: o Wszystkie watki oprocz watku wywolujacego sa niszczone podczas execve(). Zatrzaski (muteksy), zmienne warunkowe i inne obiekty pthreads nie sa zachowywane. o Odpowiednik setlocale(LC_ALL, "C") jest wykonywany po uruchomieniu programu. o POSIX.1 okresla, ze ustawienie procedur obslugi sygnalu na ignorowanie lub na wartosc domyslna jest pozostawiane bez zmian. POSIX.1 przewiduje jeden wyjatek od tej reguly: jesli SIGCHLD jest ignorowany, to implementacja moze albo nie zmienic tego ustawienia, albo przestawic je na wartosc domyslna; Linux robi to pierwsze. o Wszystkie asynchroniczne operacje wejscia/wyjscie sa anulowane (aio_read(3), aio_write(3)). o Sposob obslugi przywilejow procesu podczas execve() opisano w capabilities(7). o Domyslnie deskryptory plikow pozostaja otwarte po execve(). Deskryptory plikow oznaczone jako ,,zamknij-przy-wykonaniu" sa zamykane, patrz opis FD_CLOEXEC w fcntl(2). (Jesli deskryptor pliku zostanie zamkniety, to zwolnione zostana wszystkie blokady rekordow dotyczace pliku zwiazanego z tym deskryptorem. Szczegoly mozna znalezc w fcntl(2)). POSIX.1 mowi, ze jezeli deskryptory plikow 0, 1 i 2 zostalyby zamkniete po pomyslnym wykonaniu execve(), a proces uzyskalby przywileje z powodu ustawionego na wykonywanym pliku bitu trybu set-user-ID lub set-group-ID, to system moze otworzyc blizej nieokreslony plik dla kazdego z tych deskryptorow plikow. Jako zasade nalezy przyjac, ze zaden przenosny program, uprzywilejowany czy nie, nie moze zakladac, ze te trzy deskryptory plikow beda zamkniete po execve(). Skrypty interpretowane Skrypt interpretowany jest plikiem tekstowym majacym ustawione prawo do wykonywania. Pierwszy wiersz tego pliku jest w postaci: #!interpreter [opcjonalny-parametr] interpreter mus byc poprawna nazwa sciezki do pliku wykonywalnego. Jesli argument pathname wywolania execve() okresla interpreter, to zostanie uruchomiony interpreter z nastepujacymi argumentami: interpreter [opcjonalny-arg] pathname arg... gdzie pathname jest sciezka pliku podanego jako pierwszy argument execve(), a arg... jest zestawem slow, na ktore wskazuje argument argv execve(), zaczynajac od argv[1]. Prosze zauwazyc, ze nie da sie pozyskac argv[0] przekazanego do wywolania execve(). Dla zachowania przenosnosci na inne systemy, optional-arg albo w ogole nie powinien byc podawany, albo powinien byc podany jako pojedyncze slowo (nie powinien zawierac spacji); patrz UWAGI ponizej. Od Linuksa 2.6.28 jadro pozwala, aby interpreterem skryptu rowniez byl skrypt. To uprawnienie jest rekurencyjne, az po czterykroc, tak wiec interpreter moze byc skryptem interpretowanym przez skrypt itd. Ograniczenia rozmiaru argumentow i srodowiska Wiekszosc implementacji Uniksa narzuca ograniczenia na calkowity rozmiar argumentow linii polecen (argv) i srodowiska (envp) przekazywanych do nowego programu. POSIX.1 pozwala implementacji oglosic te ograniczenia za pomoca stalej ARG_MAX (albo zdefiniowanej w , albo dostepnej podczas wykonywania programu za pomoca wywolania sysconf(_SC_ARG_MAX)). Przed Linuksem 2.6.23, pamiec uzywana do przechowywania lancuchow znakow srodowiska i argumentow byla ograniczana do 32 stron (zdefiniowane przez stala jadra MAX_ARG_PAGES). W architekturach majacych strony o rozmiarze 4 kB oznaczalo to maksymalny rozmiar rowny 128 kB. W Linuksie 2.6.23 i pozniejszych, wiekszosc architektur obsluguje ograniczenie rozmiaru wywodzace sie z miekkiego limitu zasobu RLIMIT_STACK (patrz getrlimit(2)), obowiazujacego podczas wywolania execve() (Wyjatek stanowia architektury nie majace jednostki zarzadzania pamiecia: przechowuja ograniczenie obowiazujace przed Linuksem 2.6.23). Zmiana ta pozwala programom na posiadanie znacznie wiekszej listy argumentow lub srodowiska. Na tych architekturach calkowity rozmiar jest ograniczony do 1/4 dopuszczalnego rozmiaru stosu. (Limit 1/4 zapewnia, ze zostanie jakas przestrzen na stos dla nowego programu). Dodatkowo, calkowity rozmiar jest ograniczony do 3/4 wartosci stalej jadra _STK_LIM (8 MiB). Od Linuksa 2.6.25 jadro przyjmuje rowniez wartosc minimalna 32 stron dla tego limitu rozmiaru, tak zeby zagwarantowac, ze w przypadku gdy RLIMIT_STACK ma niewielka wartosc, aplikacje dostana co najmniej taka przestrzen na argumenty i srodowisko, jaka mialy w Linuksie 2.6.22 i wczesniejszych. (Takiej gwarancji nie ma w Linuksach 2.6.23 i 2.6.24). Dodatkowo ograniczeniem na pojedynczy lancuch znakow sa 32 strony (stala jadra MAX_ARG_STRLEN), a maksymalna liczba takich lancuchow wynosi 0x7FFFFFFF. WARTOSC ZWRACANA Po pomyslnym zakonczeniu execve() nie wraca, w wypadku bledu zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY E2BIG Calkowita liczba bajtow w srodowisku (envp) i liscie argumentow (argv) jest zbyt duza, argument lancucha srodowiska jest zbyt dlugi lub pelna sciezka pathname pliku wykonywalnego jest zbyt dluga. Koncowy bajt null jest wliczany do dlugosci lancucha. EACCES Brak praw do przeszukiwania dla skladnika sciezki pathname lub sciezki interpretera skryptu (patrz takze path_resolution(7)). EACCES Plik lub interpreter skryptu nie jest zwyklym plikiem. EACCES Brak praw wykonywania dla pliku, skryptu lub intepretera ELF. EACCES System plikow jest zamontowany jako noexec. EAGAIN (od Linuksa 3.1) Po zmianie swojego rzeczywistego UID za pomoca jednego z wywolan set*uid(), wywolujacy byl - i wciaz jest - powyzej swojego limitu zasobow RLIMIT_NPROC (zob. setrlimit(2)). Wiecej informacji o tym bledzie znajduje sie w rozdziale UWAGI. EFAULT pathname lub jeden ze wskaznikow w wektorach argv lub envp wskazuje poza dostepna dla uzytkownika przestrzen adresowa. EINVAL Plik wykonywalny w formacie ELF ma wiecej niz jeden segment PT_INTERP (tzn. ma wiecej niz jeden interpreter). EIO Wystapil blad wejscia/wyjscia. EISDIR Intepreter ELF jest katalogiem. ELIBBAD Nie zostal rozpoznany format interpretera ELF. ELOOP Podczas rozwiazywania pathname, nazwy skryptu lub interpretera ELF napotkano zbyt wiele dowiazan symbolicznych. ELOOP Osiagnieto maksymalny limit rekurencji podczas intepretacji rekurencyjnego skryptu (zob. pow. "Skrypty interpretowane"). Przed Linuksem 3.8 w takim wypadku wystepowal blad ENOEXEC. EMFILE Zostalo osiagniete ograniczenie na liczbe otwartych deskryptorow plikow dla procesu. ENAMETOOLONG Sciezka pathname jest zbyt dluga. ENFILE Zostalo osiagniete systemowe ograniczenie na calkowita liczbe otwartych plikow. ENOENT Plik pathname, skrypt lub interpreter ELF nie istnieje. ENOEXEC Nie rozpoznano formatu pliku binarnego, plik ten jest skompilowany dla innej architektury albo wystapil jakis inny blad formatu pliku, ktory powoduje, ze program nie moze byc uruchomiony. ENOMEM Brak pamieci jadra. ENOTDIR Skladowa sciezki pathname, sciezki skryptu lub sciezki interpretera ELF nie jest katalogiem. EPERM System plikow jest zamontowany jako nosuid, uzytkownik nie jest administratorem, a plik ma ustawiony bit set-user-ID lub set-group-ID. EPERM Proces jest sledzony (trace), uzytkownik nie jest superuzytkownikiem, a plik ma ustawiony bit set-user-ID lub set-group-ID. EPERM Aplikacje slepe na przywileje nie pozyskaja pelnego zestawu dozwolonych przywilejow przyznanego przez plik wykonywalny. Zob. capabilities(7). ETXTBSY Podany plik wykonywalny byl otwarty do zapisu przez jeden lub wiecej procesow. WERSJE POSIX nie opisuje zachowania #!, lecz istnieje ono (z pewnymi odmianami) na innych systemach Uniksowych. Pod Linuksem argv i envp moze byc podany jako NULL. W obu przypadkach, ma to ten sam skutek co podanie danego argumentu jako wskaznika do listy zawierajacej pojedynczy wskaznik null. Prosimy nie wykorzystywac tej niestandardowej i nieprzenosnej pseudofunkcji! Na wiekszosci innych systemow Uniksowych podanie jako argv wartosci NULL spowoduje wystapienie bledu (EFAULT). Czesc innych systemow Uniksowych traktuje przypadek envp==NULL tak samo jak Linux. POSIX.1 okresla, ze wartosci zwracane przez sysconf(3) nie powinny sie zmieniac przez caly czas zycia procesu. Jednakze od wersji 2.6.23 Linuksa zmiana limitu zasobow RLIMIT_STACK powoduje rowniez zmiane wartosci zwracanej przez _SC_ARG_MAX, zeby odzwierciedlic fakt, ze zmienily sie ograniczenia przestrzeni sluzacej do przechowywania argumentow linii polecen i zmiennych srodowiska. Skrypty interpretowane Jadro narzuca maksymalna dlugosc tekstu nastepujacego po znakach ,,#!" na poczatku skryptu; znaki wykraczajace poza limit sa ignorowane. Przed Linuksem 5.1, limit wynosi 127 znakow. Od Linuksa 5.1, limit wynosi 255 znakow. Semantyka argumentu optional-arg skryptu interpretera rozni sie pomiedzy implementacjami. Pod Linuksem caly lancuch znakow wystepujacy po nazwie interpretera jest przekazywany jako pojedynczy argument. Jednakze inne systemy zachowuja sie inaczej. Niektore systemy traktuja pierwszy znaku bialej spacji jako znak konczacy optional-arg. Na innych systemach skrypt interpretera moze przyjmowac wiele argumentow i biale znaki optional-arg sluza do ich rozdzielania. Linux (podobnie jest wiekszosc innych wspolczesnych systemow uniksowych) ignoruje bity set-user-ID i set-group-ID dla skryptow. STANDARDY POSIX.1-2008. HISTORIA POSIX.1-2001, SVr4, 4.3BSD. W Uniksie V6 lista argumentow wywolania exec() byla konczona 0, podczas gdy lista argumentow funkcji main byla konczona -1. Dlatego lista argumentow przekazana do main nie mogla byc bezposrednio uzyta w wywolaniu exec(). Od Uniksa V7 obie te wartosci sa NULL. UWAGI Mozna czasami przeczytac, ze execve() (i powiazane funkcje opisane w exec(3)) sa opisywane jako ,,wykonujace nowy proces" (lub podobnie). Jest to stwierdzenie bardzo mylace: nie wystepuje tu nowy proces; wiele atrybutow procesu wywolujacego pozostaje niezmienionych (w szczegolnosci jego identyfikator procesu). Wszystko, co robi execve(), to zaaranzowanie wykonania nowego programu przez istniejacy proces (proces wywolujacy). Procesy z ustawionymi znacznikami set-user-ID oraz set-group-ID nie moga byc sledzone za pomoca ptrace(2). Efekt zamontowania systemu plikow nosuid jest rozny dla roznych wersji jadra Linux: niektore odmowia uruchomienia programow set-user-ID i set-group-ID, gdy spowodowaloby to udostepnienie uzytkownikowi mozliwosci, ktorymi w danym momencie nie dysponuje (i zwroca EPERM), inne po prostu zignoruja bity set-user-ID i set-group-ID i pomyslnie wykonaja exec(). W wiekszosci sytuacji gdy execve() zawiedzie, kontrola powraca do oryginalnego obrazu wykonywalnego, a wywolujacy execve() moze nastepnie obsluzyc blad. Jednak sa (rzadkie) przypadki (zwykle przy braku zasobow), gdy blad moze wystapic w momencie bez powrotu: oryginalny obraz wykonywalne zostal podzielony, a nie mozna calkowicie zbudowac nowego obrazu. W takich sytuacjach jadro zabija proces sygnalem SIGSEGV (SIGKILL do Linuksa 3.17). execve() i EAGAIN Ponizej znajduje sie bardziej szczegolowy opis bledu EAGAIN, ktory moze wystapic (od Linuksa 3.1) przy wywolywaniu execve(). Blad EAGAIN moze wystapic, gdy wywolanie poprzedzajace setuid(2), setreuid(2) lub setresuid(2) spowodowalo, ze rzeczywisty ID uzytkownika procesu zmienil sie i ta zmiana doprowadzila do wyczerpania jego limitu zasobow RLIMIT_NPROC (tzn. liczba procesow nalezacych do nowego rzeczywistego UID przekroczy limit zasobow). Od Linuksa 2.6.0 do Linuksa 3.0 powodowalo to niepowodzenie wywolania set*uid(). Przed Linuksem 2.6 limit zasobow nie byl nakladany w przypadku procesow zmieniajacych swoj identyfikator uzytkownika. Od Linuksa 3.1, opisana sytuacja nie powoduje juz niepowodzenia wywolania set*uid(), poniewaz zbyt czesto prowadzilo to do dziur bezpieczenstwa, gdy nieprawidlowo napisane programy nie sprawdzaly statusu zakonczenia i przyjmowaly, ze - jesli wywolujacy ma uprawnienia roota - wywolanie zawsze powiedzie sie. Obecnie wywolania set*uid() poprawnie zmieniaja rzeczywisty UID, lecz jadro ustawia wewnetrzna flage PF_NPROC_EXCEEDED, wskazujac ze przekroczono limit zasobow RLIMIT_NPROC. Jesli flaga PF_NPROC_EXCEEDED jest ustawiona, a limit zasobow jest wciaz przekroczony w trakcie kolejnego wywolania execve(), to wywolanie to zakonczy sie z bledem EAGAIN. Ta logika jadra zapewnia, ze limit zasobow RLIMIT_NPROC jest wciaz wymuszony dla zwyklej pracy demonow uprzywilejowanych - przykladem jest fork(2) + set*uid() + execve(). Jesli jednak limit zasobow nie byl juz przekroczony w trakcie wywolania execve() (poniewaz zakonczyly sie inne procesy nalezace do tego rzeczywistego UID pomiedzy wywolaniami set*uid() i execve()), to wywolanie execve() powiedzie sie, a jadro usunie flage procesu PF_NPROC_EXCEEDED. Flaga jest usuwana rowniez wowczas, gdy kolejne wywolanie do fork(2) przez ten proces powiedzie sie. PRZYKLADY Nastepujacy program jest zaprojektowany do wykonania przez drugi program przedstawiony ponizej. Wyswietla swoje argumenty uruchomienia po jednym w wierszu. /* myecho.c */ #include #include int main(int argc, char *argv[]) { for (size_t j = 0; j < argc; j++) printf("argv[%zu]: %s\n", j, argv[j]); exit(EXIT_SUCCESS); } Tego programu mozna uzyc do uruchomienia programu podanego w argumencie wiersza polecen: /* execve.c */ #include #include #include int main(int argc, char *argv[]) { static char *newargv[] = { NULL, "witaj", "swiecie", NULL }; static char *newenviron[] = { NULL }; if (argc != 2) { fprintf(stderr, "Uzycie: %s \n", argv[0]); exit(EXIT_FAILURE); } newargv[0] = argv[1]; execve(argv[1], newargv, newenviron); perror("execve"); /* execve() powraca tylko przy bledzie */ exit(EXIT_FAILURE); } Mozemy uzyc drugiego programu do uruchomienia pierwszego: $ cc myecho.c -o myecho $ cc execve.c -o execve $ ./execve ./myecho argv[0]: ./myecho argv[1]: witaj argv[2]: swiecie Mozemy takze uzyc tych programow do pokazania uzywania interpretera skryptu. Aby to zrobic, tworzymy skrypt, ktorego ,,interpreterem" jest nasz program myecho: $ cat > script #!./myecho script-arg ^D $ chmod +x script Nastepnie uzywamy naszego programu do wykonania skryptu: $ ./execve ./script argv[0]: ./myecho argv[1]: script-arg argv[2]: ./script argv[3]: witaj argv[4]: swiecie ZOBACZ TAKZE chmod(2), execveat(2), fork(2), get_robust_list(2), ptrace(2), exec(3), fexecve(3), getauxval(3), getopt(3), system(3), capabilities(7), credentials(7), environ(7), path_resolution(7), ld.so(8) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Przemek Borys , Andrzej Krzysztofowicz , Robert Luberda i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.06 1 listopada 2023 r. execve(2)