Provided by: manpages-it_2.80-3_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);

   Test   delle   funzioni   e   requisiti   delle  macro  per  glibc  (vedere
   feature_test_macros(7)):

       waitid(): _SVID_SOURCE || _XOPEN_SOURCE

DESCRIZIONE

       Tutte queste chiamate di sistema sono usate 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).

       Le opzioni WUNTRACED  e  WCONTINUED  hanno  effetto  solo  se  il  flag
       SA_NOCLDSTOP  non  è  stato  impostato  per  il segnale SIGCHLD (vedere
       sigaction(2)).

       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_STOPPED
                   (figlio  arrestato  da un segnale); 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 untercettato un segnale
              sbloccato o un SIGCHLD.

       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  è  settato  per   SIGCHLD   (vedere
       sigaction(2)),  allora  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   SIGCHILD   è   "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.

       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(apartiredaLinux2.4)
              Non aspetta figli  di  altri  thread  nello  stesso  gruppo  del
              thread.   Questo era il comportamento predefinito prima di Linux
              2.4.

ESEMPIO

       Il seguente programma dimostra  l’uso  di  fork(2)  e  waitpid(2).   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(2), e usa le macro W*() descritte in precedenza 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
       $

       #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  2.80  del  progetto  man-pages  di
       Linux.   Si può trovare una descrizione del progetto, e informazioni su
       come riportare bachi, presso http://www.kernel.org/doc/man-pages/.  Per
       la    traduzione    in    italiano    si   può   fare   riferimento   a
       http://www.pluto.it/ildp/collaborare/