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/