Elaborato_SO/src/custom_sig.c

198 lines
4.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <custom_sig.h>
#include <structures.h>
#include <errExit.h>
#include <custom_msgq.h>
#include <custom_sem.h>
#include <custom_shm.h>
#include <forza4.h>
#include <client.h>
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");
}
}