operating-systems/lab1/v7/using_signal_handlers.c

80 lines
2.0 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
struct ping_pong_data_t {
char const *name;
pid_t pid_to_print;
pid_t pid_to_send;
double delay_seconds;
} ping_pong_data;
void do_ping_pong(int signo) {
if (signo != SIGUSR1)
return;
printf("[%s] Got signal\n", ping_pong_data.name);
printf("[%s] Another side PID=%d\n", ping_pong_data.name, ping_pong_data.pid_to_print);
printf("[%s] Sleeping %lf seconds before sending signal\n", ping_pong_data.name, ping_pong_data.delay_seconds);
usleep((useconds_t) (1000 * 1000 * ping_pong_data.delay_seconds));
printf("[%s] Sending signal\n", ping_pong_data.name);
kill(ping_pong_data.pid_to_send, SIGUSR1);
}
volatile int is_running = 1;
void interrupt(int signo) {
if (signo != SIGINT)
return;
is_running = 0;
}
int main(void) {
signal(SIGINT, interrupt);
pid_t parent_pid = getpid();
pid_t child_pid = fork();
switch (child_pid) {
case -1:
perror("Failed to fork\n");
return EXIT_FAILURE;
case 0:
child_pid = getpid();
ping_pong_data.name = "\033[36mchild\033[0m";
ping_pong_data.delay_seconds = 1.5;
ping_pong_data.pid_to_print = parent_pid;
ping_pong_data.pid_to_send = parent_pid;
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
signal(SIGUSR1, do_ping_pong);
break;
default:
ping_pong_data.name = "\033[31mparent\033[0m";
ping_pong_data.delay_seconds = 1.5;
ping_pong_data.pid_to_print = child_pid;
ping_pong_data.pid_to_send = child_pid;
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
signal(SIGUSR1, do_ping_pong);
kill(parent_pid, SIGUSR1);
break;
}
while (is_running)
pause();
printf("[%s] Interrupted\n", ping_pong_data.name);
return EXIT_SUCCESS;
}