Elaborato_SO/src/custom_sig.c

198 lines
4.9 KiB
C
Raw Permalink Normal View History

2023-05-21 11:53:23 +02:00
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
2023-05-21 11:53:23 +02:00
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
2023-05-21 11:53:23 +02:00
#include <custom_sig.h>
#include <structures.h>
#include <errExit.h>
2023-05-22 10:07:57 +02:00
#include <custom_msgq.h>
2023-05-23 15:16:06 +02:00
#include <custom_sem.h>
2023-05-23 15:41:23 +02:00
#include <custom_shm.h>
#include <forza4.h>
2023-05-31 11:13:23 +02:00
#include <client.h>
2023-05-21 11:53:23 +02:00
2023-05-23 15:47:34 +02:00
pid_t _PIDS[2];
2023-05-21 11:53:23 +02:00
2023-05-31 11:52:32 +02:00
void setServerSignal(int sig);
2023-05-21 11:53:23 +02:00
void sigHandlerServer(int sig) {
2023-05-21 17:59:02 +02:00
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);
}
2023-05-21 11:53:23 +02:00
}
2023-05-31 12:15:20 +02:00
// abbandono di un giocatore
2023-05-31 12:05:54 +02:00
if (sig == SIGUSR1) {
2023-05-31 11:52:32 +02:00
// 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);
2023-06-01 15:03:34 +02:00
2023-06-01 10:35:49 +02:00
raise(SIGTERM);
2023-05-31 11:52:32 +02:00
}
2023-05-21 17:59:02 +02:00
2023-06-17 10:45:51 +02:00
if (sig == SIGALRM) {
printf(PSERVER "Out of time, player %d won\n", turn ^1);
end_game(turn ^ 1);
}
2023-05-21 11:53:23 +02:00
if (sig == SIGTERM || sig == SIGHUP) {
if (_PIDS[0] > 0) {
2023-05-22 11:03:36 +02:00
printf(PSERVER "Terminating player one\n");
kill(_PIDS[0], SIGTERM);
2023-05-21 11:53:23 +02:00
}
if (_PIDS[1] > 0) {
2023-05-22 11:03:36 +02:00
printf(PSERVER "Terminating player two\n");
kill(_PIDS[1], SIGTERM);
2023-05-21 11:53:23 +02:00
}
// msgq
if (_MSGQID) {
2023-05-22 11:03:36 +02:00
printf(PSERVER "Deleting msg\n");
if (msgctl(_MSGQID, IPC_RMID, NULL) == -1) {
2023-05-21 11:53:23 +02:00
errExit("msgctl", "sigHandlerServer");
}
}
// sem
if (_SEMID) {
2023-05-22 11:03:36 +02:00
printf(PSERVER "Deleting sem\n");
if (semctl(_SEMID, 0, IPC_RMID, 0) == -1) {
2023-05-21 11:53:23 +02:00
errExit("semctl", "sigHandlerServer");
}
}
// shm
if (_BOARD) {
2023-05-22 11:03:36 +02:00
printf(PSERVER "Detathing shm\n");
if (shmdt(_BOARD) == -1) {
2023-05-21 11:53:23 +02:00
errExit("shmdt", "sigHandlerServer");
}
}
if (_SHMID){
2023-05-22 11:03:36 +02:00
printf(PSERVER "Deleting shm\n");
if (shmctl(_SHMID, IPC_RMID, NULL) == -1) {
2023-05-21 11:53:23 +02:00
errExit("shmctl", "SigHandlerSever");
}
}
2023-05-22 11:03:36 +02:00
2023-05-21 11:59:15 +02:00
exit(0);
}
2023-05-31 11:52:32 +02:00
2023-05-21 11:53:23 +02:00
}
2023-05-22 10:27:46 +02:00
void setupServerSignalHandler() {
2023-05-21 11:53:23 +02:00
sigset_t mySet;
sigfillset(&mySet);
2023-05-22 09:32:58 +02:00
2023-05-21 11:53:23 +02:00
sigdelset(&mySet, SIGINT);
sigdelset(&mySet, SIGTERM);
sigdelset(&mySet, SIGHUP);
sigdelset(&mySet, SIGALRM);
2023-05-31 11:52:32 +02:00
sigdelset(&mySet, SIGUSR1);
2023-05-21 11:53:23 +02:00
sigprocmask(SIG_SETMASK, &mySet, NULL);
2023-05-31 11:52:32 +02:00
setServerSignal(SIGINT);
setServerSignal(SIGTERM);
setServerSignal(SIGHUP);
setServerSignal(SIGALRM);
setServerSignal(SIGUSR1);
2023-05-21 11:53:23 +02:00
}
2023-05-31 11:52:32 +02:00
void setServerSignal(int sig) {
2023-05-21 11:53:23 +02:00
if (signal(sig, sigHandlerServer) == SIG_ERR) {
errExit("signal", "f4Server");
}
2023-05-29 12:35:04 +02:00
}
void sigHandlerClient(int sig) {
// Ctrl+C
2023-06-17 12:05:56 +02:00
if (sig == SIGINT && !clientBot) {
2023-06-05 16:17:20 +02:00
printf("\n" PCLIENT "Quitting game\n");
2023-05-31 11:52:32 +02:00
game_end_t game = {.mtype = GAME_END, .winner = ID ^ 1};
sndGame_end(&game);
2023-05-31 12:05:54 +02:00
kill(SERVER_PID, SIGUSR1);
2023-06-05 16:17:20 +02:00
printf(PSERVER "You quit\n");
kill(getpid(), SIGTERM);
2023-05-29 12:35:04 +02:00
}
// Terminazione e chiusura terminale
if (sig == SIGTERM || sig == SIGHUP) {
// shm
if (_BOARD) {
printf(PCLIENT "Detathing shm\n");
if (shmdt(_BOARD) == -1) {
errExit("shmdt", "sigHandlerServer");
}
}
2023-06-16 16:50:41 +02:00
printf("\n");
2023-05-31 11:52:32 +02:00
2023-05-29 12:35:04 +02:00
exit(0);
}
// Fine partita
if (sig == SIGUSR1) {
game_end_t winner;
rcvGame_end(&winner);
2023-05-31 11:13:23 +02:00
2023-06-17 12:46:59 +02:00
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");
}
2023-05-31 11:13:23 +02:00
}
2023-06-01 14:39:04 +02:00
2023-06-05 16:17:20 +02:00
// avviso server che ho ricevuto il messaggio
semOp(_SEMID, SERVER, 1);
2023-06-16 16:50:41 +02:00
raise(SIGTERM);
2023-05-29 12:35:04 +02:00
}
}
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");
}
2023-05-21 11:53:23 +02:00
}