bionic (2) wait.2.gz

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