#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include pid_t _PIDS[2]; void setServerSignal(int sig); void sigHandlerServer(int sig) { if (sig == SIGINT) { static int last_sigint = 0; if (time(0) - last_sigint >= TIME_TO_RESET) { printf("\n" PSERVER "Press again Ctrl^C to exit (within %d sec)\n", TIME_TO_RESET); last_sigint = time(0); } else { raise(SIGTERM); } } // abbandono di un giocatore if (sig == SIGUSR1) { // il giocatore che abbandona mi manda gia il messaggio dicendo che ha vinto l'altro game_end_t game; rcvGame_end(&game); sndGame_end(&game); kill(_PIDS[game.winner], SIGUSR1); // aspetto che i figli ricevano i messaggi semOp(_SEMID, SERVER, -1); kill(_PIDS[game.winner], SIGTERM); raise(SIGTERM); } if (sig == SIGALRM) { printf(PSERVER "Out of time, player %d won\n", turn ^1); end_game(turn ^ 1); } if (sig == SIGTERM || sig == SIGHUP) { if (_PIDS[0] > 0) { printf(PSERVER "Terminating player one\n"); kill(_PIDS[0], SIGTERM); } if (_PIDS[1] > 0) { printf(PSERVER "Terminating player two\n"); kill(_PIDS[1], SIGTERM); } // msgq if (_MSGQID) { printf(PSERVER "Deleting msg\n"); if (msgctl(_MSGQID, IPC_RMID, NULL) == -1) { errExit("msgctl", "sigHandlerServer"); } } // sem if (_SEMID) { printf(PSERVER "Deleting sem\n"); if (semctl(_SEMID, 0, IPC_RMID, 0) == -1) { errExit("semctl", "sigHandlerServer"); } } // shm if (_BOARD) { printf(PSERVER "Detathing shm\n"); if (shmdt(_BOARD) == -1) { errExit("shmdt", "sigHandlerServer"); } } if (_SHMID){ printf(PSERVER "Deleting shm\n"); if (shmctl(_SHMID, IPC_RMID, NULL) == -1) { errExit("shmctl", "SigHandlerSever"); } } exit(0); } } void setupServerSignalHandler() { sigset_t mySet; sigfillset(&mySet); sigdelset(&mySet, SIGINT); sigdelset(&mySet, SIGTERM); sigdelset(&mySet, SIGHUP); sigdelset(&mySet, SIGALRM); sigdelset(&mySet, SIGUSR1); sigprocmask(SIG_SETMASK, &mySet, NULL); setServerSignal(SIGINT); setServerSignal(SIGTERM); setServerSignal(SIGHUP); setServerSignal(SIGALRM); setServerSignal(SIGUSR1); } void setServerSignal(int sig) { if (signal(sig, sigHandlerServer) == SIG_ERR) { errExit("signal", "f4Server"); } } void sigHandlerClient(int sig) { // Ctrl+C if (sig == SIGINT && !clientBot) { printf("\n" PCLIENT "Quitting game\n"); game_end_t game = {.mtype = GAME_END, .winner = ID ^ 1}; sndGame_end(&game); kill(SERVER_PID, SIGUSR1); printf(PSERVER "You quit\n"); kill(getpid(), SIGTERM); } // Terminazione e chiusura terminale if (sig == SIGTERM || sig == SIGHUP) { // shm if (_BOARD) { printf(PCLIENT "Detathing shm\n"); if (shmdt(_BOARD) == -1) { errExit("shmdt", "sigHandlerServer"); } } printf("\n"); exit(0); } // Fine partita if (sig == SIGUSR1) { game_end_t winner; rcvGame_end(&winner); if (!clientBot) { printBoard(); if (winner.winner == ID) { printf(PSERVER "YOU WIN!!!\n"); } else if (winner.winner == -1) { printf(PSERVER "DRAW!!!\n"); } else { printf(PSERVER "YOU LOSE!!!\n"); } } // avviso server che ho ricevuto il messaggio semOp(_SEMID, SERVER, 1); raise(SIGTERM); } } void setupClientSignalHandler(){ printf(PCLIENT "Setting up signal\n"); sigset_t mySet; sigfillset(&mySet); sigdelset(&mySet, SIGINT); sigdelset(&mySet, SIGTERM); sigdelset(&mySet, SIGHUP); sigdelset(&mySet, SIGUSR1); sigprocmask(SIG_SETMASK, &mySet, NULL); if (signal(SIGINT, sigHandlerClient) == SIG_ERR) { errExit("signal SIGINT", "F4Client"); } if (signal(SIGTERM, sigHandlerClient) == SIG_ERR) { errExit("signal SIGTERM", "F4Client"); } if (signal(SIGHUP, sigHandlerClient) == SIG_ERR) { errExit("signal SIGHUP", "F4Client"); } if (signal(SIGUSR1, sigHandlerClient) == SIG_ERR) { errExit("signal SIGUSR1", "F4Client"); } }