Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef Posix_compile
- #include <unistd.h>
- #include <errno.h>
- #include <signal.h>
- #include <pthread.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/mman.h>
- #include <sys/sem.h>
- #include <semaphore.h>
- #include <fcntl.h>
- #else
- #include <windows.h>
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define data_slice 5
- int N, sem, *fd, num_cycles;
- char buffer[data_slice];
- void error_handler(char *message) {
- fprintf(stderr, "%s\n", message);
- perror("ERROR");
- exit(EXIT_FAILURE);
- }
- void *thread(void *my_index) {
- int ret;
- struct sembuf oper;
- oper.sem_flg = SEM_UNDO;
- while (1) {
- oper.sem_num = (long)my_index;
- oper.sem_op = -1;
- stepA: ret = semop(sem, &oper, 1);
- if (ret == -1 && errno != EINTR)
- error_handler("semop has failed");
- if (ret == -1)
- goto stepA;
- stepB: ret = write(fd[(long)my_index], buffer, data_slice);
- if (ret == -1 && errno != EINTR)
- error_handler("write has failed");
- if (ret == -1)
- goto stepB;
- oper.sem_num = N;
- oper.sem_op = 1;
- stepC: ret = semop(sem, &oper, 1);
- if (ret == -1 && errno == EINTR)
- error_handler("semop has failed");
- if (ret == -1)
- goto stepC;
- }
- }
- void SIGINT_handler(int signo, siginfo_t *a, void *b) {
- int i, j, index = 0;
- char c;
- for(i = 0; i < N; i++) {
- lseek(fd[i], 0, SEEK_SET);
- }
- for(i = 0; i < num_cycles; i++) {
- for(j = 0; j < data_slice; j++) {
- read(fd[index], &c, 1);
- printf("%c",c);
- }
- index = (index + 1) % N;
- }
- printf("\n");
- }
- int main(int argc, char *argv[]) {
- int ret, res, j;
- long i;
- pthread_t tid;
- sigset_t set;
- struct sembuf oper;
- struct sigaction act;
- if (argc < 2) {
- printf("Usage: pathname [pathname] ... [pathname]\n");
- exit(-1);
- }
- N = argc - 1;
- sem = semget(IPC_PRIVATE, N + 1, IPC_CREAT|0666);
- if (sem == -1)
- error_handler("semget has failed");
- fd =(int *)malloc(N*sizeof(int));
- if (fd == NULL)
- error_handler("malloc has failed");
- for(i = 0; i < N; i++) {
- ret = semctl(sem, i, SETVAL, 0);
- if (ret == -1)
- error_handler("semctl has failed");
- fd[i] = open(argv[i+1], O_CREAT|O_RDWR|O_TRUNC, 0666);
- if (fd[i] == -1)
- error_handler("Unable to open the file");
- }
- ret = semctl(sem, N, SETVAL, 1);
- if (ret == -1)
- error_handler("semctl has failed");
- for (i = 0; i < N; i++) {
- ret = pthread_create(&tid, NULL, thread, (void *)i);
- if (ret != 0)
- error_handler("pthread_create has failed");
- }
- sigfillset(&set);
- act.sa_sigaction = SIGINT_handler;
- act.sa_mask = set;
- act.sa_flags = 0;
- ret = sigaction(SIGINT, &act, NULL);
- if (ret == -1)
- error_handler("sigaction has failed");
- oper.sem_flg = SEM_UNDO;
- num_cycles = 0;
- i = 0;
- while (1) {
- res = 5;
- oper.sem_num = N;
- oper.sem_op = -1;
- step1: ret = semop(sem, &oper, 1);
- if (ret == -1 && errno != EINTR)
- error_handler("semop has failed");
- if (ret == -1)
- goto step1;
- j = 0;
- while (res > 0) {
- step2: buffer[j] = getchar();
- if (buffer[j] == EOF && errno != EINTR)
- error_handler("getchar has failed");
- if (buffer[j] == EOF || buffer[j] == '\n')
- goto step2;
- res--;
- j++;
- }
- oper.sem_num = i;
- oper.sem_op = 1;
- step3: ret = semop(sem, &oper, 1);
- if (ret == -1 && errno != EINTR)
- error_handler("semop has failed");
- if (ret == -1)
- goto step3;
- i = (i + 1) % N;
- num_cycles++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement