wait

WAIT(2)                Manuale del programmatore di Linux                WAIT(2)



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  (for wait()  or waitpid())  pid is equal to 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 ⟨⟩.



Linux                            27 agosto 2021                          WAIT(2)