Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #include <string.h>
- #include <err.h>
- #include <sys/sem.h>
- #include <sys/shm.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- struct DataContainer
- {
- int end;
- unsigned char a;
- unsigned char b;
- int process1;
- int process2;
- int process3;
- };
- #define SHM_SIZE sizeof(struct DataContainer)
- union semun
- {
- int val;
- struct semid_ds *buf;
- unsigned short int *array;
- struct seminfo *__buf;
- };
- int semlock(int semid, int nr)
- {
- struct sembuf opr;
- opr.sem_num = nr;
- opr.sem_op = -1;
- opr.sem_flg = 0;
- int rc;
- while (semop(semid, &opr, 1) == -1)
- {
- if (errno != EINTR)
- {
- warn("Blad blokowania semafora!");
- break;
- }
- else
- {
- printf("Sygnal przerwal blokowanie semafora, ale blokujemy go jeszcze raz!\n");fflush(stdout);
- }
- }
- }
- int semunlock(int semid, int nr)
- {
- struct sembuf opr;
- opr.sem_num = nr;
- opr.sem_op = 1;
- opr.sem_flg = 0;
- while (semop(semid, &opr, 1) == -1)
- {
- if (errno != EINTR)
- {
- warn("Blad odblokowania semafora!");
- break;
- }
- else
- {
- printf("Sygnal przerwal odblokowywanie semafora, ale blokujemy go jeszcze raz!\n");fflush(stdout);
- }
- }
- }
- void usunSemafora(int semid)
- {
- if((semctl(semid,0,IPC_RMID,0))==-1)
- {
- warn("Blad usuwanie samefora!");
- }
- }
- void*przylaczSegment(key_t key)
- {
- int shmid;
- char *shm;
- if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0)
- errx(2, "Blad tworzenia segmentu pamieci dzielonej!");
- if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
- errx(3, "Blad przylaczania pamieci dzielonej!");
- return (void*)shm;
- }
- void usunSegment(key_t key)
- {
- int shmid;
- char *shm;
- if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0)
- errx(2, "Blad tworzenia segmentu pamieci dzielonej!");
- if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
- errx(3, "Blad przylaczania pamieci dzielonej!");
- shmdt(shm);
- shmctl(shmid, IPC_RMID, NULL);
- }
- pid_t process1;
- pid_t process2;
- pid_t process3;
- const int contsig = SIGUSR1;
- const int stopsig = SIGUSR2;
- const int killsig = SIGTRAP;
- void sendSig(int sig)
- {
- int thisprocessid = getpid();
- if(process1!=thisprocessid)kill(process1, sig);
- if(process2!=thisprocessid)kill(process2, sig);
- if(process3!=thisprocessid)kill(process3, sig);
- }
- void writeSigData(int sig)
- {
- printf("Proces %d otrzymal signal %s\n", getpid(), strsignal(sig));fflush(stdout);;
- }
- int isworking = 1;
- int ison = 1;
- void procSigHandler(int sig)
- {
- if(sig==killsig)
- {
- if(isworking!=0)
- {
- writeSigData(sig);
- kill(getppid(), killsig);
- ison=0;
- isworking=0;
- }
- }
- else if(sig == stopsig)
- {
- if(ison!=0)
- {
- writeSigData(sig);
- sendSig(sig);
- ison=0;
- }
- }
- else if(sig == contsig)
- {
- if(ison!=1)
- {
- writeSigData(sig);
- sendSig(sig);
- ison=1;
- }
- }
- }
- void getProcessIds(int semid, int datakey)
- {
- semlock(semid, 2);
- struct DataContainer*data = przylaczSegment(datakey);
- process1 = data->process1;
- process2 = data->process2;
- process3 = data->process3;
- }
- void procFunc1(int semid, int datakey, char*fifo, FILE*input)
- {
- int i;
- //dodawanie obslugi sygnalow
- signal(killsig, procSigHandler);
- signal(contsig, procSigHandler);
- signal(stopsig, procSigHandler);
- getProcessIds(semid, datakey);
- printf("Process1 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
- //END OF INITIALISATION
- int fifofile = open(fifo, O_WRONLY);
- while(isworking)
- {
- if(ison)
- {
- //process 1->2
- unsigned char tmp=0;
- int howmanyread = fread(&tmp, sizeof(tmp), 1, input);
- write(fifofile, &tmp, howmanyread);
- if(howmanyread != 1)
- {
- printf("\nProcess 1 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
- break;
- }
- }
- }
- close(fifofile);
- }
- void procFunc2(int semid, int datakey, char*fifo)
- {
- int i;
- //dodawanie obslugi sygnalow
- signal(killsig, procSigHandler);
- signal(contsig, procSigHandler);
- signal(stopsig, procSigHandler);
- getProcessIds(semid, datakey);
- printf("Process2 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
- //END OF INITIALISATION
- struct DataContainer*data = przylaczSegment(datakey);
- int fifofile = open(fifo, O_RDONLY);
- while(isworking)
- {
- if(ison)
- {
- unsigned char tmp = 0;
- //process 1->2
- int howmanyread = read(fifofile, &tmp ,sizeof(tmp));
- if(howmanyread == 0)
- {
- printf("\nProcess 2 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
- semlock(semid, 0);
- data->end = 1;
- semunlock(semid, 1);
- break;
- }
- //Conversion to hex
- unsigned char hex[3];
- sprintf(hex, "%02X", tmp);
- //process 2->3
- semlock(semid, 0);
- data->end = 0;
- data->a = hex[0];
- data->b = hex[1];
- semunlock(semid, 1);
- }
- }
- close(fifofile);
- }
- void procFunc3(int semid, int datakey, FILE*output)
- {
- int i,o;
- //dodawanie obslugi sygnalow
- signal(killsig, procSigHandler);
- signal(contsig, procSigHandler);
- signal(stopsig, procSigHandler);
- getProcessIds(semid, datakey);
- printf("Process3 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
- //END OF INITIALISATION
- struct DataContainer*data = przylaczSegment(datakey);
- i=0;
- while(isworking)
- {
- if(ison)
- {
- semlock(semid, 1);
- if(data->end==1)
- {
- printf("\nProcess 3 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
- kill(getppid(), killsig);
- break;
- }
- if(i==15)
- {
- i=0;
- fprintf(output, "\n");
- }
- fprintf(output, "%c ", data->a);fflush(stdout);
- i++;
- if(i==15)
- {
- i=0;
- fprintf(output, "\n");
- }
- fprintf(output, "%c ", data->b);fflush(stdout);
- i++;
- semunlock(semid, 0);
- }
- }
- }
- void mainSigHandler(int sig)
- {
- printf("Proces glowny otrzymal signal %s\n", strsignal(sig));fflush(stdout);
- if(sig==killsig)
- {
- if(ison!=0)
- {
- ison = 0;
- sendSig(sig);
- }
- }
- else if(sig == stopsig)
- {
- sendSig(sig);
- }
- else if(sig == contsig)
- {
- sendSig(sig);
- }
- }
- void setSemaforValue(int semid, int semnr, int value)
- {
- union semun ctl;
- ctl.val = value;
- if (semctl(semid, semnr, SETVAL, ctl) == -1)
- errx(3, "Blad ustawiania semafora!");
- }
- int main(int argc, char *argv[])
- {
- //Wybor trybu
- FILE*input = NULL;
- if(argc<2)
- {
- errx(6, "Zla podana ilosc argumentow!");
- }
- else
- {
- int first = atoi(argv[1]);
- if(first == 0) errx(7, "Arugment nie jest liczba!");
- else if(first == 1)//urandom
- {
- input = fopen("/dev/urandom", "rb");
- }
- else if(first == 2)//file
- {
- if(argc>=3)
- {
- input = fopen(argv[2], "rb");
- }
- else errx(8, "Nie podano nazwy pliku");
- }
- else if(first == 3)//stdin
- input = stdin;
- }
- if(input == NULL)
- errx(8, "Nie znaleziono pliku!");
- int i;
- //Tworzenie semaforow
- key_t key;
- int semid;
- union semun ctl;
- {
- if ((key = ftok(".", 'a')) == -1)
- errx(1, "Blad tworzenia klucza!");
- if ((semid = semget(key, 3, IPC_CREAT | 0666)) == -1)
- errx(2, "Blad tworzenia semafora!");
- setSemaforValue(semid, 0, 1);
- setSemaforValue(semid, 1, 0);
- setSemaforValue(semid, 2, 0);
- }
- //Tworzenie shmem
- int datakey;
- if ((datakey = ftok(".", 'E')) == -1)
- errx(1, "Blad tworzenia klucza!");
- przylaczSegment(datakey);
- //Tworzenie fifo
- char*fifo = "/tmp/myfifo";
- unlink(fifo);
- if(mkfifo(fifo, 0666) == -1)
- {
- warn("Blad tworzenia fifo!");
- return 0;
- }
- //Tworzenie procesow
- if((process1 = fork())==0)
- {
- procFunc1(semid, datakey, fifo, input);
- return 0;
- }
- if((process2 = fork())==0)
- {
- procFunc2(semid, datakey, fifo);
- return 0;
- }
- if((process3 = fork())==0)
- {
- procFunc3(semid, datakey, stderr);
- return 0;
- }
- //dodawanie obslugi sygnalow
- signal(contsig, mainSigHandler);
- signal(killsig, mainSigHandler);
- signal(stopsig, mainSigHandler);
- printf("Pid procesu glownego: %d\n", getpid());
- printf("Pid procesu 1: %d\n", process1);
- printf("Pid procesu 2: %d\n", process2);
- printf("Pid procesu 3: %d\n", process3);
- fflush(stdout);
- struct DataContainer*data = przylaczSegment(datakey);
- data->process1 = process1;
- data->process2 = process2;
- data->process3 = process3;
- printf("Wpisz cokolwiek, aby wystartowac!\n");fflush(stdout);
- scanf("%d", &i);
- //END OF INITIALISATION RELEASING PROCESSES
- printf("Poczatek dzialania programu\n");fflush(stdout);
- semunlock(semid, 2);
- semunlock(semid, 2);
- semunlock(semid, 2);
- while(ison)sleep(1);
- usunSemafora(semid);
- usunSegment(datakey);
- unlink(fifo);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement