Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/shm.h>
- #include <sys/sem.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/msg.h>
- #define BUFSIZE 1
- #define R 0
- #define W 1
- // Struktura komunikatu
- struct msgbuf
- {
- long mtype;
- int mtext;
- } msg;
- // Struktura semafora
- #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
- #else
- union semun
- {
- int val; //value for SETVAL
- struct semid_ds *buf; //buffer for IPC_STAT, IPC_SET
- unsigned short int *array; //array for GETALL, SETALL
- struct seminfo *__buf; //buffer for IPC_INFO
- };
- #endif
- // zmienne do plikow z pidami procesow:
- int des_pid[2] = {};
- char bufor_proces[50] = {};
- // zmienne do kolejki komunikatow:
- int mqid;
- key_t mqkey = 1234;
- // Semaphore
- int semafor;
- int stan = 0; // 0 - pracuje, 1 - zatrzymany, 2 - koniec
- int sygnal_od_p1 = 2; // 0 - kill from user, 1 - kill from p1, 2 - another source of changes
- int sygnal_od_p2 = 2; // 0 - kill from user, 1 - kill from p1, 2 - another source of changes
- // PIDs:
- pid_t p0, p1, p2, p3;
- // FIFO
- int fifo_fd;
- unsigned char bufor[BUFSIZE] = {};
- unsigned char bufor1[BUFSIZE] = {};
- // Shared memory:
- key_t key;
- int shmid;
- char * tab;
- // pipes
- int file_des[2]; // file_des[0] - deskryptor do czytania, file_des[1] - deskryptor do pisania
- char bufor_pipe[BUFSIZE*30] = {};
- // signal handlers:
- // 1 = SIGHUP -> stan = 1 -> HOLD
- // 2 = SIGINT -> stan = 2 -> STOP
- // 17 = SIGCHLD -> stan = 0 -> WORK
- void sygnal_p0(int sig)
- {
- printf("***proces p0 odebral sygnal %d\n", sig);
- fflush(stdin);
- if(sig == 1)
- {
- if(semctl(semafor, 0, SETVAL, 1) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 1");
- exit(1);
- }
- stan = 1;
- }
- else if(sig == 2)
- {
- if(semctl(semafor, 0, SETVAL, 2) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 2");
- exit(1);
- }
- stan = 2;
- }
- else if(sig == 17)
- {
- if(semctl(semafor, 0, SETVAL, 0) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 0");
- exit(1);
- }
- stan = 0;
- }
- }
- void sygnal_p1(int sig)
- {
- printf("***proces p1 odebral sygnal %d\n", sig);
- fflush(stdin);
- if(sig == 1)
- {
- if(semctl(semafor, 0, SETVAL, 1) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
- exit(1);
- }
- sygnal_od_p2 = 0;
- stan = 1;
- }
- else if(sig == 2)
- {
- if(semctl(semafor, 0, SETVAL, 2) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 2");
- exit(1);
- }
- sygnal_od_p2 = 0;
- stan = 2;
- }
- else if(sig == 17)
- {
- if(semctl(semafor, 0, SETVAL, 0) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 0");
- exit(1);
- }
- sygnal_od_p2 = 0;
- stan = 0;
- }
- else if(sig == 10) // WORK signal from p2
- {
- if(semctl(semafor, 0, SETVAL, 0) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 0");
- exit(1);
- }
- sygnal_od_p2 = 1;
- stan = 0;
- }
- else if(sig == 12) // HOLD signal from p2
- {
- if(semctl(semafor, 0, SETVAL, 1) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
- exit(1);
- }
- sygnal_od_p2 = 1;
- stan = 1;
- }
- }
- void sygnal_p2(int sig)
- {
- printf("***proces p2 odebral sygnal %d\n", sig);
- fflush(stdin);
- if(sig == 1)
- {
- // zatrzymaj p3
- msg.mtype = 3;
- msg.mtext = 1;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"1\" z p2");
- exit(1);
- }
- sygnal_od_p1 = 0;
- // zatrzymaj sie
- stan = 1;
- }
- else if(sig == 2)
- {
- msg.mtype = 3;
- msg.mtext = 2;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"2\" z p2");
- exit(1);
- }
- sygnal_od_p1 = 0;
- stan = 2;
- }
- else if(sig == 17)
- {
- msg.mtype = 3;
- msg.mtext = 0;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"0\" z p2");
- exit(1);
- }
- sygnal_od_p1 = 0;
- stan = 0;
- }
- else if(sig == 10) // WORK signal from p1
- {
- msg.mtype = 3;
- msg.mtext = 0;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"0\" z p2");
- exit(1);
- }
- sygnal_od_p1 = 1;
- stan = 0;
- }
- else if(sig == 12) // HOLD signal from p2
- {
- // zatrzymaj p3
- msg.mtype = 3;
- msg.mtext = 1;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"1\" z p2");
- exit(1);
- }
- sygnal_od_p1 = 1;
- stan = 1;
- }
- }
- void sygnal_p3(int sig)
- {
- printf("***proces p3 odebral sygnal %d\n", sig);
- fflush(stdin);
- if(sig == 1)
- {
- msg.mtype = 2;
- msg.mtext = 1;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"1\" z p3");
- exit(1);
- }
- stan = 1;
- }
- else if(sig == 2)
- {
- msg.mtype = 2;
- msg.mtext = 2;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"2\" z p3");
- exit(1);
- }
- stan = 2;
- }
- else if(sig == 17)
- {
- msg.mtype = 2;
- msg.mtext = 0;
- if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
- {
- perror("blad wysylania komunikatu \"0\" z p3");
- exit(1);
- }
- stan = 0;
- }
- }
- // ciala procesow:
- void proces0()
- {
- ssize_t n;
- int poprzedni_stan = 0;
- signal(SIGINT, sygnal_p0);
- signal(SIGHUP, sygnal_p0);
- signal(SIGCHLD, sygnal_p0);
- while(stan == 0 || stan == 1)
- {
- while(stan == 0)
- {
- //printf("proces p0 dziala w petli while stan == 0\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan);
- //fflush(stdin);
- if(semctl(semafor, 0, GETVAL) != stan)
- {
- stan = semctl(semafor, 0, GETVAL);
- //printf("proces 0 zmienil swoj stan z 0 na : %d\n", stan);
- //fflush(stdin);
- }
- if(poprzedni_stan == 1) // proces0 byl uspiony i zauwazyl ze semafor zmienil sie na 0 czyli musi sie wznowic
- {
- poprzedni_stan = 0; // daj znac ze proces0 sie obudzil
- }
- if(tab[0] == 0)
- {
- fifo_fd = open("/tmp/fifo", O_WRONLY); // otwiera kolejke fifo do zapisu
- if(fifo_fd == -1)
- {
- perror("blad przy otwieraniu kolejki FIFO w p0\n");
- exit(1);
- }
- n = read(STDIN_FILENO, bufor, BUFSIZE);
- if(n<0)
- {
- perror("read error w p0\n");
- exit(1);
- }
- if(n > 0)
- {
- if(write(fifo_fd, bufor, n) != n)
- {
- perror("blad zapisu do kolejki fifo w p0\n");
- exit(1);
- }
- tab[0] = 1;
- memset(bufor, 0, sizeof(bufor)); // czyszczenie bufora
- }
- close(fifo_fd);
- }
- //sleep(1);
- }
- while(stan == 1)
- {
- //printf("proces p0 dziala w petli while stan == 1\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan);
- //fflush(stdin);
- if(semctl(semafor, 0, GETVAL) != stan)
- {
- stan = semctl(semafor, 0, GETVAL);
- printf("proces 0 zmienil swoj stan na : %d\n", stan);
- fflush(stdin);
- }
- if(poprzedni_stan == 0) // proces0 dzialal i zauwazyl, ze semafor zmienil sie na 1 (trzeba sie zatrzymac)
- {
- // wykonaj aktualne akcje do konca:
- if(tab[0] == 0)
- {
- fifo_fd = open("/tmp/fifo", O_WRONLY); // otwiera kolejke fifo do zapisu
- if(fifo_fd == -1)
- {
- perror("blad przy otwieraniu kolejki FIFO w p0\n");
- exit(1);
- }
- n = read(STDIN_FILENO, bufor, BUFSIZE);
- if(n<0)
- {
- perror("read error w p0\n");
- exit(1);
- }
- if(n > 0)
- {
- if(write(fifo_fd, bufor, n) != n)
- {
- perror("blad zapisu do kolejki fifo w p0\n");
- exit(1);
- }
- tab[0] = 1;
- memset(bufor, 0, sizeof(bufor)); // czyszczenie bufora
- }
- close(fifo_fd);
- }
- poprzedni_stan = 1;
- }
- //sleep(1);
- }
- }
- }
- void proces1()
- {
- ssize_t m, x, q;
- char wartosc_hex[30] = {};
- int poprzedni_stan = 0;
- int pid2 = 0;
- signal(SIGINT, sygnal_p1);
- signal(SIGHUP, sygnal_p1);
- signal(SIGCHLD, sygnal_p1);
- signal(SIGUSR1, sygnal_p1);
- signal(SIGUSR2, sygnal_p1);
- while( (stan == 0) || (stan == 1) )
- {
- while(stan == 0)
- {
- //printf("proces p1 dziala w petli while stan == 0\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\nsygnal_od_p2 = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan, sygnal_od_p2);
- //fflush(stdin);
- if(semctl(semafor, 0, GETVAL) != 0) // gdy semafor zostal zmieniony przez p0
- {
- //printf("proces p1 bedac w petli stan == 1 zauwazyl ze semafor ma wartosc %d\n", semctl(semafor, 0, GETVAL));
- //fflush(stdin);
- if(semctl(semafor, 0, GETVAL) == 1) // p0 zmienil semafor na 1 - rozpoczyna sie zatrzymywanie wszystkich procesow
- {
- stan = 1;
- //printf("proces 1 zmienil swoj stan na : %d\n", stan);
- //fflush(stdin);
- if(poprzedni_stan == 0) // sprawdzamy czy proces na pewno byl w ruchu, jesli nie to juz jest zatrzymany i nie trzeba nic robic
- {
- if(pid2 == 0)
- {
- des_pid[R] = open("pid2", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p2 w p1");
- exit(1);
- }
- pid2 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- kill(pid2, 12); // zatrzymujemy proces 2
- //printf("\nproces 1 wyslal sygnal 12 do procesu 2 w linii 449\n");
- //fflush(stdin);
- }
- sygnal_od_p2 = 2; // dajemy znac ze zrodlem zmiany stanu jest proces0
- }
- else
- {
- stan = 2;
- }
- }
- if(poprzedni_stan == 1)
- {
- if(sygnal_od_p2 == 0)
- {
- if(pid2 == 0)
- {
- des_pid[R] = open("pid2", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p2 w p1");
- exit(1);
- }
- pid2 = atoi(&bufor_proces[14]);
- //printf("proces1 odczytal PID procesu 2 w linii 439, czyli: %d\n", pid2);
- //fflush(stdin);
- close(des_pid[R]);
- }
- // budzimy proces2
- kill(pid2, 10);
- //printf("\nproces 1 wyslal sygnal 10 do procesu 2 w linii 482\n");
- //fflush(stdin);
- }
- poprzedni_stan = 0;
- }
- if(strlen(&tab[1]) == 0)
- {
- fifo_fd = open("/tmp/fifo", O_RDONLY); // otwiera plik typu fifo do odczytu
- if(fifo_fd == -1)
- {
- perror("blad przy otwieraniu kolejki FIFO w p1\n");
- exit(1);
- }
- m = read(fifo_fd, bufor1, BUFSIZE);
- x = m;
- if(x < 0)
- {
- perror("read error p1\n");
- exit(1);
- }
- if(x > 0)
- {
- // Konwersja na HEX
- if(bufor1[0] < 16)
- {
- if(bufor1[0] == 10) // gdy enter
- {
- sprintf(wartosc_hex, "0x0%X\n", bufor1[0]);
- }
- else
- {
- sprintf(wartosc_hex, "0x0%X ", bufor1[0]);
- }
- }
- else
- {
- sprintf(wartosc_hex, "0x%X ", bufor1[0]);
- }
- // poczekaj az pamiec bedzie pusta (gotowa do zapisu)
- strcpy(&tab[1], wartosc_hex);
- memset(bufor1, 0, sizeof(bufor1)); // czyszczenie bufora
- memset(wartosc_hex, 0, sizeof(wartosc_hex)); // przygotowanie tablicy na zapis wartosci hex
- x = 0;
- }
- close(fifo_fd);
- }
- //sleep(1);
- }
- while(stan == 1)
- {
- //printf("proces p1 dziala w petli while stan == 1\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\nsygnal_od_p2 = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan, sygnal_od_p2);
- //fflush(stdin);
- if(semctl(semafor, 0, GETVAL) != 1)
- {
- // printf("proces p1 bedac w petli stan == 1 zauwazyl ze semafor ma wartosc %d\n", semctl(semafor, 0, GETVAL));
- // fflush(stdin);
- if((semctl(semafor, 0, GETVAL) == 0))
- {
- stan = 0;
- //printf("proces 1 zmienil swoj stan na : %d\n", stan);
- //fflush(stdin);
- if(poprzedni_stan == 1)
- {
- if(pid2 == 0)
- {
- des_pid[R] = open("pid2", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p2 w p1");
- exit(1);
- }
- pid2 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- kill(pid2, 10);
- //printf("\nproces 1 wyslal sygnal 10 do procesu 2 w linii 561\n");
- //fflush(stdin);
- sygnal_od_p2 = 2;
- }
- }
- else
- {
- stan = 2;
- }
- }
- if(poprzedni_stan == 0)
- {
- if(sygnal_od_p2 == 0)
- {
- if(pid2 == 0)
- {
- des_pid[R] = open("pid2", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p2 w p1");
- exit(1);
- }
- pid2 = atoi(&bufor_proces[14]);
- //printf("proces1 odczytal PID procesu 2 w linii 516, czyli: %d\n", pid2);
- close(des_pid[R]);
- }
- kill(pid2, 12);
- //printf("\nproces 1 wyslal sygnal 12 do procesu 2 w linii 593\n");
- //fflush(stdin);
- sygnal_od_p2 = 2;
- }
- if(strlen(&tab[1]) == 0)
- {
- fifo_fd = open("/tmp/fifo", O_RDONLY); // otwiera plik typu fifo do odczytu
- if(fifo_fd == -1)
- {
- perror("blad przy otwieraniu kolejki FIFO w p1\n");
- exit(1);
- }
- m = read(fifo_fd, bufor1, BUFSIZE);
- if(m == 0) break;
- x = m;
- if(x < 0)
- {
- perror("read error p1\n");
- exit(1);
- }
- if(x > 0)
- {
- // Konwersja na HEX
- if(bufor1[0] < 16)
- {
- if(bufor1[0] == 10) // gdy enter
- {
- sprintf(wartosc_hex, "0x0%X\n", bufor1[0]);
- }
- else
- {
- sprintf(wartosc_hex, "0x0%X ", bufor1[0]);
- }
- }
- else
- {
- sprintf(wartosc_hex, "0x%X ", bufor1[0]);
- }
- // poczekaj az pamiec bedzie pusta (gotowa do zapisu)
- strcpy(&tab[1], wartosc_hex);
- memset(bufor1, 0, sizeof(bufor1)); // czyszczenie bufora
- memset(wartosc_hex, 0, sizeof(wartosc_hex)); // przygotowanie tablicy na zapis wartosci hex
- x = 0;
- }
- close(fifo_fd);
- }
- poprzedni_stan = 1;
- }
- sleep(1);
- }
- }
- if(pid2 == 0)
- {
- des_pid[R] = open("pid2", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p2 w p1");
- exit(1);
- }
- pid2 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- // zabijamy proces 2
- kill(pid2, 2);
- // zabijamy proces 0
- if(semctl(semafor, 0, SETVAL, 2) == -1)
- {
- perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
- exit(1);
- }
- }
- void proces2()
- {
- ssize_t q;
- int poprzedni_stan = 0;
- int pid1 = 0;
- close(file_des[0]); // zablokuj kanal do odczytu
- signal(SIGINT, sygnal_p2);
- signal(SIGHUP, sygnal_p2);
- signal(SIGCHLD, sygnal_p2);
- signal(SIGUSR1, sygnal_p2);
- signal(SIGUSR2, sygnal_p2);
- while((stan == 0) || (stan == 1))
- {
- while(stan == 0)
- {
- if(msgrcv(mqid, &msg, sizeof(msg.mtext), 2, IPC_NOWAIT) > 0) // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
- {
- if(stan != msg.mtext)
- {
- stan = msg.mtext;
- }
- }
- if(poprzedni_stan == 1)
- {
- if(sygnal_od_p1 != 1)
- {
- if(pid1 == 0)
- {
- des_pid[R] = open("pid1", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p1 w p2");
- exit(1);
- }
- pid1 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- // budzimy proces1
- kill(pid1, 10);
- //printf("\nproces 2 wyslal sygnal 10 do procesu 1 w linii 728\n");
- //fflush(stdin);
- }
- sygnal_od_p1 = 2;
- poprzedni_stan = 0;
- }
- if(strlen(&tab[1]) != 0)
- {
- if(write(file_des[1], &tab[1], strlen(&tab[1])) != strlen(&tab[1]))
- {
- perror("blad write w p2");
- exit(1);
- }
- // wyczysc pamiec dzielona by przyjac kolejny bajt
- memset(&tab[1], 0, strlen(&tab[1]));
- }
- }
- while(stan == 1)
- {
- if(msgrcv(mqid, &msg, sizeof(msg.mtext), 2, IPC_NOWAIT) > 0) // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
- {
- if(stan != msg.mtext)
- {
- stan = msg.mtext;
- }
- }
- if(poprzedni_stan == 0)
- {
- if(sygnal_od_p1 != 1)
- {
- if(pid1 == 0)
- {
- des_pid[R] = open("pid1", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p1 w p2");
- exit(1);
- }
- pid1 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- // wstrzymaj p1
- kill(pid1, 12);
- //printf("\nproces 2 wyslal sygnal 12 do procesu 1 w linii 783\n");
- //fflush(stdin);
- }
- sygnal_od_p1 = 2;
- if(strlen(&tab[1]) != 0)
- {
- if(write(file_des[1], &tab[1], strlen(&tab[1])) != strlen(&tab[1]))
- {
- perror("blad write w p2");
- exit(1);
- }
- // wyczysc pamiec dzielona by przyjac kolejny bajt
- memset(&tab[1], 0, strlen(&tab[1]));
- }
- poprzedni_stan = 1;
- }
- }
- }
- if(pid1 == 0)
- {
- des_pid[R] = open("pid1", O_RDONLY);
- memset(bufor_proces, 0, sizeof(bufor_proces));
- if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
- {
- perror("blad przy odczytywaniu pid p1 w p2");
- exit(1);
- }
- pid1 = atoi(&bufor_proces[14]);
- close(des_pid[R]);
- }
- // zabijamy proces 1
- kill(pid1, 2);
- }
- void proces3()
- {
- ssize_t n;
- int poprzedni_stan = 0;
- close(file_des[1]); // zablokuj kanal do zapisu
- signal(SIGINT, sygnal_p3);
- signal(SIGHUP, sygnal_p3);
- signal(SIGCHLD, sygnal_p3);
- while((stan == 0) || (stan == 1))
- {
- while(stan == 0)
- {
- if(msgrcv(mqid, &msg, sizeof(msg.mtext), 3, IPC_NOWAIT) > 0) // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
- {
- if(stan != msg.mtext)
- {
- stan = msg.mtext;
- }
- }
- if(poprzedni_stan == 1)
- {
- poprzedni_stan = 0;
- }
- if(tab[0] == 1)
- {
- if((n = read(file_des[0], bufor_pipe, sizeof(bufor_pipe))) > 0)
- {
- if(write(STDOUT_FILENO, bufor_pipe, n) != n)
- {
- perror("write error w proces3()");
- exit(1);
- }
- tab[0] = 0;
- memset(bufor_pipe, 0, sizeof(bufor_pipe));
- }
- }
- }
- while(stan == 1)
- {
- if(msgrcv(mqid, &msg, sizeof(msg.mtext), 3, IPC_NOWAIT) > 0) // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
- {
- if(stan != msg.mtext)
- {
- stan = msg.mtext;
- }
- }
- if(poprzedni_stan == 0)
- {
- if(tab[0] == 1)
- {
- if((n = read(file_des[0], bufor_pipe, sizeof(bufor_pipe))) > 0)
- {
- if(write(STDOUT_FILENO, bufor_pipe, n) != n)
- {
- perror("write error w proces3()");
- exit(1);
- }
- tab[0] = 0;
- memset(bufor_pipe, 0, sizeof(bufor_pipe));
- }
- }
- poprzedni_stan = 1;
- }
- }
- }
- }
- int main(void)
- {
- key = 5678;
- int status;
- // Tworzenie plikow przechowujacych ID procesow
- mknod("pid0", S_IFREG | 0777, 0);
- mknod("pid1", S_IFREG | 0777, 0);
- mknod("pid2", S_IFREG | 0777, 0);
- mknod("pid3", S_IFREG | 0777, 0);
- // Tworzenie kolejki komunikatow
- if((mqid = msgget(mqkey, IPC_CREAT | 0666)) < 0)
- {
- perror("blad tworzenia kolejki komunikatow");
- exit(1);
- }
- // Tworzenie semaforow
- key_t klucz;
- klucz = ftok(".", 'a'); // na podstawie pliku i pojedynczego znaku id wyznacza klucz semafora
- if(klucz == -1)
- {
- perror("blad wyznaczania klucza semafora");
- exit(1);
- }
- semafor = semget(klucz, 1, IPC_CREAT | 0777); // tworzy na podstawie klucza semafor. 1 - ilosc semaforow
- if(semafor == -1)
- {
- perror("blad przy tworzeniu semafora");
- exit(1);
- }
- if(semctl(semafor, 0, SETVAL, 0) == -1) // ustawia poczatkowa wartosc semafora (klucz, numer w zbiorze od 0, polecenie, argument 0/1/2)
- {
- perror("blad przy ustawianiu wartosci poczatkowej semafora");
- exit(1);
- }
- // Tworzenie lacza nazwanego FIFO
- if(access("/tmp/fifo", F_OK) == -1) // sprawdza czy plik istnieje, jesli nie - tworzy go
- {
- if(mkfifo("/tmp/fifo", 0777) != 0)
- {
- perror("blad tworzenia FIFO w main");
- exit(1);
- }
- }
- // Tworzenie pamieci dzielonej
- // Lista pamieci wspoldzielonych, komenda "ipcs"
- // usuwanie pamieci wspoldzielonej, komenta "ipcrm -m ID_PAMIECI"
- shmid = shmget(key, (BUFSIZE*30), 0666 | IPC_CREAT);
- if(shmid == -1)
- {
- perror("shmget");
- exit(1);
- }
- tab = (char *) shmat(shmid, NULL, 0);
- if(tab == (char *)(-1))
- {
- perror("shmat");
- exit(1);
- }
- memset(tab, 0, (BUFSIZE*30));
- tab[0] = 0;
- // Tworzenie lacza nienazwanego pipe
- if(pipe(file_des) == -1)
- {
- perror("pipe");
- exit(1);
- }
- // Tworzenie procesow potomnych
- if(!(p0 = fork()))
- {
- des_pid[W] = open("pid0", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt
- sprintf(bufor_proces, "Proces0 ma ID: %d\n", getpid());
- if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
- {
- perror("blad przy zapisie pid do pliku w p0");
- exit(1);
- }
- close(des_pid[W]);
- proces0();
- }
- else if(p0 == -1)
- {
- perror("blad przy p0 fork w main");
- exit(1);
- }
- else
- {
- if(!(p1 = fork()))
- {
- des_pid[W] = open("pid1", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt
- sprintf(bufor_proces, "Proces1 ma ID: %d\n", getpid());
- if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
- {
- perror("blad przy zapisie pid do pliku w p1");
- exit(1);
- }
- close(des_pid[W]);
- proces1();
- }
- else if(p1 == -1)
- {
- perror("blad przy p1 fork w main");
- exit(1);
- }
- else
- {
- if(!(p2 = fork()))
- {
- des_pid[W] = open("pid2", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt
- sprintf(bufor_proces, "Proces2 ma ID: %d\n", getpid());
- if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
- {
- perror("blad przy zapisie pid do pliku w p2");
- exit(1);
- }
- close(des_pid[W]);
- proces2();
- }
- else if(p2 == -1)
- {
- perror("blad przy p2 fork w main");
- exit(1);
- }
- else
- {
- if(!(p3 = fork()))
- {
- des_pid[W] = open("pid3", O_WRONLY | O_TRUNC | O_CREAT); // 1 - zapis, 0 - odczyt
- sprintf(bufor_proces, "Proces3 ma ID: %d\n", getpid());
- if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
- {
- perror("blad przy zapisie pid do pliku w p3");
- exit(1);
- }
- close(des_pid[W]);
- proces3();
- }
- else if(p3 == -1)
- {
- perror("blad przy p3 fork w main");
- exit(1);
- }
- else
- {
- // proces macierzysty
- waitpid(p0, &status, 0);
- printf("\np0 zakonczyl sie\n");
- waitpid(p1, &status, 0);
- printf("\np1 zakonczyl sie\n");
- waitpid(p2, &status, 0);
- printf("\np2 zakonczyl sie\n");
- waitpid(p3, &status, 0);
- printf("\np3 zakonczyl sie\n");
- //wait(NULL);
- // usuwanie kolejki komunikatow:
- if(msgctl(mqid,IPC_RMID,NULL) < 0)
- {
- perror("blad przy usuwaniu kolejki komunikatow");
- exit(1);
- }
- unlink("/tmp/fifo");
- shmdt(tab); // odlaczenie pamieci dzielonej
- shmctl(shmid, IPC_RMID, NULL); // usuwanie pamieci wspoldzielonej
- printf("\nKONIEC PROGRAMU\n");
- }
- }
- }
- }
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement