Provided by: manpages-pl-dev_4.21.0-2_all bug

NAZWA

       execve - uruchomienie programu

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #include <unistd.h>

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

OPIS

       execve()   executes  the program referred to by pathname.  This causes the program that is
       currently being run by the calling process to be replaced with a new program,  with  newly
       initialized stack, heap, and (initialized and uninitialized) data segments.

       pathname  musi  być  albo wykonywalnym plikiem binarnym, albo skryptem zaczynającym się od
       linii w postaci:

           #!interpreter [opcjonalny-parametr]

       Szczegóły  tego  ostatniego  przypadku  można  znaleźć  poniżej   w   rozdziale   "Skrypty
       interpretowane".

       argv  is  an  array  of  pointers to strings passed to the new program as its command-line
       arguments.  By convention, the first of these strings (i.e., argv[0])  should contain  the
       filename  associated with the file being executed.  The argv array must be terminated by a
       NULL pointer.  (Thus, in the new program, argv[argc] will be NULL.)

       envp is an array of pointers to strings, conventionally of the form key=value,  which  are
       passed as the environment of the new program.  The envp array must be terminated by a NULL
       pointer.

       This manual page describes the Linux system  call  in  detail;  for  an  overview  of  the
       nomenclature  and  the  many,  often  preferable,  standardised  variants of this function
       provided by libc, including ones that search the PATH environment variable, see exec(3).

       The argument vector and environment can be accessed by the new  program's  main  function,
       when it is defined as:

           int main(int argc, char *argv[], char *envp[])

       Note,  however,  that the use of a third argument to the main function is not specified in
       POSIX.1; according to POSIX.1,  the  environment  should  be  accessed  via  the  external
       variable environ(7).

       execve()   does  not return on success, and the text, initialized data, uninitialized data
       (bss), and stack of the calling process are overwritten according to the contents  of  the
       newly loaded program.

       Jeśli  obecny  program  jest śledzony za pomocą ptrace, wysyła się mu SIGTRAP po pomyślnym
       execve().

       If the set-user-ID bit is set on the program  file  referred  to  by  pathname,  then  the
       effective  user  ID  of the calling process is changed to that of the owner of the program
       file.  Similarly, if the set-group-ID bit is set on the program file, then  the  effective
       group ID of the calling process is set to the group of the program file.

       The  aforementioned  transformations  of  the  effective  IDs are not performed (i.e., the
       set-user-ID and set-group-ID bits are ignored)  if any of the following is true:

       •  the no_new_privs attribute is set for the calling thread (see prctl(2));

       •  the underlying filesystem is mounted nosuid (the MS_NOSUID flag for mount(2)); or

       •  the calling process is being ptraced.

       The capabilities of the program file (see capabilities(7))  are also ignored if any of the
       above are true.

       Efektywny   identyfikator   użytkownika  jest  kopiowany  do  saved-set-user-ID;  podobnie
       efektywny identyfikator grupy jest kopiowany do saved-set-group-ID. Kopiowanie odbywa  się
       po   zmianie  któregokolwiek  z  efektywnych  identyfikatorów  związanej  z  bitami  trybu
       set-user-ID i set-group-ID.

       The process's real UID and real GID, as well as its supplementary group IDs, are unchanged
       by a call to execve().

       Jeśli  program wykonywalny jest skonsolidowany dynamicznie w formacie a.out z bibliotekami
       dzielonymi, to na początku uruchamiania wywoływany jest konsolidator dynamiczny  ld.so(8),
       który ładuje wszystkie obiekty do pamięci i konsoliduje z nimi program wykonywalny.

       Jeżeli  program  jest  skonsolidowany  dynamicznie jako ELF, to do załadowania potrzebnych
       obiektów współdzielonych używany jest interpreter określony  w  segmencie  PT_INTERP.  Tym
       interpreterem  jest  zazwyczaj  /lib/ld-linux.so.2, w wypadku programów skonsolidowanych z
       glibc2 (zob. ld-linux.so(8)).

   Effect on process attributes
       Wszystkie atrybuty procesu są zachowywane podczas execve(), z wyjątkiem poniższych:

       •  Ustawienia obsługi sygnałów, które są przechwytywane, są zmieniane na wartości domyślne
          (signal(7)).

       •  Alternatywny stos sygnałów nie jest zachowywany (sigaltstack(2)).

       •  Mapowania pamięci nie są zachowywane (mmap(2))

       •  Dołączone segmenty pamięci dzielonej Systemu V są odłączane (shmat(2)).

       •  Regiony pamięci dzielonej POSIX są odmapowane (shm_open(3)).

       •  Otwarte kolejki komunikatów POSIX są zamykane (mq_overview(7)).

       •  Otwarte semafory nazwane POSIX są zamykane (mq_overview(7)).

       •  Timery POSIX nie są zachowywane (timer_create(2)).

       •  Otwarte strumienie katalogów są zamykane (opendir(3)).

       •  Blokady pamięci nie są zachowywane (mlock(2), mlockall(2)).

       •  Zarejestrowanie   funkcje  wykonywanych  po  zakończeniu  procesu  nie  są  zachowywane
          (atexit(3), on_exit(3)).

       •  Środowisko zmiennoprzecinkowe jest ustawiane na domyślne (patrz fenv(3)).

       Atrybuty procesu w liście przedstawionej  powyżej  są  określone  w  POSIX.1.  Następujące
       specyficzne dla Linuksa atrybuty procesu również nie są zachowywane podczas execve():

       •  The process's "dumpable" attribute is set to the value 1, unless a set-user-ID program,
          a set-group-ID program, or a program with capabilities is being executed, in which case
          the  dumpable  flag may instead be reset to the value in /proc/sys/fs/suid_dumpable, in
          the circumstances described under PR_SET_DUMPABLE in prctl(2).  Note  that  changes  to
          the  "dumpable"  attribute  may  cause  ownership  of  files in the process's /proc/pid
          directory to change to root:root, as described in proc(5).

       •  Znacznik PR_SET_KEEPCAPS prctl(2) jest czyszczony.

       •  (Od Linuksa 2.4.36 / 2.6.23) Jeśli wykonywany program ma ustawiony bit set-user-ID  lub
          set-group-ID,  to  jest  czyszczony  znacznik PR_SET_PDEATHSIG  sygnału śmierci rodzica
          ustawiony przez  prctl(2).

       •  Nazwa procesu ustawiona przez PR_SET_NAME z prctl(2) (i wyświetlana przez  ps -o  comm)
          jest ustawiana na nazwę nowego pliku wykonywalnego.

       •  Znacznik SECBIT_KEEP_CAPS w securebits jest czyszczony. Patrz capabilities(7).

       •  Sygnał zakończenia jest ustawiany na SIGCHLD (patrz clone(2)).

       •  Tablica  deskryptora  plików  nie jest dzielona, co anuluje działanie flagi CLONE_FILES
          clone(2).

       Dalsze uwagi:

       •  Wszystkie wątki oprócz wątku  wywołującego  są  niszczone  podczas  execve().  Muteksy,
          zmienne warunkowe i inne obiekty pthreads nie są zachowywane.

       •  Odpowiednik setlocale(LC_ALL, "C") jest wykonywany po uruchomieniu programu.

       •  POSIX.1  określa,  że ustawienie procedur obsługi sygnału na ignorowanie lub na wartość
          domyślną jest pozostawiane bez zmian. POSIX.1 przewiduje jeden wyjątek od  tej  reguły:
          jeśli  SIGCHLD jest ignorowany, to implementacja może albo nie zmienić tego ustawienia,
          albo przestawić je na wartość domyślną; Linux robi to pierwsze.

       •  Wszystkie  asynchroniczne   operacje   wejścia/wyjście   są   anulowane   (aio_read(3),
          aio_write(3)).

       •  Sposób   obsługi   atrybutów   (zdolności)   procesu   podczas   execve()   opisano   w
          capabilities(7).

       •  Domyślnie  deskryptory  plików  pozostają  otwarte  po  execve().  Deskryptory   plików
          oznaczone  jako  "close-on-exec"  są zamykane, patrz opis FD_CLOEXEC w fcntl(2). (Jeśli
          deskryptor pliku zostanie zamknięty, to zwolnione zostaną  wszystkie  blokady  rekordów
          dotyczące  pliku  związanego  z  tym deskryptorem. Szczegóły można znaleźć w fcntl(2)).
          POSIX.1 mówi, że jeżeli deskryptory plików 0, 1 i 2 zostałyby  zamknięte  po  pomyślnym
          wykonaniu  execve(),  a proces uzyskałby przywileje z powodu ustawionego na wykonywanym
          pliku  bitu  trybu  set-user-ID  lub  set-group-ID,  to  system  może  otworzyć  bliżej
          nieokreślony  plik  dla każdego z tych deskryptorów plików. Jako zasadę należy przyjąć,
          że żaden przenośny program, uprzywilejowany czy nie, nie  może  zakładać,  że  te  trzy
          deskryptory plików będą zamknięte po execve().

   Skrypty interpretowane
       Skrypt  interpretowany  jest  plikiem  tekstowym  mającym  ustawione prawo do wykonywania.
       Pierwsza linia tego pliku jest w postaci:

           #!interpreter [opcjonalny-parametr]

       interpreter mus być poprawną nazwą ścieżki do pliku wykonywalnego.

       Jeśli argument pathname wywołania execve() określa interpreter,  to  zostanie  uruchomiony
       interpreter z następującymi argumentami:

           interpreter [opcjonalny-arg] pathname arg...

       where  pathname  is  the pathname of the file specified as the first argument of execve(),
       and arg... is the series of words pointed to by the argv argument of execve(), starting at
       argv[1].   Note  that  there  is no way to get the argv[0] that was passed to the execve()
       call.

       Dla zachowania przenośności na inne systemu optional-arg albo w  ogóle  nie  powinien  być
       podawany,  albo  powinien być podany jako pojedyncze słowo (nie powinien zawierać spacji);
       patrz UWAGI poniżej.

       Od Linuksa 2.6.28  jądro  pozwala,  aby  interpreterem  skryptu  również  był  skrypt.  To
       uprawnienie  jest  rekurencyjne,  aż po czterykroć, tak więc interpreter może być skryptem
       interpretowanym przez skrypt itd.

   Ograniczenia rozmiaru argumentów i środowiska
       Większość implementacji Uniksa narzuca ograniczenia na całkowity rozmiar argumentów  linii
       poleceń  (argv)  i  środowiska  (envp)  przekazywanych do nowego programu. POSIX.1 pozwala
       implementacji ogłosić te ograniczenia za  pomocą  stałej  ARG_MAX  (albo  zdefiniowanej  w
       <limits.h>,   albo   dostępnej   podczas   wykonywania   programu   za   pomocą  wywołania
       sysconf(_SC_ARG_MAX)).

       Before Linux 2.6.23, the memory used to store the environment  and  argument  strings  was
       limited to 32 pages (defined by the kernel constant MAX_ARG_PAGES).  On architectures with
       a 4-kB page size, this yields a maximum size of 128 kB.

       On Linux 2.6.23 and later, most architectures support a size limit derived from  the  soft
       RLIMIT_STACK  resource  limit  (see  getrlimit(2))   that  is  in force at the time of the
       execve()  call.  (Architectures with no memory management unit are excepted: they maintain
       the  limit that was in effect before Linux 2.6.23.)  This change allows programs to have a
       much larger argument and/or environment list.  For these architectures, the total size  is
       limited  to  1/4  of the allowed stack size.  (Imposing the 1/4-limit ensures that the new
       program always has some stack space.)  Additionally, the total size is limited to  3/4  of
       the  value  of  the kernel constant _STK_LIM (8 MiB).  Since Linux 2.6.25, the kernel also
       places a floor of 32 pages on this size limit, so that, even when RLIMIT_STACK is set very
       low,  applications  are guaranteed to have at least as much argument and environment space
       as was provided by Linux 2.6.22 and earlier.  (This guarantee was not  provided  in  Linux
       2.6.23  and  2.6.24.)  Additionally, the limit per string is 32 pages (the kernel constant
       MAX_ARG_STRLEN), and the maximum number of strings is 0x7FFFFFFF.

WARTOŚĆ ZWRACANA

       On success, execve()  does not return, on error -1  is  returned,  and  errno  is  set  to
       indicate the error.

BŁĘDY

       E2BIG  Całkowita liczba bajtów środowiska (envp) i listy argumentów (argv) jest za duża.

       EACCES Brak praw do przeszukiwania dla składnika ścieżki pathname lub ścieżki interpretera
              skryptu (patrz także path_resolution(7)).

       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.

       EAGAIN (od Linuksa 3.1)
              Having changed its real UID using one of the set*uid()  calls, the  caller  was—and
              is  now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)).  For a more
              detailed explanation of this error, see NOTES.

       EFAULT pathname lub jeden ze wskaźników w wektorach argv lub envp wskazuje  poza  dostępną
              dla użytkownika przestrzeń adresową.

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

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

       EISDIR Intepreter ELF jest katalogiem.

       ELIBBAD
              Nie został rozpoznany format interpretera ELF.

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

       ELOOP  Osiągnięto  maksymalny limit rekurencji podczas intepretacji rekurencyjnego skryptu
              (zob. pow. "Skrypty interpretowane"). Przed Linuksem 3.8 w takim wypadku występował
              błąd ENOEXEC.

       EMFILE Zostało  osiągnięte  ograniczenie  na  liczbę  otwartych  deskryptorów  plików  dla
              procesu.

       ENAMETOOLONG
              Ścieżka pathname jest zbyt długa.

       ENFILE Zostało osiągnięte systemowe ograniczenie na całkowitą liczbę otwartych plików.

       ENOENT The file pathname or a script or ELF interpreter does not exist.

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

       ENOMEM Brak pamięci jądra.

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

       EPERM  System  plików jest zamontowany jako nosuid, użytkownik nie jest administratorem, a
              plik ma ustawiony bit set-user-ID lub set-group-ID.

       EPERM  Proces jest śledzony (trace), użytkownik nie jest  superużytkownikiem,  a  plik  ma
              ustawiony bit set-user-ID lub set-group-ID.

       EPERM  Aplikację ślepe na przywileje nie pozyskają pełnego zestawu dozwolonych przywilejów
              przyznanego przez plik wykonywalny. Zob. capabilities(7).

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

STANDARDY

       POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.  POSIX nie opisuje zachowania #!, lecz  istnieje
       ono (z pewnymi odmianami) na innych systemach Uniksowych.

UWAGI

       One  sometimes  sees execve()  (and the related functions described in exec(3))  described
       as "executing a new process" (or similar).  This is a highly misleading description: there
       is no new process; many attributes of the calling process remain unchanged (in particular,
       its PID).  All that execve()  does  is  arrange  for  an  existing  process  (the  calling
       process) to execute a new program.

       Procesy  z  ustawionymi znacznikami set-user-ID oraz set-group-ID nie mogą być śledzone za
       pomocą ptrace(2).

       Efekt zamontowania systemu plików nosuid jest różny  dla  różnych  wersji  jądra  Linuksa:
       niektóre  odmówią  uruchomienia programów set-user-ID i set-group-ID, 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 set-user-ID i set-group-ID i pomyślnie wykonają
       exec().

       Pod Linuksem argv i envp może być podany jako NULL. W  obu  przypadkach,  ma  to  ten  sam
       skutek  co  podanie  danego  argumentu  jako  wskaźnika  do  listy zawierającej pojedynczy
       wskaźnik  null.  Prosimy   nie   wykorzystywać   tej   niestandardowej   i   nieprzenośnej
       pseudofunkcji!  Na  większości  innych systemów Uniksowych podanie jako argv wartości NULL
       spowoduje wystąpienie błędu (EFAULT). Część innych systemów Uniksowych traktuje  przypadek
       envp==NULL tak samo jak Linux.

       POSIX.1 określa, że wartości zwracane przez sysconf(3) nie powinny się zmieniać przez cały
       czas życia procesu. Jednakże od wersji 2.6.23 Linuksa zmiana limitu  zasobów  RLIMIT_STACK
       powoduje również zmianę wartości zwracanej przez _SC_ARG_MAX, żeby odzwierciedlić fakt, że
       zmieniły się ograniczenia przestrzeni służącej do przechowywania argumentów linii  poleceń
       i zmiennych środowiska.

       In most cases where execve()  fails, control returns to the original executable image, and
       the caller of execve()  can then handle the error.  However, in  (rare)  cases  (typically
       caused  by  resource  exhaustion),  failure  may  occur  past  the point of no return: the
       original executable image has been torn down, but the new image could  not  be  completely
       built.   In  such  cases, the kernel kills the process with a SIGSEGV (SIGKILL until Linux
       3.17)  signal.

   Skrypty interpretowane
       The kernel imposes a maximum length on the text that follows the "#!"  characters  at  the
       start  of  a script; characters beyond the limit are ignored.  Before Linux 5.1, the limit
       is 127 characters.  Since Linux 5.1, the limit is 255 characters.

       Semantyka argumentu optional-arg skryptu interpretera różni się pomiędzy  implementacjami.
       Pod Linuksem cały łańcuch znaków występujący po nazwie interpretera jest przekazywany jako
       pojedynczy argument.  Jednakże  inne  systemy  zachowują  się  inaczej.  Niektóre  systemy
       traktują   pierwszy  znaku  białej  spacji  jako  znak  kończący  optional-arg.  Na innych
       systemach skrypt interpretera może przyjmować wiele argumentów i białe znaki  optional-arg
       służą do ich rozdzielania.

       Linux (like most other modern UNIX systems)  ignores the set-user-ID and set-group-ID bits
       on scripts.

   execve() i EAGAIN
       Poniżej znajduje się bardziej szczegółowy opis  błędu  EAGAIN,  który  może  wystąpić  (od
       Linuksa 3.1) przy wywoływaniu execve().

       The  EAGAIN  error  can  occur  when  a  preceding  call  to  setuid(2),  setreuid(2),  or
       setresuid(2)  caused the real user ID of the process to change, and that change caused the
       process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging
       to the new real UID exceeds the resource limit).  From Linux  2.6.0  to  Linux  3.0,  this
       caused the set*uid()  call to fail.  (Before Linux 2.6, the resource limit was not imposed
       on processes that changed their user IDs.)

       Since Linux 3.1, the scenario just described no longer causes the set*uid()  call to fail,
       because  it  too  often  led  to  security holes where buggy applications didn't check the
       return status and assumed that—if the caller had root  privileges—the  call  would  always
       succeed.   Instead,  the  set*uid()   calls  now successfully change the real UID, but the
       kernel sets an internal flag, named  PF_NPROC_EXCEEDED,  to  note  that  the  RLIMIT_NPROC
       resource  limit  has been exceeded.  If the PF_NPROC_EXCEEDED flag is set and the resource
       limit is still exceeded at the time of a subsequent execve()  call, that call  fails  with
       the error EAGAIN.  This kernel logic ensures that the RLIMIT_NPROC resource limit is still
       enforced for the  common  privileged  daemon  workflow—namely,  fork(2)   +  set*uid()   +
       execve().

       Jeśli jednak limit zasobów nie był już przekroczony w trakcie wywołania execve() (ponieważ
       zakończyły się inne procesy  należące  do  tego  rzeczywistego  UID  pomiędzy  wywołaniami
       set*uid()  i  execve()), to wywołanie execve() powiedzie się, a jądro usunie flagę procesu
       PF_NPROC_EXCEEDED. Flaga jest usuwana również wówczas, gdy kolejne  wywołanie  do  fork(2)
       przez ten proces powiedzie się.

   Historia
       W  Uniksie V6  lista  argumentów  wywołania  exec()  była  kończona  0,  podczas gdy lista
       argumentów funkcji main była kończona -1. Dlatego lista argumentów przekazana do main  nie
       mogła być bezpośrednio użyta w wywołaniu exec(). Od Uniksa V7 obie te wartości są NULL.

PRZYKŁADY

       Następujący  program  jest  zaprojektowany  do wykonania przez drugi program przedstawiony
       poniżej. Wyświetla swoje argumenty uruchomienia po jednym w wierszu.

           /* myecho.c */

           #include <stdio.h>
           #include <stdlib.h>

           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 można użyć do uruchomienia programu podanego w argumencie linii poleceń:

           /* execve.c */

           #include <stdio.h>
           #include <stdlib.h>
           #include <unistd.h>

           int
           main(int argc, char *argv[])
           {
               static char *newargv[] = { NULL, "hello", "world", NULL };
               static char *newenviron[] = { NULL };

               if (argc != 2) {
                   fprintf(stderr, "Użycie: %s <plik-do-uruchomienia>\n", argv[0]);
                   exit(EXIT_FAILURE);
               }

               newargv[0] = argv[1];

               execve(argv[1], newargv, newenviron);
               perror("execve");   /* execve() wraca tylko w przypadku błędu */
               exit(EXIT_FAILURE);
           }

       Możemy użyć 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]: świecie

       Możemy także użyć tych programów  do  pokazania  używania  interpretera  skryptu.  Aby  to
       zrobić, tworzymy skrypt, którego "interpreterem"  jest nasz program myecho:

           $ cat > script
           #!./myecho script-arg
           ^D
           $ chmod +x script

       Następnie używamy naszego programu do wykonania skryptu:

           $ ./execve ./script
           argv[0]: ./myecho
           argv[1]: script-arg
           argv[2]: ./script
           argv[3]: witaj
           argv[4]: świecie

ZOBACZ TAKŻE

       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)

TŁUMACZENIE

       Autorami   polskiego   tłumaczenia   niniejszej   strony  podręcznika  są:  Przemek  Borys
       <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>,  Robert  Luberda
       <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>

       Niniejsze  tłumaczenie  jest  wolną  dokumentacją. Bliższe informacje o warunkach licencji
       można   uzyskać   zapoznając   się   z   GNU   General   Public   License   w   wersji   3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   lub   nowszej.   Nie  przyjmuje  się  ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy w tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres  listy  dyskusyjnej
       ⟨manpages-pl-list@lists.sourceforge.net⟩.