Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.01 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. #include <stdlib.h>
  4.  
  5. #include <signal.h>
  6.  
  7. #include <unistd.h>
  8.  
  9. #include <string.h>
  10.  
  11. #include <err.h>
  12.  
  13. #include <sys/sem.h>
  14.  
  15. #include <sys/shm.h>
  16.  
  17. #include <errno.h>
  18.  
  19. #include <fcntl.h>
  20.  
  21. #include <sys/stat.h>
  22.  
  23. #include <sys/types.h>
  24.  
  25.  
  26.  
  27. struct DataContainer
  28.  
  29. {
  30.  
  31.     int end;
  32.  
  33.     unsigned char a;
  34.  
  35.     unsigned char b;
  36.  
  37.     int process1;
  38.  
  39.     int process2;
  40.  
  41.     int process3;
  42.  
  43. };
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53. #define SHM_SIZE sizeof(struct DataContainer)
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63. union semun
  64.  
  65. {
  66.  
  67.     int val;
  68.  
  69.     struct semid_ds *buf;
  70.  
  71.     unsigned short int *array;
  72.  
  73.     struct seminfo *__buf;
  74.  
  75. };
  76.  
  77.  
  78.  
  79. int semlock(int semid, int nr)
  80.  
  81. {
  82.  
  83.     struct sembuf opr;
  84.  
  85.     opr.sem_num =  nr;
  86.  
  87.     opr.sem_op  = -1;
  88.  
  89.     opr.sem_flg =  0;
  90.  
  91.  
  92.  
  93.     int rc;
  94.  
  95.  
  96.  
  97.     while (semop(semid, &opr, 1) == -1)
  98.  
  99.     {
  100.  
  101.       if (errno != EINTR)
  102.  
  103.       {
  104.  
  105.         warn("Blad blokowania semafora!");
  106.  
  107.         break;
  108.  
  109.       }
  110.  
  111.       else
  112.  
  113.       {
  114.  
  115.         printf("Sygnal przerwal blokowanie semafora, ale blokujemy go jeszcze raz!\n");fflush(stdout);
  116.  
  117.       }
  118.  
  119.     }
  120.  
  121. }
  122.  
  123.  
  124.  
  125. int semunlock(int semid, int nr)
  126.  
  127. {
  128.  
  129.     struct sembuf opr;
  130.  
  131.  
  132.  
  133.     opr.sem_num = nr;
  134.  
  135.     opr.sem_op  = 1;
  136.  
  137.     opr.sem_flg = 0;
  138.  
  139.  
  140.  
  141.     while (semop(semid, &opr, 1) == -1)
  142.  
  143.     {
  144.  
  145.       if (errno != EINTR)
  146.  
  147.       {
  148.  
  149.         warn("Blad odblokowania semafora!");
  150.  
  151.         break;
  152.  
  153.       }
  154.  
  155.       else
  156.  
  157.       {
  158.  
  159.         printf("Sygnal przerwal odblokowywanie semafora, ale blokujemy go jeszcze raz!\n");fflush(stdout);
  160.  
  161.       }
  162.  
  163.     }
  164.  
  165. }
  166.  
  167.  
  168.  
  169.  
  170.  
  171. void usunSemafora(int semid)
  172.  
  173. {
  174.  
  175.     if((semctl(semid,0,IPC_RMID,0))==-1)
  176.  
  177.     {
  178.  
  179.         warn("Blad usuwanie samefora!");
  180.  
  181.     }
  182.  
  183. }
  184.  
  185.  
  186.  
  187. void*przylaczSegment(key_t key)
  188.  
  189. {
  190.  
  191.     int shmid;
  192.  
  193.     char *shm;
  194.  
  195.     if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0)
  196.  
  197.         errx(2, "Blad tworzenia segmentu pamieci dzielonej!");
  198.  
  199.     if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
  200.  
  201.         errx(3, "Blad przylaczania pamieci dzielonej!");
  202.  
  203.     return (void*)shm;
  204.  
  205. }
  206.  
  207.  
  208.  
  209. void usunSegment(key_t key)
  210.  
  211. {
  212.  
  213.     int shmid;
  214.  
  215.     char *shm;
  216.  
  217.     if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0)
  218.  
  219.         errx(2, "Blad tworzenia segmentu pamieci dzielonej!");
  220.  
  221.     if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
  222.  
  223.         errx(3, "Blad przylaczania pamieci dzielonej!");
  224.  
  225.     shmdt(shm);
  226.  
  227.     shmctl(shmid, IPC_RMID, NULL);
  228.  
  229. }
  230.  
  231.  
  232.  
  233. pid_t process1;
  234.  
  235. pid_t process2;
  236.  
  237. pid_t process3;
  238.  
  239.  
  240.  
  241. const int contsig = SIGUSR1;
  242.  
  243. const int stopsig = SIGUSR2;
  244.  
  245. const int killsig = SIGTRAP;
  246.  
  247.  
  248.  
  249. void sendSig(int sig)
  250.  
  251. {
  252.  
  253.     int thisprocessid = getpid();
  254.  
  255.     if(process1!=thisprocessid)kill(process1, sig);
  256.  
  257.     if(process2!=thisprocessid)kill(process2, sig);
  258.  
  259.     if(process3!=thisprocessid)kill(process3, sig);
  260.  
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267. void writeSigData(int sig)
  268.  
  269. {
  270.  
  271.     printf("Proces %d otrzymal signal %s\n", getpid(), strsignal(sig));fflush(stdout);;
  272.  
  273. }
  274.  
  275.  
  276.  
  277. int isworking = 1;
  278.  
  279. int ison = 1;
  280.  
  281. void procSigHandler(int sig)
  282.  
  283. {
  284.  
  285.     if(sig==killsig)
  286.  
  287.     {
  288.  
  289.     if(isworking!=0)
  290.  
  291.     {
  292.  
  293.         writeSigData(sig);
  294.  
  295.         kill(getppid(), killsig);
  296.  
  297.         ison=0;
  298.  
  299.         isworking=0;
  300.  
  301.     }
  302.  
  303.     }
  304.  
  305.     else if(sig == stopsig)
  306.  
  307.     {
  308.  
  309.         if(ison!=0)
  310.  
  311.         {
  312.  
  313.             writeSigData(sig);
  314.  
  315.             sendSig(sig);
  316.  
  317.             ison=0;
  318.  
  319.         }
  320.  
  321.     }
  322.  
  323.     else if(sig == contsig)
  324.  
  325.     {
  326.  
  327.         if(ison!=1)
  328.  
  329.         {
  330.  
  331.             writeSigData(sig);
  332.  
  333.             sendSig(sig);
  334.  
  335.             ison=1;
  336.  
  337.         }
  338.  
  339.     }
  340.  
  341.  
  342.  
  343. }
  344.  
  345.  
  346.  
  347.  
  348.  
  349. void getProcessIds(int semid, int datakey)
  350.  
  351. {
  352.  
  353.     semlock(semid, 2);
  354.  
  355.     struct DataContainer*data = przylaczSegment(datakey);
  356.  
  357.     process1 = data->process1;
  358.  
  359.     process2 = data->process2;
  360.  
  361.     process3 = data->process3;
  362.  
  363. }
  364.  
  365.  
  366.  
  367. void procFunc1(int semid, int datakey, char*fifo, FILE*input)
  368.  
  369. {
  370.  
  371.     int i;
  372.  
  373.     //dodawanie obslugi sygnalow
  374.  
  375.     signal(killsig, procSigHandler);
  376.  
  377.     signal(contsig, procSigHandler);
  378.  
  379.     signal(stopsig, procSigHandler);
  380.  
  381.  
  382.  
  383.     getProcessIds(semid, datakey);
  384.  
  385.     printf("Process1 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
  386.  
  387.     //END OF INITIALISATION
  388.  
  389.  
  390.  
  391.     int fifofile = open(fifo, O_WRONLY);
  392.  
  393.     while(isworking)
  394.  
  395.     {
  396.  
  397.         if(ison)
  398.  
  399.         {
  400.  
  401.             //process 1->2
  402.  
  403.             unsigned char tmp=0;
  404.  
  405.             int howmanyread = fread(&tmp, sizeof(tmp), 1, input);
  406.  
  407.             write(fifofile, &tmp, howmanyread);
  408.  
  409.             if(howmanyread != 1)
  410.  
  411.             {
  412.  
  413.                 printf("\nProcess 1 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
  414.  
  415.                 break;
  416.  
  417.             }
  418.  
  419.         }
  420.  
  421.     }
  422.  
  423.     close(fifofile);
  424.  
  425. }
  426.  
  427.  
  428.  
  429. void procFunc2(int semid, int datakey, char*fifo)
  430.  
  431. {
  432.  
  433.     int i;
  434.  
  435.     //dodawanie obslugi sygnalow
  436.  
  437.     signal(killsig, procSigHandler);
  438.  
  439.     signal(contsig, procSigHandler);
  440.  
  441.     signal(stopsig, procSigHandler);
  442.  
  443.  
  444.  
  445.     getProcessIds(semid, datakey);
  446.  
  447.     printf("Process2 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
  448.  
  449.     //END OF INITIALISATION
  450.  
  451.  
  452.  
  453.     struct DataContainer*data = przylaczSegment(datakey);
  454.  
  455.  
  456.  
  457.     int fifofile = open(fifo, O_RDONLY);
  458.  
  459.     while(isworking)
  460.  
  461.     {
  462.  
  463.         if(ison)
  464.  
  465.         {
  466.  
  467.             unsigned char tmp = 0;
  468.  
  469.  
  470.  
  471.             //process 1->2
  472.  
  473.             int howmanyread = read(fifofile, &tmp ,sizeof(tmp));
  474.  
  475.             if(howmanyread == 0)
  476.  
  477.             {
  478.  
  479.                 printf("\nProcess 2 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
  480.  
  481.                 semlock(semid, 0);
  482.  
  483.                 data->end = 1;
  484.  
  485.                 semunlock(semid, 1);
  486.  
  487.                 break;
  488.  
  489.             }
  490.  
  491.  
  492.  
  493.             //Conversion to hex
  494.  
  495.             unsigned char hex[3];
  496.  
  497.             sprintf(hex, "%02X", tmp);
  498.  
  499.  
  500.  
  501.  
  502.  
  503.             //process 2->3
  504.  
  505.             semlock(semid, 0);
  506.  
  507.             data->end = 0;
  508.  
  509.             data->a = hex[0];
  510.  
  511.             data->b = hex[1];
  512.  
  513.             semunlock(semid, 1);
  514.  
  515.         }
  516.  
  517.     }
  518.  
  519.  
  520.  
  521.     close(fifofile);
  522.  
  523. }
  524.  
  525.  
  526.  
  527. void procFunc3(int semid, int datakey, FILE*output)
  528.  
  529. {
  530.  
  531.     int i,o;
  532.  
  533.     //dodawanie obslugi sygnalow
  534.  
  535.     signal(killsig, procSigHandler);
  536.  
  537.     signal(contsig, procSigHandler);
  538.  
  539.     signal(stopsig, procSigHandler);
  540.  
  541.  
  542.  
  543.     getProcessIds(semid, datakey);
  544.  
  545.     printf("Process3 mowi czesc p1:%d p2:%d p3:%d\n", process1, process2, process3);fflush(stdout);
  546.  
  547.     //END OF INITIALISATION
  548.  
  549.  
  550.  
  551.     struct DataContainer*data = przylaczSegment(datakey);
  552.  
  553.  
  554.  
  555.     i=0;
  556.  
  557.     while(isworking)
  558.  
  559.     {
  560.  
  561.         if(ison)
  562.  
  563.         {
  564.  
  565.             semlock(semid, 1);
  566.  
  567.             if(data->end==1)
  568.  
  569.             {
  570.  
  571.                 printf("\nProcess 3 realised that the file has ended and starts the exit sequence!\n");fflush(stdout);
  572.  
  573.         kill(getppid(), killsig);
  574.  
  575.                 break;
  576.  
  577.             }
  578.  
  579.         if(i==15)
  580.  
  581.         {
  582.  
  583.             i=0;
  584.  
  585.             fprintf(output, "\n");
  586.  
  587.         }
  588.  
  589.         fprintf(output, "%c ", data->a);fflush(stdout);
  590.  
  591.         i++;
  592.  
  593.         if(i==15)
  594.  
  595.         {
  596.  
  597.         i=0;
  598.  
  599.         fprintf(output, "\n");
  600.  
  601.         }
  602.  
  603.         fprintf(output, "%c ", data->b);fflush(stdout);
  604.  
  605.         i++;
  606.  
  607.         semunlock(semid, 0);
  608.  
  609.     }
  610.  
  611.     }
  612.  
  613. }
  614.  
  615.  
  616.  
  617. void mainSigHandler(int sig)
  618.  
  619. {
  620.  
  621.     printf("Proces glowny otrzymal signal %s\n", strsignal(sig));fflush(stdout);
  622.  
  623.  
  624.  
  625.     if(sig==killsig)
  626.  
  627.     {
  628.  
  629.         if(ison!=0)
  630.  
  631.         {
  632.  
  633.             ison = 0;
  634.  
  635.             sendSig(sig);
  636.  
  637.         }
  638.  
  639.     }
  640.  
  641.     else if(sig == stopsig)
  642.  
  643.     {
  644.  
  645.         sendSig(sig);
  646.  
  647.     }
  648.  
  649.     else if(sig == contsig)
  650.  
  651.     {
  652.  
  653.         sendSig(sig);
  654.  
  655.     }
  656.  
  657. }
  658.  
  659.  
  660.  
  661.  
  662.  
  663. void setSemaforValue(int semid, int semnr, int value)
  664.  
  665. {
  666.  
  667.     union semun ctl;
  668.  
  669.     ctl.val = value;
  670.  
  671.     if (semctl(semid, semnr, SETVAL, ctl) == -1)
  672.  
  673.         errx(3, "Blad ustawiania semafora!");
  674.  
  675. }
  676.  
  677.  
  678.  
  679.  
  680.  
  681. int main(int argc, char *argv[])
  682.  
  683. {
  684.  
  685.     //Wybor trybu
  686.  
  687.     FILE*input = NULL;
  688.  
  689.  
  690.  
  691.     if(argc<2)
  692.  
  693.     {
  694.  
  695.          errx(6, "Zla podana ilosc argumentow!");
  696.  
  697.     }
  698.  
  699.     else
  700.  
  701.     {
  702.  
  703.         int first = atoi(argv[1]);
  704.  
  705.         if(first == 0) errx(7, "Arugment nie jest liczba!");
  706.  
  707.         else if(first == 1)//urandom
  708.  
  709.         {
  710.  
  711.             input = fopen("/dev/urandom", "rb");
  712.  
  713.         }
  714.  
  715.         else if(first == 2)//file
  716.  
  717.         {
  718.  
  719.             if(argc>=3)
  720.  
  721.             {
  722.  
  723.                 input = fopen(argv[2], "rb");
  724.  
  725.             }
  726.  
  727.             else errx(8, "Nie podano nazwy pliku");
  728.  
  729.         }
  730.  
  731.         else if(first == 3)//stdin
  732.  
  733.             input = stdin;
  734.  
  735.     }
  736.  
  737.  
  738.  
  739.     if(input == NULL)
  740.  
  741.         errx(8, "Nie znaleziono pliku!");
  742.  
  743.  
  744.  
  745.     int i;
  746.  
  747.  
  748.  
  749.     //Tworzenie semaforow
  750.  
  751.  
  752.  
  753.     key_t key;
  754.  
  755.     int   semid;
  756.  
  757.     union semun ctl;
  758.  
  759.  
  760.  
  761.     {
  762.  
  763.         if ((key = ftok(".", 'a')) == -1)
  764.  
  765.             errx(1, "Blad tworzenia klucza!");
  766.  
  767.  
  768.  
  769.         if ((semid = semget(key, 3, IPC_CREAT | 0666)) == -1)
  770.  
  771.             errx(2, "Blad tworzenia semafora!");
  772.  
  773.         setSemaforValue(semid, 0, 1);
  774.  
  775.         setSemaforValue(semid, 1, 0);
  776.  
  777.         setSemaforValue(semid, 2, 0);
  778.  
  779.     }
  780.  
  781.  
  782.  
  783.     //Tworzenie shmem
  784.  
  785.     int datakey;
  786.  
  787.     if ((datakey = ftok(".", 'E')) == -1)
  788.  
  789.         errx(1, "Blad tworzenia klucza!");
  790.  
  791.     przylaczSegment(datakey);
  792.  
  793.  
  794.  
  795.  
  796.  
  797.     //Tworzenie fifo
  798.  
  799.     char*fifo = "/tmp/myfifo";
  800.  
  801.     unlink(fifo);
  802.  
  803.     if(mkfifo(fifo, 0666) == -1)
  804.  
  805.     {
  806.  
  807.          warn("Blad tworzenia fifo!");
  808.  
  809.          return 0;
  810.  
  811.     }
  812.  
  813.  
  814.  
  815.     //Tworzenie procesow
  816.  
  817.     if((process1 = fork())==0)
  818.  
  819.     {
  820.  
  821.         procFunc1(semid, datakey, fifo, input);
  822.  
  823.         return 0;
  824.  
  825.     }
  826.  
  827.  
  828.  
  829.     if((process2 = fork())==0)
  830.  
  831.     {
  832.  
  833.         procFunc2(semid, datakey, fifo);
  834.  
  835.         return 0;
  836.  
  837.     }
  838.  
  839.  
  840.  
  841.     if((process3 = fork())==0)
  842.  
  843.     {
  844.  
  845.         procFunc3(semid, datakey, stderr);
  846.  
  847.         return 0;
  848.  
  849.     }
  850.  
  851.  
  852.  
  853.     //dodawanie obslugi sygnalow
  854.  
  855.     signal(contsig, mainSigHandler);
  856.  
  857.     signal(killsig, mainSigHandler);
  858.  
  859.     signal(stopsig, mainSigHandler);
  860.  
  861.  
  862.  
  863.  
  864.  
  865.     printf("Pid procesu glownego: %d\n", getpid());
  866.  
  867.     printf("Pid procesu 1: %d\n", process1);
  868.  
  869.     printf("Pid procesu 2: %d\n", process2);
  870.  
  871.     printf("Pid procesu 3: %d\n", process3);
  872.  
  873.     fflush(stdout);
  874.  
  875.  
  876.  
  877.     struct DataContainer*data = przylaczSegment(datakey);
  878.  
  879.     data->process1 = process1;
  880.  
  881.     data->process2 = process2;
  882.  
  883.     data->process3 = process3;
  884.  
  885.  
  886.  
  887.     printf("Wpisz cokolwiek, aby wystartowac!\n");fflush(stdout);
  888.  
  889.     scanf("%d", &i);
  890.  
  891.  
  892.  
  893.     //END OF INITIALISATION RELEASING PROCESSES
  894.  
  895.     printf("Poczatek dzialania programu\n");fflush(stdout);
  896.  
  897.  
  898.  
  899.     semunlock(semid, 2);
  900.  
  901.     semunlock(semid, 2);
  902.  
  903.     semunlock(semid, 2);
  904.  
  905.  
  906.  
  907.     while(ison)sleep(1);
  908.  
  909.  
  910.  
  911.     usunSemafora(semid);
  912.  
  913.     usunSegment(datakey);
  914.  
  915.     unlink(fifo);
  916.  
  917.  
  918.  
  919.     return 0;
  920.  
  921. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement