oracular (2) waitpid.2.gz

Provided by: manpages-it-dev_4.23.1-1_all bug

NOME

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

LIBRERIA

       Libreria C standard (libc, -lc)

SINTASSI

       #include <sys/wait.h>

       pid_t wait(int *_Nullable wstatus);
       pid_t waitpid(pid_t pid, int *_Nullable 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():
           Since glibc 2.26:
               _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L
           glibc 2.25 and earlier:
               _XOPEN_SOURCE
                   || /* Since 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  (per wait()  o waitpid())  pid è uguale a INT_MIN.

VERSIONI

   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.

CONFORME A

       POSIX.1-2008.

STORIA

       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.

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 <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/types.h>
       #include <sys/wait.h>
       #include <unistd.h>

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

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

           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %jd\n", (intmax_t) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               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)

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⟩.