Provided by: manpages-it-dev_4.15.0-9_all bug

NOME

       wait, waitpid, waitid - aspetta che il processo cambi stato

SINTASSI

       #include <sys/wait.h>

       pid_t wait(int *wstatus);
       pid_t waitpid(pid_t pid, int *wstatus, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int opzioni);
                       /* Questa è l'interfaccia di glibc e POSIX ; si veda
                          NOTES for informazioni sulla chiamata di sistema diretta. */

   Macro per test di funzionalità per glibc (vedere feature_test_macros(7)):

       waitid():
           A partire da glibc 2.26:
               _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L
       Glibc 2.25 e precedenti:
           _XOPEN_SOURCE
               || /* A partire da glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
               || /* Glibc <= 2.19: */ _BSD_SOURCE

DESCRIZIONE

       Tutte  queste  chiamate  di  sistema  si  usano  per  attendere cambiamenti di stato in un
       processo figlio del processo chiamante, e ottenere informazioni sul processo figlio il cui
       stato  è cambiato. Un cambiamento di stato avviene quando: il processo figlio è terminato;
       il processo  figlio  è  stato  arrestato  da  un  segnale;  il  processo  figlio  è  stato
       ripristinato  da  un segnale.  In caso di un processo figlio terminato, un'attesa permette
       al sistema di rilasciare le risorse associate al processo figlio; se  non  viene  eseguita
       un'attesa,  allora  il  processo  figlio terminato rimane in uno stato "zombie" (vedere le
       NOTE sotto).

       Se un processo figlio ha già cambiato stato, allora le  chiamate  tornano  immediatamente.
       Altrimenti  esse si bloccano fino a quando un processo figlio cambia stato o un gestore di
       segnale  interrompe  la  chiamata  (supponendo  che  le  chiamate  di  sistema  non  siano
       automaticamente  riavviate usando il flag SA_RESTART di sigaction(2)). Nel resto di questa
       pagina un processo figlio il cui stato è cambiato, e che nessuna  di  queste  chiamate  di
       sistema ha aspettato, è definito aspettabile.

   wait() e waitpid()
       La chiamata di sistema wait() sospende l'esecuzione del thread chiamante fino a quando uno
       dei suoi figli termina. La chiamata wait(&wstatus) è equivalente a:

           waitpid(-1, &wstatus, 0);

       La chiamata di sistema waitpid() sospende l'esecuzione del thread chiamante fino a  quando
       un  processo  figlio  specificato  dall'argomento  pid ha cambiato stato. Il comportamento
       predefinito di waitpid() è attendere solo i figli terminati,  ma  questo  comportamento  è
       modificabile attraverso l'argomento opzioni come descritto di seguito.

       Il valore di pid può essere:

       < -1   che significa attesa di qualunque processo figlio il cui gruppo ID del processo sia
              uguale al valore assoluto di pid.

       -1     che significa aspettare qualunque processo figlio.

       0      che significa aspettare qualunque processo figlio il cui gruppo ID del processo sia
              uguale a quello del processo chiamante al momento della chiamata a waitpid().

       > 0    che  significa  aspettare  il  processo  figlio il cui ID di processo sia uguale al
              valore di pid.

       Il valore di opzioni è un OR di zero o più delle seguenti costanti:

       WNOHANG
              torna immediatamente se nessun processo figlio è uscito.

       WUNTRACED
              torna anche se un processo figlio si  è  arrestato  (ma  non  tracciato  attraverso
              ptrace(2)).  Lo  stato  del  processo  figlio non tracciato che è stato arrestato è
              fornito anche se l'opzione non è specificata.

       WCONTINUED (a partire da Linux 2.6.10)
              torna anche se un processo figlio arrestato è stato riesumato inviando SIGCONT.

       (Per le opzioni solo Linux vedere oltre).

       Se wstatus non è NULL, wait() e waitpid() memorizzano l'informazione di stato in int a cui
       punta.  Questo  intero può essere verificato con le seguenti macro (che prendono lo stesso
       intero come argomento, non come un puntatore ad esso, come fanno wait() e waitpid()!):

       WIFEXITED(wstatus)
              restituisce true se il processo figlio è terminato normalmente,  ovvero,  chiamando
              exit(3) o _exit(2), o tornando da main().

       WEXITSTATUS(wstatus)
              ritorna  lo  stato  di  uscita  del processo figlio. Esso consiste negli 8 bit meno
              significativi dell'argomento status che il processo figlio ha  specificato  in  una
              chiamata  a exit(3) o _exit(2) o come argomento per una dichiarazione di ritorno in
              main(). Questa macro deve essere impiegata solo se WIFEXITED restituisce true.

       WIFSIGNALED(wstatus)
              restituisce true se il processo figlio è stato terminato da un segnale.

       WTERMSIG(wstatus)
              restituisce il numero del segnale che ha causato  l'arresto  del  processo  figlio.
              Questa macro deve essere impiegata solo se WIFSIGNALED ha restituito true.

       WCOREDUMP(wstatus)
              restituisce  true se il processo figlio ha prodotto un core dump (si veda core(5)).
              Questa macro deve essere impiegata solo se WIFSIGNALED ha restituito true.

              Questa macro non è specificata in  POSIX.1-2001  e  non  è  disponibile  in  alcune
              implementazioni Unix (per esempio AIX, SunOS). Usarla solo racchiusa all'interno di
              #ifdef WCOREDUMP ... #endif.

       WIFSTOPPED(wstatus)
              restituisce true se il processo figlio  è  stato  arrestato  inviando  un  segnale;
              questo è possibile solo se la chiamata è stata effettuata usando WUNTRACED o quando
              il processo figlio è stato tracciato (vedere ptrace(2)).

       WSTOPSIG(wstatus)
              restituisce il numero del segnale che ha causato  l'arresto  del  processo  figlio.
              Questa macro deve essere impiegata solo se WIFSTOPPED ha restituito true.

       WIFCONTINUED(wstatus)
              (A  partire  da  Linux  2.6.10)  restituisce  true  se  il  processo figlio è stato
              riesumato inviando SIGCONT.

   waitid()
       La chiamata di sistema waitid()  (disponibile  a  partire  da  Linux  2.6.9)  fornisce  un
       controllo più preciso su quale cambiamento di stato del processo figlio aspettare.

       Gli argomenti idtype e id selezionano il processo figlio(i) da aspettare, come segue:

       idtype == P_PID
              Aspetta il processo figlio il cui ID di processo corrisponde a id.

       idtype == P_PIDFD (a partire da Linux 5.4)
              Aspetta  il  processo  figlio  a  cui  fa riferimento il descrittore di file di PID
              specificato  in  id.  (Si  veda  pidfd_open(2)  per  ulteriori   informazioni   sui
              descrittori di file di PID.)

       idtype == P_PGID
              Aspetta  qualunque  processo  figlio il cui ID di gruppo del processo corrisponda a
              id. Da Linux 5.4, se id è zero, aspetta  qualsiasi  processo  figlio  che  è  nello
              stesso  gruppo  di  processi  del gruppo di processi del chiamante al momento della
              chiamata.

       idtype == P_ALL
              Aspetta qualunque processo figlio; id è ignorato.

       Il cambiamento di stato del processo figlio da aspettare è specificato eseguendo un OR  su
       uno o più dei seguenti flag in opzioni:

       WEXITED
              Aspetta il processo figlio che è terminato.

       WSTOPPED
              Aspetta il processo figlio che è stato arrestato con l'invio di un segnale.

       WCONTINUED
              Aspetta  i  figli  (precedentemente  arrestati)  che  sono stati riesumati inviando
              SIGCONT.

       Si può inoltre eseguire un OR sui seguenti flag in opzioni:

       WNOHANG
              Come per waitpid().

       WNOWAIT
              Lascia il processo figlio in uno stato  aspettabile;  una  successiva  chiamata  di
              attesa  può  essere  usata  per  trovare  di  nuovo  l'informazione sullo stato del
              processo figlio.

       In seguito a un ritorno con successo, waitid() riempie i seguenti  campi  della  struttura
       siginfo_t a cui punta infop:

       si_pid L'ID di processo del processo figlio.

       si_uid L'ID reale dell'utente del processo figlio. (Questo campo non viene impostato nella
              maggior parte delle altre implementazioni.)

       si_signo
              Imposta sempre a SIGCHLD.

       si_status
              O lo stato di uscita del processo figlio, come dato a _exit(2) (o  exit(3)),  o  il
              segnale  che  ha causato la terminazione, l'arresto o la continuazione del processo
              figlio. Il campo si_code può essere usato per determinare come interpretare  questo
              campo.

       si_code
              Imposta  a  uno  tra:  CLD_EXITED  (processo  figlio chiamato _exit(2)); CLD_KILLED
              (processo figlio terminato da un segnale); CLD_DUMPED (processo figlio terminato da
              un segnale, ed eseguito un core dump); CLD_STOPPED (processo figlio arrestato da un
              segnale);  CLD_TRAPPED  (il  processo  figlio  tracciato  è  stato   bloccato);   o
              CLD_CONTINUED (processo figlio continuato da SIGCONT).

       Se  WNOHANG  è  stato specificato in opzioni e non c'erano figli in uno stato aspettabile,
       allora waitid() restituisce immediatamente 0, e lo stato della struttura siginfo_t  a  cui
       punta  infop dipende dall'implementazione. Per distinguere (in modo portabile) questo caso
       da quello in cui un processo figlio era in uno stato aspettabile, il  campo  si_pid  viene
       impostato  a  zero prima della chiamata e, dopo il ritorno della chiamata, verifica che in
       questo campo non ci sia un valore zero.

       POSIX.1-2008 Technical Corrigendum 1 (2013) aggiunge il requisito secondo il quale, quando
       viene  specificato  WNOHANG  nelle  opzioni  e non ci sono figli in uno stato aspettabile,
       waitid() dovrebbe impostate a zero i campi si_pid e si_signo della struttura. Su  Linux  e
       altre  implementazioni  che  aderiscono  a  questi requisiti, non è necessario azzerare il
       campo si_pid prima di chiamare waitid(). Comunque, non tutte le implementazioni seguono le
       specifiche POSIX.1 riguardo a questo punto.

VALORE RESTITUITO

       wait():  in caso di successo, restituisce l'ID del processo del processo figlio terminato;
       in caso di insuccesso restituisce -1.

       waitpid(): in caso di successo, restituisce l'ID del processo del processo figlio  il  cui
       stato  è cambiato; se WNOHANG era specificato e uno o più figli specificati da pid esiste,
       ma non ha ancora cambiato  stato,  allora  viene  restituito  0.  In  caso  di  insuccesso
       restituisce -1.

       waitid(): restituisce 0 in caso di successo o se WNOHANG era specificato e nessun processo
       figlio(i) specificato da id ha ancora cambiato stato; in caso  di  insuccesso  restituisce
       -1.

       Ciascuna di queste chiamate imposta errno ad un valore per indicare l'errore.

ERRORI

       EAGAIN The  PID  file  descriptor  specified  in id is nonblocking and the process that it
              refers to has not terminated.

       ECHILD (per wait()) Il processo chiamante non ha nessun processo figlio inaspettato.

       ECHILD (per waitpid() o waitid()) Il processo specificato da pid (waitpid()) o idtype e id
              (waitid())  non  esiste  o non è un processo figlio del processo chiamante (ciò può
              accadere per il processo figlio di un processo se l'azione per SIGCHLD è  impostata
              a SIG_IGN. Vedere anche la sezione Note Linux sui thread).

       EINTR  WNOHANG  non  era  impostata  ed  è  stato  intercettato  un segnale sbloccato o un
              SIGCHLD; vedere signal(7).

       EINVAL Gli argomenti delle opzioni non erano validi.

       ESRCH  (per wait()  o waitpid())  pid è uguale a INT_MIN.

CONFORME A

       SVr4, 4.3BSD, POSIX.1-2001.

NOTE

       Un processo figlio che termina, ma in modo inaspettato, diviene uno  "zombie".  Il  kernel
       mantiene   un   insieme  minimo  di  informazioni  sui  processi  zombie  (PID,  stato  di
       terminazione, informazioni sull'uso delle risorse) allo scopo di permettere  al  padre  di
       eseguire  in  seguito un wait per ottenere informazioni sul processo figlio. Se uno zombie
       non viene rimosso dal sistema attraverso un wait, esso consumerà uno  slot  nella  tabella
       dei  processi  del  kernel,  e  se  questa  tabella  si riempie, non sarà possibile creare
       ulteriori processi. Se un processo padre termina, allora i suoi figli "zombie" (se  ce  ne
       sono)  sono  adottati  da  init(1)  (o  dal  processo "subreaper" più vicino come definito
       attraverso  l'uso  dell'operazione  prctl(2)   PR_SET_CHILD_SUBREAPER);   init(1)   esegue
       automaticamente un wait per rimuovere gli zombie.

       POSIX.1-2001  specifica  che se la disposizione di SIGCHLD è impostata a SIG_IGN o il flag
       SA_NOCLDWAIT è  impostato  per  SIGCHLD  (vedere  sigaction(2)),  i  figli  terminati  non
       diventano  zombie e una chiamata a wait() o waitpid() verrà bloccata fino a quando tutti i
       figli sono terminati, e in seguito fallisce con errno impostato  a  ECHILD.  (Lo  standard
       POSIX  originale lasciava il comportamento di impostare SIGCHLD a SIG_IGN non specificato.
       Si noti che, anche se la  disposizione  predefinita  di  SIGCHLD  è  "ignore",  impostarla
       esplicitamente a SIG_IGN comporterà un diverso trattamento dei processi figlio zombie).

       Linux  2.6  è  conforme a questa specifica. Tuttavia Linux 2.4 (e precedenti) non lo è: se
       una chiamata wait() o waitpid() è effettuata mentre SIGCHLD è  ignorato,  la  chiamata  si
       comporta  come  se  SIGCHLD non fosse stato ignorato, ovvero, la chiamata si blocca fino a
       quando il prossimo processo figlio termina e quindi restituisce l'ID  del  processo  e  lo
       stato di questo processo figlio.

   Note Linux
       Nel  kernel  Linux  un  thread  programmato  dal  kernel non è un costrutto distinto da un
       processo. Invece un thread è semplicemente un processo creato usando la chiamata esclusiva
       di  Linux  clone(2);  altre  routine  come  la  chiamata  portabile pthread_create(3) sono
       implementate usando clone(2). Prima di Linux 2.4 un thread era solo un caso speciale di un
       processo, e come conseguenza un thread non poteva aspettare il processo figlio di un altro
       thread, anche se l'ultimo apparteneva  allo  stesso  gruppo  del  thread.  Tuttavia  POSIX
       prescrive tale funzionalità, e a partire da Linux 2.4 un thread può, e in modo predefinito
       lo fa, aspettare il processo figlio di un altro thread nello stesso gruppo del thread.

       Le seguenti opzioni specifiche di Linux devono essere usate  con  i  figli  creati  usando
       clone(2); esse possono anche essere usate, a partire da Linux 4.07, con waitid():

       __WCLONE
              Aspetta solo i figli di "clone". Se omessa allora aspetta solo i figli "non-clone".
              (Un processo figlio "clone" è uno che non invia segnali, o un  segnale  diverso  da
              SIGCHLD  ai  suoi  genitori  quando  viene terminato). Questa opzione è ignorata se
              viene anche specificato __WALL.

       __WALL (a partire da Linux 2.4)
              Aspetta tutti i figli, qualunque sia il loro tipo ("clone" o "non-clone").

       __WNOTHREAD (a partire da Linux 2.4)
              Non aspetta figli di altri thread nello stesso gruppo del  thread.  Questo  era  il
              comportamento predefinito prima di Linux 2.4.

       A  partire da Linux 4.7, il flag __WALL è automaticamente sottinteso se il processo figlio
       è tracciato con ptrace.

   Differenze tra la libreria C e il kernel
       wait() è in realtà una funzione di  libreria  che  (in  glibc)  è  implementata  come  una
       chiamata a wait4(2).

       Su  alcune  architetture,  non  c'è  nessuna chiamata di sistema waitpid(); invece, questa
       interfaccia è implementata attraverso una funzione wrapper della  libreria  C  che  chiama
       wait4(2).

       La  chiamata  di  sistema  diretta  waitid()  accetta  un quinto argomento, di tipo struct
       rusage *. Se questo argomento non è NULL, viene usato per restituire informazioni sull'uso
       delle  risorse del processofiglio, allo stesso modo di wait4(2). Vedere getrusage(2) per i
       dettagli.

BUG

       Secondo POSIX.1-2008, un'applicazione che chiama waitid() deve assicurarsi che infop punti
       ala  struttura siginfo_t (cioé, che sia un puntatore non-NULL). Su Linux, se infop è NULL,
       waitid() va a buon fine, e ritorna l'ID di processo  del  processo  figlio  aspettato.  Le
       applicazioni  dovrebbero  evitare  di  contare  su questa caratteristica non conforme, non
       standard e non necessaria.

ESEMPI

       Il seguente programma dimostra l'uso di fork(2) e waitpid(). Il programma crea un processo
       figlio.  Se  dalla linea di comando non viene fornito alcun argomento al programma, allora
       il processo  figlio  sospende  la  propria  esecuzione  usando  pause(2),  per  permettere
       all'utente  di  mandare  il  segnale  al  processo figlio. Altrimenti, se viene fornito un
       argomento dalla linea di comando, allora il processo figlio  esce  immediatamente,  usando
       l'intero  fornito dalla linea di comando come stato di uscita. Il processo genitore esegue
       un ciclo che controlla il processo figlio usando waitpid(), e usa le macro W*()  descritte
       sopra per analizzare il valore dello stato diattesa.

       La seguente sessione di shell dimostra l'uso del programma:

           $ ./a.out &
           Child PID is 32360
           [1] 32359
           $ kill -STOP 32360
           stopped by signal 19
           $ kill -CONT 32360
           continued
           $ kill -TERM 32360
           killed by signal 15
           [1]+  Done                    ./a.out
           $

   Sorgente del programma

       #include <sys/wait.h>
       #include <stdint.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

       int
       main(int argc, char *argv[])
       {
           pid_t cpid, w;
           int wstatus;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Codice eseguito dal processo figlio */
               printf("Child PID is %jd\n", (intmax_t) getpid());
               if (argc == 1)
                   pause();                    /* Aspetta i segnali */
               _exit(atoi(argv[1]));

           } else {                    /* codice eseguito dal genitore */
               do {
                   w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }

                   if (WIFEXITED(wstatus)) {
                       printf("exited, status=%d\n", WEXITSTATUS(wstatus));
                   } else if (WIFSIGNALED(wstatus)) {
                       printf("killed by signal %d\n", WTERMSIG(wstatus));
                   } else if (WIFSTOPPED(wstatus)) {
                       printf("stopped by signal %d\n", WSTOPSIG(wstatus));
                   } else if (WIFCONTINUED(wstatus)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
               exit(EXIT_SUCCESS);
           }
       }

VEDERE ANCHE

       _exit(2),  clone(2),  fork(2),  kill(2),  ptrace(2),  sigaction(2),  signal(2),  wait4(2),
       pthread_create(3), core(5), credentials(7), signal(7)

COLOPHON

       Questa pagina fa parte del rilascio 5.13 del progetto Linux man-pages. Una descrizione del
       progetto,  le  istruzioni  per la segnalazione degli errori, e l'ultima versione di questa
       pagina si trovano su https://www.kernel.org/doc/man-pages/.

TRADUZIONE

       La traduzione italiana di questa pagina di  manuale  è  stata  creata  da  Giulio  Daprelà
       <giulio@pluto.it>, Elisabetta Galli <lab@kkk.it> e Marco Curreli <marcocurreli@tiscali.it>

       Questa  traduzione è documentazione libera; leggere la GNU General Public License Versione
       3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ o successiva per le condizioni di copyright.
       Non ci assumiamo alcuna responsabilità.

       Per  segnalare  errori nella traduzione di questa pagina di manuale inviare un messaggio a
       ⟨pluto-ildp@lists.pluto.it⟩.