#include <stdio.h>
#include <stdlib.h>     // Per exit(), abort()
#include <unistd.h>     // Per fork(), getpid()
#include <sys/types.h>  // Per pid_t
#include <sys/wait.h>   // Per waitpid() e le macro

int main() {
    pid_t pid1, pid2;
    int wstatus;
    pid_t pid_terminato;
    // --- Primo figlio (che terminerà correttamente) ---
    pid1 = fork();
    if(pid1 < 0) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (pid1 == 0) {
        sleep(1); // Diamo tempo al padre di mettersi in attesa
        printf("[FIGLIO %d] termino con stato 42.\n", getpid());
        exit(42); // Uscita normale con valore 42
    }
    // --- Secondo figlio (che terminerà con un segnale) ---
    pid2 = fork();
    if(pid2 < 0) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    if (pid2 == 0) {
        sleep(1); // Diamo tempo al padre di mettersi in attesa
        printf("[FIGLIO %d] genero un errore (abort).\n", getpid());
        abort(); // Termina con un segnale (SIGABRT)
    }
    // --- Codice del Padre ---
    printf("[PADRE] Ho creato i figli %d e %d. Ora attendo...\n", pid1, pid2);
    // Usiamo un loop per attendere TUTTI i figli
    int figli_raccolti = 0;
    while (figli_raccolti < 2) {
        pid_terminato = wait(&wstatus); // Attende un figlio qualsiasi
        figli_raccolti++;
        printf("[PADRE] Raccolto il figlio %d.\n", pid_terminato);
        // Analisi 'wstatus'
        if (WIFEXITED(wstatus)) {
            // Caso 1: Uscita normale (exit())
            // Recuperiamo il valore passato a exit()
            int exit_status_figlio = WEXITSTATUS(wstatus);
            printf("[PADRE]\t\t Il figlio %d è terminato NORMALMENTE ed ha restituito %d.\n", pid_terminato, exit_status_figlio);
        } else if (WIFSIGNALED(wstatus)) {
            // Caso 2: Uscita anormale (segnale)
            // Recuperiamo il numero del segnale
            int segnale_ricevuto = WTERMSIG(wstatus);
            printf("[PADRE]\t\t Il figlio %d è terminato da un SEGNALE: %d.\n", pid_terminato, segnale_ricevuto);
        } else {
            printf("[PADRE]\t\t Il figlio %d è terminato in un altro modo.\n", pid_terminato);
        }
    }
    printf("[PADRE] Tutti i figli sono stati raccolti. Termino.\n");
    return 0;
}