Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.41 KB | None | 0 0
  1. #ifdef Posix_compile
  2. #include <unistd.h>
  3. #include <errno.h>
  4. #include <signal.h>
  5. #include <pthread.h>
  6. #include <sys/types.h>
  7. #include <sys/ipc.h>
  8. #include <sys/mman.h>
  9. #include <sys/sem.h>
  10. #include <semaphore.h>
  11. #include <fcntl.h>
  12. #else
  13. #include <windows.h>
  14. #endif
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20.  
  21. #define data_slice 5
  22.  
  23.  
  24. int N, sem, *fd, num_cycles;
  25. char buffer[data_slice];
  26.  
  27.  
  28.  
  29. void error_handler(char *message) {
  30. fprintf(stderr, "%s\n", message);
  31. perror("ERROR");
  32. exit(EXIT_FAILURE);
  33. }
  34.  
  35.  
  36. void *thread(void *my_index) {
  37. int ret;
  38. struct sembuf oper;
  39.  
  40. oper.sem_flg = SEM_UNDO;
  41.  
  42. while (1) {
  43. oper.sem_num = (long)my_index;
  44. oper.sem_op = -1;
  45.  
  46. stepA: ret = semop(sem, &oper, 1);
  47. if (ret == -1 && errno != EINTR)
  48. error_handler("semop has failed");
  49. if (ret == -1)
  50. goto stepA;
  51.  
  52. stepB: ret = write(fd[(long)my_index], buffer, data_slice);
  53. if (ret == -1 && errno != EINTR)
  54. error_handler("write has failed");
  55. if (ret == -1)
  56. goto stepB;
  57.  
  58. oper.sem_num = N;
  59. oper.sem_op = 1;
  60.  
  61. stepC: ret = semop(sem, &oper, 1);
  62. if (ret == -1 && errno == EINTR)
  63. error_handler("semop has failed");
  64. if (ret == -1)
  65. goto stepC;
  66. }
  67. }
  68.  
  69.  
  70. void SIGINT_handler(int signo, siginfo_t *a, void *b) {
  71. int i, j, index = 0;
  72. char c;
  73.  
  74. for(i = 0; i < N; i++) {
  75. lseek(fd[i], 0, SEEK_SET);
  76. }
  77. for(i = 0; i < num_cycles; i++) {
  78. for(j = 0; j < data_slice; j++) {
  79. read(fd[index], &c, 1);
  80. printf("%c",c);
  81. }
  82. index = (index + 1) % N;
  83. }
  84. printf("\n");
  85. }
  86.  
  87.  
  88.  
  89. int main(int argc, char *argv[]) {
  90. int ret, res, j;
  91. long i;
  92. pthread_t tid;
  93. sigset_t set;
  94. struct sembuf oper;
  95. struct sigaction act;
  96.  
  97. if (argc < 2) {
  98. printf("Usage: pathname [pathname] ... [pathname]\n");
  99. exit(-1);
  100. }
  101. N = argc - 1;
  102.  
  103. sem = semget(IPC_PRIVATE, N + 1, IPC_CREAT|0666);
  104. if (sem == -1)
  105. error_handler("semget has failed");
  106.  
  107. fd =(int *)malloc(N*sizeof(int));
  108. if (fd == NULL)
  109. error_handler("malloc has failed");
  110.  
  111. for(i = 0; i < N; i++) {
  112. ret = semctl(sem, i, SETVAL, 0);
  113. if (ret == -1)
  114. error_handler("semctl has failed");
  115.  
  116. fd[i] = open(argv[i+1], O_CREAT|O_RDWR|O_TRUNC, 0666);
  117. if (fd[i] == -1)
  118. error_handler("Unable to open the file");
  119. }
  120. ret = semctl(sem, N, SETVAL, 1);
  121. if (ret == -1)
  122. error_handler("semctl has failed");
  123.  
  124. for (i = 0; i < N; i++) {
  125. ret = pthread_create(&tid, NULL, thread, (void *)i);
  126. if (ret != 0)
  127. error_handler("pthread_create has failed");
  128. }
  129. sigfillset(&set);
  130. act.sa_sigaction = SIGINT_handler;
  131. act.sa_mask = set;
  132. act.sa_flags = 0;
  133.  
  134. ret = sigaction(SIGINT, &act, NULL);
  135. if (ret == -1)
  136. error_handler("sigaction has failed");
  137.  
  138. oper.sem_flg = SEM_UNDO;
  139. num_cycles = 0;
  140. i = 0;
  141.  
  142. while (1) {
  143. res = 5;
  144.  
  145. oper.sem_num = N;
  146. oper.sem_op = -1;
  147.  
  148. step1: ret = semop(sem, &oper, 1);
  149. if (ret == -1 && errno != EINTR)
  150. error_handler("semop has failed");
  151. if (ret == -1)
  152. goto step1;
  153. j = 0;
  154. while (res > 0) {
  155. step2: buffer[j] = getchar();
  156. if (buffer[j] == EOF && errno != EINTR)
  157. error_handler("getchar has failed");
  158. if (buffer[j] == EOF || buffer[j] == '\n')
  159. goto step2;
  160. res--;
  161. j++;
  162. }
  163.  
  164. oper.sem_num = i;
  165. oper.sem_op = 1;
  166.  
  167. step3: ret = semop(sem, &oper, 1);
  168. if (ret == -1 && errno != EINTR)
  169. error_handler("semop has failed");
  170. if (ret == -1)
  171. goto step3;
  172.  
  173. i = (i + 1) % N;
  174. num_cycles++;
  175. }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement