Advertisement
Vladislav8653

Untitled

Dec 23rd, 2023
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.89 KB | None | 0 0
  1. #include <bits/types/struct_timeval.h>
  2. #include <errno.h>
  3. #include <libgen.h>
  4. #include <signal.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/mman.h>
  9. #include <sys/time.h>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12.  
  13. //1->2 2->(3,4,5) 4->6 3->7 5->8
  14. //1->2 SIGUSR2 2->(3,4,5)SIGUSR1 4->6 SIGUSR1 3->7 SIGUSR1 5->8 SIGUSR1 8->1 SIGUSR2
  15.  
  16. #define PROCESSES_COUNT 9
  17. #define PARENTS_COUNT 6
  18.  
  19. static int RECEIVERS_IDS[PROCESSES_COUNT] = { -1, 2, 3, 7, 6, 8, -1, -1, 1 };
  20. static int SIGNALS_TO_SEND[PROCESSES_COUNT] = { -1, SIGUSR2, SIGUSR1, SIGUSR1, SIGUSR1, SIGUSR1, -1, -1, SIGUSR2};
  21. static int GROUPS_INFO[PROCESSES_COUNT] = { 0, 1, 2, 3, 3, 3, 6, 7, 8 };
  22.  
  23. typedef struct {
  24. int process_number;
  25. int children_count;
  26. int *children;
  27. } info;
  28.  
  29. void createForkingScheme(info *tree) {
  30. int sus = 0;
  31. tree[sus].process_number = 0;
  32. tree[sus].children_count = 1;
  33. tree[sus].children = malloc(sizeof(int));
  34. tree[sus].children[0] = 1;
  35. sus++;
  36. tree[sus].process_number = 1;
  37. tree[sus].children_count = 1;
  38. tree[sus].children = malloc(sizeof(int));
  39. tree[sus].children[0] = 2;
  40. sus++;
  41. tree[sus].process_number = 2;
  42. tree[sus].children_count = 3;
  43. tree[sus].children = malloc(sizeof(int) * 3);
  44. tree[sus].children[0] = 3;
  45. tree[sus].children[1] = 4;
  46. tree[sus].children[2] = 5;
  47. sus++;
  48. tree[sus].process_number = 4;
  49. tree[sus].children_count = 1;
  50. tree[sus].children = malloc(sizeof(int));
  51. tree[sus].children[0] = 6;
  52. sus++;
  53. tree[sus].process_number = 3;
  54. tree[sus].children_count = 1;
  55. tree[sus].children = malloc(sizeof(int));
  56. tree[sus].children[0] = 7;
  57. sus++;
  58. tree[sus].process_number = 5;
  59. tree[sus].children_count = 1;
  60. tree[sus].children = malloc(sizeof(int));
  61. tree[sus].children[0] = 8;
  62. }
  63.  
  64. long long currentTime() {
  65. struct timeval time;
  66. gettimeofday(&time, NULL);
  67. return time.tv_usec / 1000;
  68. }
  69.  
  70. char* signalName(int signum) {
  71. switch (signum) {
  72. case SIGUSR1:
  73. return "USR1";
  74. case SIGUSR2:
  75. return "USR2";
  76. default:
  77. return "not found";
  78. }
  79. }
  80.  
  81. void printInfo(int process_number, char is_received, int signal_number) {
  82. if (is_received) {
  83. printf("%d [%d] received %s from %d; %lld\n", process_number, getpid(), signalName(signal_number), getppid(), currentTime());
  84. } else {
  85. printf("%d [%d] sent %s; ppid %d; %lld\n", process_number, getpid(), signalName(signal_number), getppid(), currentTime());
  86. }
  87. fflush(stdout);
  88. }
  89.  
  90. void printStat(int usr1_count, int usr2_count) {
  91. printf("%d %d finished after USR1 №%d and USR2 №%d\n", getpid(), getppid(), usr1_count, usr2_count);
  92. }
  93.  
  94. char *MODULE_NAME;
  95. int *PROCESSES_PIDS;
  96. int PROCESS_NUMBER = 0;
  97. int sig_received = 0;
  98. int sig_usr1_sent = 0;
  99. int sig_usr2_sent = 0;
  100. info *FORKING_SCHEME;
  101.  
  102. info* getForkInfo(int process_number, info *tree) {
  103. for (int i = 0; i < PARENTS_COUNT; i++) {
  104. if (tree[i].process_number == process_number) {
  105. return &(tree[i]);
  106. }
  107. }
  108. return NULL;
  109. }
  110.  
  111. void signalHandler(int signum) {
  112. if (signum != SIGTERM) {
  113. printInfo(PROCESS_NUMBER, 1, signum);
  114. int receiver_number = RECEIVERS_IDS[PROCESS_NUMBER];
  115. sig_received++;
  116. if (PROCESS_NUMBER == 1) {
  117. if (sig_received == 101) {
  118. kill(-PROCESSES_PIDS[RECEIVERS_IDS[PROCESS_NUMBER]], SIGTERM);
  119. while (wait(NULL) > 0) {
  120. }
  121. exit(0);
  122. }
  123. }
  124. if (receiver_number != -1) {
  125. int signal_to_send = SIGNALS_TO_SEND[PROCESS_NUMBER];
  126. usleep(100);
  127. if (kill(-PROCESSES_PIDS[RECEIVERS_IDS[PROCESS_NUMBER]], signal_to_send) == -1) {
  128. exit(1);
  129. } else {
  130. printInfo(PROCESS_NUMBER, 0, signal_to_send);
  131. if (signal_to_send == SIGUSR1) {
  132. sig_usr1_sent++;
  133. } else {
  134. sig_usr2_sent++;
  135. }
  136. }
  137. }
  138. } else {
  139. kill(-PROCESSES_PIDS[RECEIVERS_IDS[PROCESS_NUMBER]], SIGTERM);
  140. while (wait(NULL) > 0) {
  141. }
  142. if (PROCESS_NUMBER != 1) {
  143. printStat(sig_usr1_sent, sig_usr2_sent);
  144. }
  145. exit(0);
  146. }
  147. }
  148.  
  149. void clearForkingScheme(info *tree) {
  150. for (int i = 0; i < PARENTS_COUNT; i++) {
  151. free(tree[i].children);
  152. }
  153. free(tree);
  154. }
  155.  
  156. char isAllSet(pid_t *process_pids) {
  157. for (int i = 0; i < PROCESSES_COUNT; i++) {
  158. if (!process_pids[i]) {
  159. return 0;
  160. }
  161. }
  162. return 1;
  163. }
  164.  
  165. void startProcess() {
  166. PROCESSES_PIDS[0] = getpid();
  167. int forked_process_number;
  168. int child_number = 0;
  169. pid_t group_leader;
  170. info *forking_info;
  171.  
  172. struct sigaction sig_handler;
  173. sig_handler.sa_handler = &signalHandler;
  174. sig_handler.sa_flags = 0;
  175. sigset_t sigset;
  176.  
  177. sigemptyset(&sigset);
  178.  
  179.  
  180. while ((forking_info = getForkInfo(PROCESS_NUMBER, FORKING_SCHEME)) && (child_number < forking_info->children_count)) {
  181. forked_process_number = forking_info->children[child_number];
  182. pid_t child = fork();
  183. switch (child) {
  184. case 0:
  185. child_number = 0;
  186. PROCESS_NUMBER = forked_process_number;
  187. break;
  188. case -1:
  189. exit(1);
  190. default:
  191. while (!(group_leader = PROCESSES_PIDS[GROUPS_INFO[forked_process_number]])) {
  192. }
  193. if (setpgid(child, group_leader) == -1) {
  194. exit(1);
  195. }
  196. child_number++; //next
  197. }
  198. }
  199. sigaction(SIGUSR1, &sig_handler, 0);
  200. sigaction(SIGUSR2, &sig_handler, 0);
  201. sigaction(SIGTERM, &sig_handler, 0);
  202. PROCESSES_PIDS[PROCESS_NUMBER] = getpid();
  203. if (PROCESS_NUMBER == 1) {
  204. while (!isAllSet(PROCESSES_PIDS)) {
  205. }
  206. int signal_to_send = SIGNALS_TO_SEND[PROCESS_NUMBER];
  207. kill(-PROCESSES_PIDS[RECEIVERS_IDS[PROCESS_NUMBER]], signal_to_send);
  208. printInfo(PROCESS_NUMBER, 0, signal_to_send);
  209. }
  210. if (PROCESS_NUMBER == 0) {
  211. wait(NULL);
  212. return;
  213. }
  214. while (1) {
  215. sleep(1);
  216. };
  217. }
  218.  
  219. int main(int argc, char *argv[]) {
  220. MODULE_NAME = basename(argv[0]);
  221. FORKING_SCHEME = malloc(sizeof(info) * PARENTS_COUNT);
  222. createForkingScheme(FORKING_SCHEME);
  223. PROCESSES_PIDS = mmap(NULL, PROCESSES_COUNT * sizeof(pid_t),
  224. PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  225. startProcess();
  226. munmap(PROCESSES_PIDS, sizeof(pid_t) * PROCESSES_COUNT);
  227. clearForkingScheme(FORKING_SCHEME);
  228. return 0;
  229. }
  230.  
  231.  
  232.  
  233.  
  234.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement