#include #include #include #include #include #include #include /* For O_* constants */ #include /* For mode constants */ #include #include /* * https://github.com/marcotessarotto/exOpSys/tree/master/006.3signals4ipc * * processo padre e processo figlio * processo padre controlla il processo figlio attraverso dei signal * SIGUSR1 ("avvia la produzione"), * SIGUSR2 ("ferma la produzione"), * SIGTERM (fa terminare il processo figlio) * * processo padre riceve comandi da stdin: * +: avvia la produzione * -: ferma la produzione * q: termina tutto * */ pid_t child_pid; int cookie_machine_state; void child_process_signal_handler(int signum) { if (signum == SIGUSR1) { // accendi la cookie machine cookie_machine_state = 1; } else if (signum == SIGUSR2) { // spegni la cookie machine cookie_machine_state = 0; } else if (signum == SIGTERM) { printf("[child] ho ricevuto SIGTERM, ora termino\n"); exit(0); } printf("[child] cookie_machine_state = %d\n", cookie_machine_state); } void child_process() { if (signal(SIGUSR1, child_process_signal_handler) == SIG_ERR) { perror("signal"); exit(1); } if (signal(SIGUSR2, child_process_signal_handler) == SIG_ERR) { perror("signal"); exit(1); } if (signal(SIGTERM, child_process_signal_handler) == SIG_ERR) { perror("signal"); exit(1); } while (1) { while (cookie_machine_state) { printf("[child] COOKIE\n"); sleep(3); } // ora cookie_machine_state == 0 printf("[child] prima di pause()\n"); pause(); printf("[child] dopo pause()\n"); } } void parent_process() { printf("[parent] prima di sleep(2)\n"); // dormire 2 secondi sleep(2); printf("[parent] avvio la produzione\n"); // avviare la produzione di cookies if (kill(child_pid, SIGUSR1) == -1) { perror("kill"); exit(1); } printf("[parent] prima di sleep(10)\n"); // dormire 10 secondi sleep(10); printf("[parent] fermo la produzione\n"); // fermare la produzione di cookies if (kill(child_pid, SIGUSR2) == -1) { perror("kill"); exit(1); } printf("[parent] prima di sleep(2)\n"); // dormire 2 secondi sleep(2); printf("[parent] termino il processo figlio\n"); // fare terminare il processo figlio if (kill(child_pid, SIGTERM) == -1) { perror("kill"); exit(1); } if (wait(NULL) == -1) { perror("wait"); } printf("[parent] bye\n"); exit(0); } int main() { // pipe: // creare una pipe prima di invocare fork() // utilizzare la pipe per inviare comandi al processo figlio switch (child_pid = fork()) { case -1: perror("fork"); exit(1); case 0: child_process(); default: parent_process(); } }