-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon_niklas_version.c
118 lines (101 loc) · 3.27 KB
/
common_niklas_version.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* Game of luck: Implementation of the players (shooters)
*
* Course: Operating Systems and Multicore Programming - OSM lab
* assignment 1: game of luck.
*
* Author: Nikos Nikoleris <[email protected]>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "common.h"
/* These flags control the termination of the main loop and indicate the winner. */
volatile sig_atomic_t winner = 0;
/* TODO: Change this to 0 to make the children spin in the for loop before they
receive the SIGUSR2 signal */
volatile sig_atomic_t results = 0;
/**
* end_handler - handle the SIGUSR2 signal, the player will receive
* this signal when the game ends
* @signum: the signal that triggered this handler
*/
void end_handler(int signum)
{
/* TODO: Check that the signum is indeed SIGUSR2 */
//assert(signum == SIGUSR2);
/* TODO: "leave the game" make the appropriate changes to let the
current process exit*/
results = 1;
signal(signum, end_handler);
}
/**
* win_handler - handle the SIGUSR1 signal, player will receive the SIGUSR1 when
* he is the winner
* @signum: the signal that triggered this handler
*/
void win_handler(int signum)
{
/* TODO - Check that the signum is indeed SIGUSR1 */
//assert(signum == SIGUSR1);
/* TODO - this player is the winner, make the appropriate changes
upon reception of this singal */
winner = 1;
signal(signum, win_handler);
}
/**
* shooter - it simulates the players action during a game of lack.
* @id: id number of the player
* @seed_rd_fd: file descriptor of the pipe used to read the seed from
* @score_wr_fd: file descriptor of the pipe used to write the scores to
*/
void shooter(int id, int seed_fd_rd, int score_fd_wr)
{
pid_t pid;
int score, seed = 0;
/* TODO: Install SIGUSR1 handler */
signal(SIGUSR1, win_handler);
/* TODO: Install SIGUSR2 handler */
signal(SIGUSR2, end_handler);
pid = getpid();
fprintf(stderr, "player %d: I'm in this game (PID = %ld)\n",
id, (long)pid);
/* TODO: roll the dice, but before that, get a seed from the parent */
read(seed_fd_rd, &seed, sizeof(int));
srand(seed);
score = rand() % 10000;
fprintf(stderr, "player %d: I scored %d (PID = %ld\n", id, score, (long)pid);
/* TODO: send my score back */
write(score_fd_wr, &score, sizeof(score));
/* spin while I wait for the results */
while (!results) ;
if (winner)
fprintf(stderr, "player %d: Walking away rich\n", id);
fprintf(stderr, "player %d: Leaving the game (PID = %ld)\n",
id, (long)pid);
/* TODO: free resources and exit with success */
exit(EXIT_SUCCESS);
}
/**
* waitstat - explain the status returned by the wait()/waitpid() functions.
* @pid: pid of the process returned by the wait()/waitpid()
* @status: the status returned by the wait()/waitpid(), to be explained
* This is function is not complete, but in our case it is enough to print the
* exit value returned by each child process
*/
void waitstat(pid_t pid, int status)
{
if (WIFEXITED(status))
fprintf(stderr, "Child with PID = %ld terminated normally, exit"
" status = %d\n", (long)pid, WEXITSTATUS(status));
else {
fprintf(stderr, "%s: Internal error: Unhandled case, PID = %ld,"
" status = %d\n", __func__, (long)pid, status);
exit(1);
}
fflush(stderr);
}