diff options
Diffstat (limited to 'semestr-5/so/lista2/so21_lista_2/cycle.c')
-rw-r--r-- | semestr-5/so/lista2/so21_lista_2/cycle.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/semestr-5/so/lista2/so21_lista_2/cycle.c b/semestr-5/so/lista2/so21_lista_2/cycle.c new file mode 100644 index 0000000..7daf754 --- /dev/null +++ b/semestr-5/so/lista2/so21_lista_2/cycle.c @@ -0,0 +1,57 @@ +#include "csapp.h" + +static void signal_handler(int signum, siginfo_t *info, void *data) { + if (signum == SIGINT) { + safe_printf("(%d) Screw you guys... I'm going home!\n", getpid()); + _exit(0); + } +} + +static void play(pid_t next, const sigset_t *set) { + for (;;) { + printf("(%d) Waiting for a ball!\n", getpid()); + /* TODO: Something is missing here! */ + sigset_t mask; + sigfillset(&mask); + sigdelset(&mask, SIGUSR1); + sigdelset(&mask, SIGINT); + Sigsuspend(&mask); + usleep((300 + random() % 400) * 1000); + Kill(next, SIGUSR1); + printf("(%d) Passing ball to (%d)!\n", getpid(), next); + } +} + +int main(int argc, char *argv[]) { + if (argc != 2) + app_error("Usage: %s [CHILDREN]", argv[0]); + + int children = atoi(argv[1]); + + if (children < 4 || children > 20) + app_error("Give number of children in range from 4 to 20!"); + + /* Register signal handler for SIGUSR1 */ + struct sigaction action = {.sa_sigaction = signal_handler}; + Sigaction(SIGINT, &action, NULL); + Sigaction(SIGUSR1, &action, NULL); + + /* TODO: Start all processes and make them wait for the ball! */ + sigset_t mask; + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, NULL); + + pid_t prev_pid = getpid(); + + for (int i = 1; i <= children; i++) { + int pid = Fork(); + if (pid == 0) { + play(prev_pid, NULL); + } + prev_pid = pid; + } + + Kill(prev_pid, SIGUSR1); + play(prev_pid, NULL); + return EXIT_SUCCESS; +} |