Provided by: manpages-it_3.73-2_all bug

NOME

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

SINTASSI

       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *status);

       pid_t waitpid(pid_t pid, int *status, int opzioni);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int opzioni);
                       /* This is the glibc and POSIX interface; see
                          NOTES for information on the raw system call. */

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

       waitid():
           _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

DESCRIZIONE

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

       Se un figlio ha già cambiato stato, allora le chiamate tornano immediatamente.  Altrimenti
       esse si bloccano fino a quando un 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 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 processo chiamante fino  a  quando
       uno dei suoi figli termina.  La chiamata wait(&status) è equivalente a:

           waitpid(-1, &status, 0);

       La  chiamata  di  sistema  waitpid()  sospende  l'esecuzione del processo chiamante fino a
       quando un 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.

       > 0    che significa aspettare il 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 figlio è uscito.

       WUNTRACED   torna  anche  se  un  figlio  si  è  arrestato  (ma  non  tracciato attraverso
                   ptrace(2)).  Lo stato del 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 figlio arrestato è stato riesumato inviando SIGCONT.

       (Per le opzioni solo Linux vedere oltre).

       Se status 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(stato)
              restituisce  true se il figlio è terminato normalmente, ovvero, chiamando exit(3) o
              _exit(2), o tornando da main().

       WEXITSTATUS(stato)
              ritorna  lo  stato  di  uscita  del  figlio.   Esso  consiste  negli  8  bit   meno
              significativi  dell'argomento status che il 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(stato)
              restituisce true se il processo figlio è stato terminato da un segnale.

       WTERMSIG(stato)
              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(stato)
              restituisce true se il figlio ha prodotto un core dump.  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 tra #ifdef WCOREDUMP ... #endif.

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

       WSTOPSIG(stato)
              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(stato)
              (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 figlio(i) da aspettare, come segue:

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

       idtype == P_PGID
              Aspetta qualunque figlio il cui ID di gruppo del processo corrisponda a id.

       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 figlio che è terminato.

       WSTOPPED    Aspetta il 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 figlio in uno stato in attesa; una successiva chiamata di attesa può
                   essere usata per trovare di nuovo l'informazione sullo stato del 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 figlio.

       si_uid      L'ID reale dell'utente del 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  figlio,  come dato a _exit(2) (o exit(3)), o il
                   segnale che ha causato la  terminazione,  l'arresto  o  la  continuazione  del
                   figlio.   Il  campo si_code può essere usato per determinare come interpretare
                   questo campo.

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

       Se WNOHANG è stato specificato in opzioni e non c'erano figli  in  uno  stato  di  attesa,
       allora  waitid()  restituisce immediatamente 0, e lo stato della struttura siginfo_t a cui
       punta infop non è specificato.  Per distinguere questo caso da quello in cui un figlio era
       in  uno  stato  di  attesa, 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.

VALORI RESTITUITI

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

       waitpid():  in  caso  di successo, restituisce l'ID del processo del 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 errore restituisce -1.
       waitid(): restituisce 0 in caso  di  successo  o  se  WNOHANG  era  specificato  e  nessun
       figlio(i)  specificato  da  id ha ancora cambiato stato; in caso di errore restituisce -1.
       Ciascuna di queste chiamate imposta errno ad un valore appropriato in caso di errore.

ERRORI

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

       ECHILD (per waitpid() o waitid()) Il processo specificato da pid (waitpid()) o idtype e id
              (waitid())  non  esiste  o non è un figlio del processo chiamante (ciò può accadere
              per il 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.

CONFORME A

       SVr4, 4.3BSD, POSIX.1-2001.

NOTE

       Un 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 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(8), che automaticamente esegue 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  figlio  termina e quindi restituisce l'ID del processo e lo stato di
       questo 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 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 figlio di un altro thread nello stesso gruppo del thread.i

       Le  seguenti  opzioni  specifiche  di  Linux devono essere usate con i figli creati usando
       clone(2); esse non possono essere usate con waitid():

       __WCLONE
              Aspetta solo i figli di "clone".  Se omessa  allora  aspetta  solo  i  figli  "non-
              clone".   (Un  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.

   Differenze tra le ABI della libreria C e quelle del kernel
       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 figlio, 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 figlio aspettato.  Le applicazioni
       dovrebbero evitare di contare su questa caratteristica non conforme, non  standard  e  non
       necessaria.

ESEMPIO

       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 figlio sospende la propria esecuzione usando pause(2), per permettere
       all'utente di mandare il segnale al figlio.  Altrimenti, se  viene  fornito  un  argomento
       dalla  linea  di  comando,  allora  il figlio esce immediatamente, usando l'intero fornito
       dalla linea di comando come stato di uscita.  Il processo genitore  esegue  un  ciclo  che
       controlla  il  figlio usando waitpid(), e usa le macro W*() descritte sopra per analizzare
       il valore dello stato di attesa.

       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 <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

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

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

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

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

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

VEDERE ANCHE

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

COLOPHON

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

       La versione italiana fa parte del pacchetto man-pages-it v. 3.73, a cura di: ILDP "Italian
       Linux Documentation Project" http://www.pluto.it/ildp
       Per    la     traduzione     in     italiano     si     può     fare     riferimento     a
       http://www.pluto.it/ildp/collaborare/
       Segnalare eventuali errori di traduzione a ildp@pluto.it