Advertisement
Guest User

Multiprocess application to translate from char to hex

a guest
Sep 17th, 2012
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.47 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <sys/shm.h>
  7. #include <sys/sem.h>
  8. #include <sys/types.h>
  9. #include <sys/wait.h>
  10. #include <sys/stat.h>
  11. #include <string.h>
  12. #include <signal.h>
  13. #include <sys/msg.h>
  14.  
  15. #define BUFSIZE 1
  16. #define R 0
  17. #define W 1
  18.  
  19. // Struktura komunikatu
  20.  
  21. struct msgbuf
  22. {
  23.     long mtype;
  24.     int mtext;
  25. } msg;
  26.  
  27. // Struktura semafora
  28. #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
  29. #else
  30. union semun
  31. {
  32.         int val;                            //value for SETVAL
  33.         struct semid_ds *buf;               //buffer for IPC_STAT, IPC_SET
  34.         unsigned short int *array;          //array for GETALL, SETALL
  35.         struct seminfo *__buf;              //buffer for IPC_INFO
  36. };
  37. #endif
  38.  
  39. // zmienne do plikow z pidami procesow:
  40. int des_pid[2] = {};
  41. char bufor_proces[50] = {};
  42.  
  43. // zmienne do kolejki komunikatow:
  44. int mqid;
  45. key_t mqkey = 1234;
  46.  
  47. // Semaphore
  48. int semafor;
  49. int stan = 0;           // 0 - pracuje, 1 - zatrzymany, 2 - koniec
  50. int sygnal_od_p1 = 2;   // 0 - kill from user, 1 - kill from p1, 2 - another source of changes
  51. int sygnal_od_p2 = 2;   // 0 - kill from user, 1 - kill from p1, 2 - another source of changes
  52.  
  53. // PIDs:
  54. pid_t p0, p1, p2, p3;
  55.  
  56. // FIFO
  57. int fifo_fd;
  58. unsigned char bufor[BUFSIZE] = {};
  59. unsigned char bufor1[BUFSIZE] = {};
  60.  
  61. // Shared memory:
  62. key_t key;
  63. int shmid;
  64. char * tab;
  65.  
  66. // pipes
  67. int file_des[2];        // file_des[0] - deskryptor do czytania, file_des[1] - deskryptor do pisania
  68. char bufor_pipe[BUFSIZE*30] = {};
  69.  
  70. // signal handlers:
  71. // 1 = SIGHUP   -> stan = 1 -> HOLD
  72. // 2 = SIGINT   -> stan = 2 -> STOP
  73. // 17 = SIGCHLD -> stan = 0 -> WORK
  74.  
  75. void sygnal_p0(int sig)
  76. {
  77.     printf("***proces p0 odebral sygnal %d\n", sig);
  78.     fflush(stdin);
  79.     if(sig == 1)
  80.     {
  81.         if(semctl(semafor, 0, SETVAL, 1) == -1)                        
  82.         {
  83.             perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 1");
  84.             exit(1);
  85.         }
  86.         stan = 1;
  87.     }
  88.     else if(sig == 2)
  89.     {
  90.         if(semctl(semafor, 0, SETVAL, 2) == -1)                        
  91.         {
  92.             perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 2");
  93.             exit(1);
  94.         }
  95.         stan = 2;
  96.     }
  97.     else if(sig == 17)
  98.     {
  99.         if(semctl(semafor, 0, SETVAL, 0) == -1)                        
  100.         {
  101.             perror("blad przy zmianie wartosci semafora przez sygnal_p0 na 0");
  102.             exit(1);
  103.         }
  104.         stan = 0;
  105.     }
  106. }
  107.  
  108. void sygnal_p1(int sig)
  109. {
  110.     printf("***proces p1 odebral sygnal %d\n", sig);
  111.     fflush(stdin);
  112.    
  113.     if(sig == 1)
  114.     {
  115.         if(semctl(semafor, 0, SETVAL, 1) == -1)                        
  116.         {
  117.             perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
  118.             exit(1);
  119.         }
  120.         sygnal_od_p2 = 0;
  121.         stan = 1;
  122.     }
  123.     else if(sig == 2)
  124.     {
  125.         if(semctl(semafor, 0, SETVAL, 2) == -1)                        
  126.         {
  127.             perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 2");
  128.             exit(1);
  129.         }
  130.         sygnal_od_p2 = 0;
  131.         stan = 2;
  132.     }
  133.     else if(sig == 17)
  134.     {
  135.         if(semctl(semafor, 0, SETVAL, 0) == -1)                        
  136.         {
  137.             perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 0");
  138.             exit(1);
  139.         }
  140.         sygnal_od_p2 = 0;
  141.         stan = 0;
  142.     }
  143.     else if(sig == 10)  // WORK signal from p2
  144.     {
  145.         if(semctl(semafor, 0, SETVAL, 0) == -1)                        
  146.         {
  147.             perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 0");
  148.             exit(1);
  149.         }
  150.         sygnal_od_p2 = 1;
  151.         stan = 0;
  152.     }
  153.     else if(sig == 12)  // HOLD signal from p2
  154.     {
  155.         if(semctl(semafor, 0, SETVAL, 1) == -1)                        
  156.         {
  157.             perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
  158.             exit(1);
  159.         }
  160.         sygnal_od_p2 = 1;
  161.         stan = 1;
  162.     }
  163. }
  164.  
  165. void sygnal_p2(int sig)
  166. {  
  167.     printf("***proces p2 odebral sygnal %d\n", sig);
  168.     fflush(stdin);
  169.                
  170.     if(sig == 1)
  171.     {
  172.         // zatrzymaj p3
  173.         msg.mtype = 3;
  174.         msg.mtext = 1;
  175.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  176.         {
  177.             perror("blad wysylania komunikatu \"1\" z p2");
  178.             exit(1);
  179.         }
  180.                
  181.         sygnal_od_p1 = 0;
  182.         // zatrzymaj sie
  183.         stan = 1;
  184.        
  185.     }
  186.     else if(sig == 2)
  187.     {      
  188.         msg.mtype = 3;
  189.         msg.mtext = 2;
  190.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  191.         {
  192.             perror("blad wysylania komunikatu \"2\" z p2");
  193.             exit(1);
  194.         }
  195.         sygnal_od_p1 = 0;
  196.         stan = 2;
  197.     }
  198.     else if(sig == 17)
  199.     {      
  200.         msg.mtype = 3;
  201.         msg.mtext = 0;
  202.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  203.         {
  204.             perror("blad wysylania komunikatu \"0\" z p2");
  205.             exit(1);
  206.         }
  207.        
  208.         sygnal_od_p1 = 0;
  209.         stan = 0;
  210.     }
  211.     else if(sig == 10)  // WORK signal from p1
  212.     {
  213.         msg.mtype = 3;
  214.         msg.mtext = 0;
  215.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  216.         {
  217.             perror("blad wysylania komunikatu \"0\" z p2");
  218.             exit(1);
  219.         }
  220.  
  221.            
  222.        
  223.         sygnal_od_p1 = 1;
  224.         stan = 0;
  225.     }
  226.     else if(sig == 12)  // HOLD signal from p2
  227.     {
  228.         // zatrzymaj p3
  229.         msg.mtype = 3;
  230.         msg.mtext = 1;
  231.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  232.         {
  233.             perror("blad wysylania komunikatu \"1\" z p2");
  234.             exit(1);
  235.         }
  236.  
  237.        
  238.        
  239.         sygnal_od_p1 = 1;
  240.         stan = 1;
  241.     }
  242. }
  243.  
  244. void sygnal_p3(int sig)
  245. {
  246.     printf("***proces p3 odebral sygnal %d\n", sig);
  247.     fflush(stdin);
  248.    
  249.     if(sig == 1)
  250.     {
  251.         msg.mtype = 2;
  252.         msg.mtext = 1;
  253.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  254.         {
  255.             perror("blad wysylania komunikatu \"1\" z p3");
  256.             exit(1);
  257.         }
  258.  
  259.         stan = 1;  
  260.     }
  261.     else if(sig == 2)
  262.     {
  263.         msg.mtype = 2;
  264.         msg.mtext = 2;
  265.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  266.         {
  267.             perror("blad wysylania komunikatu \"2\" z p3");
  268.             exit(1);
  269.         }
  270.  
  271.         stan = 2;
  272.     }
  273.     else if(sig == 17)
  274.     {
  275.         msg.mtype = 2;
  276.         msg.mtext = 0;
  277.         if(msgsnd(mqid, &msg, sizeof(msg.mtext), 0) < 0)
  278.         {
  279.             perror("blad wysylania komunikatu \"0\" z p3");
  280.             exit(1);
  281.         }
  282.  
  283.         stan = 0;
  284.     }
  285. }
  286.  
  287. // ciala procesow:
  288.  
  289. void proces0()
  290. {
  291.     ssize_t n;
  292.    
  293.     int poprzedni_stan = 0;
  294.    
  295.     signal(SIGINT, sygnal_p0);
  296.     signal(SIGHUP, sygnal_p0);
  297.     signal(SIGCHLD, sygnal_p0);
  298.    
  299.     while(stan == 0 || stan == 1)
  300.     {  
  301.         while(stan == 0)
  302.         {
  303.             //printf("proces p0 dziala w petli while stan == 0\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan);
  304.             //fflush(stdin);
  305.            
  306.             if(semctl(semafor, 0, GETVAL) != stan)
  307.             {
  308.                 stan = semctl(semafor, 0, GETVAL);
  309.                 //printf("proces 0 zmienil swoj stan z 0 na : %d\n", stan);
  310.                 //fflush(stdin);
  311.             }
  312.            
  313.             if(poprzedni_stan == 1)                     // proces0 byl uspiony i zauwazyl ze semafor zmienil sie na 0 czyli musi sie wznowic
  314.             {
  315.                 poprzedni_stan = 0;                     // daj znac ze proces0 sie obudzil
  316.             }
  317.            
  318.             if(tab[0] == 0)
  319.             {  
  320.                 fifo_fd = open("/tmp/fifo", O_WRONLY);                      // otwiera kolejke fifo do zapisu
  321.  
  322.                 if(fifo_fd == -1)
  323.                 {
  324.                     perror("blad przy otwieraniu kolejki FIFO w p0\n");
  325.                     exit(1);
  326.                 }
  327.  
  328.                 n = read(STDIN_FILENO, bufor, BUFSIZE);    
  329.            
  330.                 if(n<0)
  331.                 {
  332.                     perror("read error w p0\n");
  333.                     exit(1);
  334.                 }
  335.        
  336.                 if(n > 0)
  337.                 {
  338.                     if(write(fifo_fd, bufor, n) != n)
  339.                     {
  340.                         perror("blad zapisu do kolejki fifo w p0\n");
  341.                         exit(1);
  342.                     }      
  343.                     tab[0] = 1;
  344.                     memset(bufor, 0, sizeof(bufor));                                    // czyszczenie bufora      
  345.                 }
  346.                
  347.                 close(fifo_fd);
  348.             }
  349.             //sleep(1);
  350.         }
  351.        
  352.         while(stan == 1)
  353.         {
  354.             //printf("proces p0 dziala w petli while stan == 1\nstan = %d\nsemafor = %d\npoprzedni_stan = %d\n", stan, semctl(semafor, 0, GETVAL), poprzedni_stan);
  355.             //fflush(stdin);
  356.            
  357.             if(semctl(semafor, 0, GETVAL) != stan)
  358.             {
  359.                 stan = semctl(semafor, 0, GETVAL);
  360.                 printf("proces 0 zmienil swoj stan na : %d\n", stan);
  361.                 fflush(stdin);
  362.             }
  363.            
  364.             if(poprzedni_stan == 0)         // proces0 dzialal i zauwazyl, ze semafor zmienil sie na 1 (trzeba sie zatrzymac)
  365.             {
  366.                 // wykonaj aktualne akcje do konca:
  367.                 if(tab[0] == 0)
  368.                 {  
  369.                     fifo_fd = open("/tmp/fifo", O_WRONLY);                      // otwiera kolejke fifo do zapisu
  370.  
  371.                     if(fifo_fd == -1)
  372.                     {
  373.                         perror("blad przy otwieraniu kolejki FIFO w p0\n");
  374.                         exit(1);
  375.                     }
  376.  
  377.                     n = read(STDIN_FILENO, bufor, BUFSIZE);    
  378.            
  379.                     if(n<0)
  380.                     {
  381.                         perror("read error w p0\n");
  382.                         exit(1);
  383.                     }
  384.        
  385.                     if(n > 0)
  386.                     {
  387.                         if(write(fifo_fd, bufor, n) != n)
  388.                         {
  389.                             perror("blad zapisu do kolejki fifo w p0\n");
  390.                             exit(1);
  391.                         }      
  392.                         tab[0] = 1;
  393.                         memset(bufor, 0, sizeof(bufor));                                    // czyszczenie bufora      
  394.                     }
  395.                
  396.                     close(fifo_fd);
  397.                 }
  398.                
  399.                 poprzedni_stan = 1;        
  400.             }
  401.             //sleep(1);
  402.         }
  403.     }
  404. }
  405.  
  406. void proces1()
  407. {
  408.     ssize_t m, x, q;
  409.     char wartosc_hex[30] = {};
  410.     int poprzedni_stan = 0;
  411.     int pid2 = 0;
  412.    
  413.     signal(SIGINT, sygnal_p1);
  414.     signal(SIGHUP, sygnal_p1);
  415.     signal(SIGCHLD, sygnal_p1);
  416.     signal(SIGUSR1, sygnal_p1);
  417.     signal(SIGUSR2, sygnal_p1);
  418.    
  419.     while( (stan == 0) || (stan == 1) )
  420.     {
  421.         while(stan == 0)
  422.         {
  423.             //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);
  424.             //fflush(stdin);
  425.            
  426.             if(semctl(semafor, 0, GETVAL) != 0)                                                         // gdy semafor zostal zmieniony przez p0
  427.             {
  428.                 //printf("proces p1 bedac w petli stan == 1 zauwazyl ze semafor ma wartosc %d\n", semctl(semafor, 0, GETVAL));
  429.                 //fflush(stdin);
  430.                
  431.                 if(semctl(semafor, 0, GETVAL) == 1)                                                         // p0 zmienil semafor na 1 - rozpoczyna sie zatrzymywanie wszystkich procesow
  432.                 {
  433.                     stan = 1;
  434.                     //printf("proces 1 zmienil swoj stan na : %d\n", stan);
  435.                     //fflush(stdin);
  436.                     if(poprzedni_stan == 0)                                                                 // sprawdzamy czy proces na pewno byl w ruchu, jesli nie to juz jest zatrzymany i nie trzeba nic robic
  437.                     {
  438.                         if(pid2 == 0)
  439.                         {
  440.                             des_pid[R] = open("pid2", O_RDONLY);
  441.                             memset(bufor_proces, 0, sizeof(bufor_proces));
  442.                             if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  443.                             {
  444.                                 perror("blad przy odczytywaniu pid p2 w p1");
  445.                                 exit(1);
  446.                             }
  447.                             pid2 = atoi(&bufor_proces[14]);
  448.                             close(des_pid[R]);
  449.                         }
  450.                         kill(pid2, 12);                                                                     // zatrzymujemy proces 2
  451.                         //printf("\nproces 1 wyslal sygnal 12 do procesu 2 w linii 449\n");
  452.                         //fflush(stdin);
  453.                     }
  454.                     sygnal_od_p2 = 2;                                                                       // dajemy znac ze zrodlem zmiany stanu jest proces0
  455.                 }
  456.                 else
  457.                 {
  458.                     stan = 2;
  459.                 }
  460.             }
  461.            
  462.             if(poprzedni_stan == 1)
  463.             {
  464.                 if(sygnal_od_p2 == 0)
  465.                 {
  466.                     if(pid2 == 0)
  467.                     {
  468.                         des_pid[R] = open("pid2", O_RDONLY);
  469.                         memset(bufor_proces, 0, sizeof(bufor_proces));
  470.                         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  471.                         {
  472.                             perror("blad przy odczytywaniu pid p2 w p1");
  473.                             exit(1);
  474.                         }
  475.                         pid2 = atoi(&bufor_proces[14]);
  476.                         //printf("proces1 odczytal PID procesu 2 w linii 439, czyli: %d\n", pid2);
  477.                         //fflush(stdin);
  478.                         close(des_pid[R]);
  479.                     }
  480.                     // budzimy proces2
  481.                     kill(pid2, 10);
  482.                     //printf("\nproces 1 wyslal sygnal 10 do procesu 2 w linii 482\n");
  483.                     //fflush(stdin);
  484.                 }
  485.                 poprzedni_stan = 0;
  486.             }
  487.            
  488.             if(strlen(&tab[1]) == 0)
  489.             {      
  490.                 fifo_fd = open("/tmp/fifo", O_RDONLY);                      // otwiera plik typu fifo do odczytu
  491.        
  492.                 if(fifo_fd == -1)
  493.                 {
  494.                     perror("blad przy otwieraniu kolejki FIFO w p1\n");
  495.                     exit(1);
  496.                 }
  497.        
  498.                 m = read(fifo_fd, bufor1, BUFSIZE);
  499.                 x = m;
  500.  
  501.                 if(x < 0)
  502.                 {
  503.                     perror("read error p1\n");
  504.                     exit(1);
  505.                 }
  506.            
  507.                 if(x > 0)
  508.                 {      
  509.                     // Konwersja na HEX
  510.  
  511.                     if(bufor1[0] < 16)
  512.                     {
  513.                         if(bufor1[0] == 10)     // gdy enter
  514.                         {
  515.                             sprintf(wartosc_hex, "0x0%X\n", bufor1[0]);
  516.                         }
  517.                         else
  518.                         {
  519.                             sprintf(wartosc_hex, "0x0%X ", bufor1[0]);
  520.                         }
  521.                     }
  522.                     else
  523.                     {
  524.                         sprintf(wartosc_hex, "0x%X ", bufor1[0]);
  525.                     }
  526.            
  527.                     // poczekaj az pamiec bedzie pusta (gotowa do zapisu)
  528.            
  529.                     strcpy(&tab[1], wartosc_hex);
  530.                     memset(bufor1, 0, sizeof(bufor1));                                  // czyszczenie bufora
  531.                     memset(wartosc_hex, 0, sizeof(wartosc_hex));        // przygotowanie tablicy na zapis wartosci hex
  532.                     x = 0;
  533.                 }          
  534.                 close(fifo_fd);                
  535.             }
  536.             //sleep(1);
  537.         }
  538.        
  539.         while(stan == 1)
  540.         {
  541.             //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);
  542.             //fflush(stdin);
  543.            
  544.             if(semctl(semafor, 0, GETVAL) != 1)
  545.             {
  546.                
  547.             //  printf("proces p1 bedac w petli stan == 1 zauwazyl ze semafor ma wartosc %d\n", semctl(semafor, 0, GETVAL));
  548.             //  fflush(stdin);
  549.                 if((semctl(semafor, 0, GETVAL) == 0))
  550.                 {
  551.                     stan = 0;
  552.                     //printf("proces 1 zmienil swoj stan na : %d\n", stan);
  553.                     //fflush(stdin);
  554.                    
  555.                     if(poprzedni_stan == 1)
  556.                     {
  557.                         if(pid2 == 0)
  558.                         {
  559.                             des_pid[R] = open("pid2", O_RDONLY);
  560.                             memset(bufor_proces, 0, sizeof(bufor_proces));
  561.                             if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  562.                             {
  563.                                 perror("blad przy odczytywaniu pid p2 w p1");
  564.                                 exit(1);
  565.                             }
  566.                             pid2 = atoi(&bufor_proces[14]);
  567.                             close(des_pid[R]);
  568.                         }
  569.                         kill(pid2, 10);
  570.                         //printf("\nproces 1 wyslal sygnal 10 do procesu 2 w linii 561\n");
  571.                         //fflush(stdin);
  572.                        
  573.                         sygnal_od_p2 = 2;
  574.                     }                  
  575.                 }
  576.                 else
  577.                 {
  578.                     stan = 2;
  579.                 }
  580.             }
  581.                
  582.             if(poprzedni_stan == 0)
  583.             {
  584.                 if(sygnal_od_p2 == 0)
  585.                 {
  586.                     if(pid2 == 0)
  587.                     {
  588.                         des_pid[R] = open("pid2", O_RDONLY);
  589.                         memset(bufor_proces, 0, sizeof(bufor_proces));
  590.                         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  591.                         {
  592.                             perror("blad przy odczytywaniu pid p2 w p1");
  593.                             exit(1);
  594.                         }
  595.                         pid2 = atoi(&bufor_proces[14]);
  596.                         //printf("proces1 odczytal PID procesu 2 w linii 516, czyli: %d\n", pid2);
  597.                         close(des_pid[R]);
  598.                     }
  599.                
  600.                     kill(pid2, 12);
  601.                     //printf("\nproces 1 wyslal sygnal 12 do procesu 2 w linii 593\n");
  602.                     //fflush(stdin);
  603.                     sygnal_od_p2 = 2;
  604.                 }
  605.                
  606.                                
  607.                 if(strlen(&tab[1]) == 0)
  608.                 {      
  609.                     fifo_fd = open("/tmp/fifo", O_RDONLY);                      // otwiera plik typu fifo do odczytu
  610.        
  611.                     if(fifo_fd == -1)
  612.                     {
  613.                         perror("blad przy otwieraniu kolejki FIFO w p1\n");
  614.                         exit(1);
  615.                     }
  616.        
  617.                     m = read(fifo_fd, bufor1, BUFSIZE);
  618.                     if(m == 0) break;
  619.                     x = m;
  620.  
  621.                     if(x < 0)
  622.                     {
  623.                         perror("read error p1\n");
  624.                         exit(1);
  625.                     }
  626.            
  627.                     if(x > 0)
  628.                     {      
  629.                         // Konwersja na HEX
  630.  
  631.                         if(bufor1[0] < 16)
  632.                         {
  633.                             if(bufor1[0] == 10)     // gdy enter
  634.                             {
  635.                                 sprintf(wartosc_hex, "0x0%X\n", bufor1[0]);
  636.                             }
  637.                             else
  638.                             {
  639.                                 sprintf(wartosc_hex, "0x0%X ", bufor1[0]);
  640.                             }
  641.                         }
  642.                         else
  643.                         {
  644.                             sprintf(wartosc_hex, "0x%X ", bufor1[0]);
  645.                         }
  646.            
  647.                         // poczekaj az pamiec bedzie pusta (gotowa do zapisu)
  648.            
  649.                         strcpy(&tab[1], wartosc_hex);
  650.                         memset(bufor1, 0, sizeof(bufor1));                                  // czyszczenie bufora
  651.                         memset(wartosc_hex, 0, sizeof(wartosc_hex));        // przygotowanie tablicy na zapis wartosci hex
  652.                         x = 0;
  653.                     }          
  654.                     close(fifo_fd);                
  655.                 }  
  656.                 poprzedni_stan = 1;
  657.             }
  658.             sleep(1);  
  659.         }
  660.     }
  661.    
  662.     if(pid2 == 0)
  663.     {
  664.         des_pid[R] = open("pid2", O_RDONLY);
  665.         memset(bufor_proces, 0, sizeof(bufor_proces));
  666.         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  667.         {
  668.             perror("blad przy odczytywaniu pid p2 w p1");
  669.             exit(1);
  670.         }
  671.         pid2 = atoi(&bufor_proces[14]);
  672.         close(des_pid[R]);
  673.     }
  674.     // zabijamy proces 2
  675.     kill(pid2, 2);
  676.     // zabijamy proces 0
  677.     if(semctl(semafor, 0, SETVAL, 2) == -1)                        
  678.     {
  679.         perror("blad przy zmianie wartosci semafora przez sygnal_p1 na 1");
  680.         exit(1);
  681.     }
  682. }
  683.  
  684. void proces2()
  685. {
  686.     ssize_t q;
  687.     int poprzedni_stan = 0;
  688.  
  689.     int pid1 = 0;
  690.     close(file_des[0]);     // zablokuj kanal do odczytu
  691.    
  692.     signal(SIGINT, sygnal_p2);
  693.     signal(SIGHUP, sygnal_p2);
  694.     signal(SIGCHLD, sygnal_p2);
  695.     signal(SIGUSR1, sygnal_p2);
  696.     signal(SIGUSR2, sygnal_p2);
  697.    
  698.     while((stan == 0) || (stan == 1))
  699.     {
  700.         while(stan == 0)
  701.         {      
  702.             if(msgrcv(mqid, &msg, sizeof(msg.mtext), 2, IPC_NOWAIT) > 0)            // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
  703.             {
  704.                 if(stan != msg.mtext)
  705.                 {
  706.                     stan = msg.mtext;
  707.                 }      
  708.             }
  709.            
  710.             if(poprzedni_stan == 1)
  711.             {
  712.                 if(sygnal_od_p1 != 1)
  713.                 {
  714.                     if(pid1 == 0)
  715.                     {
  716.                         des_pid[R] = open("pid1", O_RDONLY);
  717.                         memset(bufor_proces, 0, sizeof(bufor_proces));
  718.                         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  719.                         {
  720.                             perror("blad przy odczytywaniu pid p1 w p2");
  721.                             exit(1);
  722.                         }
  723.                         pid1 = atoi(&bufor_proces[14]);
  724.                         close(des_pid[R]);
  725.                     }
  726.                     // budzimy proces1
  727.                     kill(pid1, 10);
  728.                     //printf("\nproces 2 wyslal sygnal 10 do procesu 1 w linii 728\n");
  729.                     //fflush(stdin);
  730.                    
  731.                 }
  732.                 sygnal_od_p1 = 2;
  733.                 poprzedni_stan = 0;            
  734.             }
  735.            
  736.             if(strlen(&tab[1]) != 0)
  737.             {
  738.                 if(write(file_des[1], &tab[1], strlen(&tab[1])) != strlen(&tab[1]))
  739.                 {
  740.                     perror("blad write w p2");
  741.                     exit(1);
  742.                 }
  743.                 // wyczysc pamiec dzielona by przyjac kolejny bajt
  744.                 memset(&tab[1], 0, strlen(&tab[1]));
  745.             }
  746.         }
  747.        
  748.         while(stan == 1)
  749.         {
  750.             if(msgrcv(mqid, &msg, sizeof(msg.mtext), 2, IPC_NOWAIT) > 0)            // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
  751.             {
  752.                
  753.                 if(stan != msg.mtext)
  754.                 {
  755.                     stan = msg.mtext;
  756.                 }
  757.             }
  758.            
  759.             if(poprzedni_stan == 0)
  760.             {
  761.                 if(sygnal_od_p1 != 1)
  762.                 {
  763.                     if(pid1 == 0)
  764.                     {
  765.                         des_pid[R] = open("pid1", O_RDONLY);
  766.                         memset(bufor_proces, 0, sizeof(bufor_proces));
  767.                         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  768.                         {
  769.                             perror("blad przy odczytywaniu pid p1 w p2");
  770.                             exit(1);
  771.                         }
  772.                         pid1 = atoi(&bufor_proces[14]);
  773.                         close(des_pid[R]);
  774.                     }
  775.                     // wstrzymaj p1
  776.                     kill(pid1, 12);
  777.                     //printf("\nproces 2 wyslal sygnal 12 do procesu 1 w linii 783\n");
  778.                     //fflush(stdin);
  779.                    
  780.                 }
  781.                 sygnal_od_p1 = 2;
  782.                
  783.                 if(strlen(&tab[1]) != 0)
  784.                 {
  785.                     if(write(file_des[1], &tab[1], strlen(&tab[1])) != strlen(&tab[1]))
  786.                     {
  787.                         perror("blad write w p2");
  788.                         exit(1);
  789.                     }
  790.                     // wyczysc pamiec dzielona by przyjac kolejny bajt
  791.                     memset(&tab[1], 0, strlen(&tab[1]));
  792.                 }
  793.                 poprzedni_stan = 1;
  794.             }          
  795.         }
  796.     }
  797.    
  798.     if(pid1 == 0)
  799.     {
  800.         des_pid[R] = open("pid1", O_RDONLY);
  801.         memset(bufor_proces, 0, sizeof(bufor_proces));
  802.         if((q = read(des_pid[R], bufor_proces, sizeof(bufor_proces))) < 0)
  803.         {
  804.             perror("blad przy odczytywaniu pid p1 w p2");
  805.             exit(1);
  806.         }
  807.         pid1 = atoi(&bufor_proces[14]);
  808.         close(des_pid[R]);
  809.     }
  810.     // zabijamy proces 1
  811.     kill(pid1, 2);
  812. }
  813.  
  814. void proces3()
  815. {
  816.     ssize_t n;
  817.     int poprzedni_stan = 0;
  818.  
  819.     close(file_des[1]);     // zablokuj kanal do zapisu
  820.    
  821.     signal(SIGINT, sygnal_p3);
  822.     signal(SIGHUP, sygnal_p3);
  823.     signal(SIGCHLD, sygnal_p3);
  824.    
  825.     while((stan == 0) || (stan == 1))
  826.     {  
  827.         while(stan == 0)
  828.         {          
  829.             if(msgrcv(mqid, &msg, sizeof(msg.mtext), 3, IPC_NOWAIT) > 0)            // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
  830.             {
  831.                 if(stan != msg.mtext)
  832.                 {
  833.                     stan = msg.mtext;
  834.                 }
  835.                        
  836.             }
  837.            
  838.             if(poprzedni_stan == 1)
  839.             {
  840.                 poprzedni_stan = 0;
  841.             }
  842.            
  843.             if(tab[0] == 1)
  844.             {
  845.                 if((n = read(file_des[0], bufor_pipe, sizeof(bufor_pipe))) > 0)
  846.                 {
  847.                     if(write(STDOUT_FILENO, bufor_pipe, n) != n)
  848.                     {
  849.                         perror("write error w proces3()");
  850.                         exit(1);
  851.                     }
  852.                     tab[0] = 0;
  853.                     memset(bufor_pipe, 0, sizeof(bufor_pipe));                                     
  854.                 }
  855.             }              
  856.         }
  857.        
  858.         while(stan == 1)
  859.         {          
  860.             if(msgrcv(mqid, &msg, sizeof(msg.mtext), 3, IPC_NOWAIT) > 0)            // ID kolejki, struktura na wiadomosc, rozmiar wiadomosci, typ wiadomosci, flaga
  861.             {
  862.                 if(stan != msg.mtext)
  863.                 {
  864.                     stan = msg.mtext;
  865.                 }
  866.                        
  867.             }
  868.            
  869.             if(poprzedni_stan == 0)
  870.             {
  871.                 if(tab[0] == 1)
  872.                 {
  873.                     if((n = read(file_des[0], bufor_pipe, sizeof(bufor_pipe))) > 0)
  874.                     {
  875.                         if(write(STDOUT_FILENO, bufor_pipe, n) != n)
  876.                         {
  877.                             perror("write error w proces3()");
  878.                             exit(1);
  879.                         }
  880.                         tab[0] = 0;
  881.                         memset(bufor_pipe, 0, sizeof(bufor_pipe));                                     
  882.                     }
  883.                 }
  884.                 poprzedni_stan = 1;
  885.             }
  886.  
  887.         }
  888.     }
  889. }
  890.  
  891. int main(void)
  892. {  
  893.     key = 5678;
  894.     int status;
  895.    
  896.     // Tworzenie plikow przechowujacych ID procesow
  897.    
  898.     mknod("pid0", S_IFREG | 0777, 0);
  899.     mknod("pid1", S_IFREG | 0777, 0);
  900.     mknod("pid2", S_IFREG | 0777, 0);
  901.     mknod("pid3", S_IFREG | 0777, 0);
  902.    
  903.     // Tworzenie kolejki komunikatow
  904.    
  905.     if((mqid = msgget(mqkey, IPC_CREAT | 0666)) < 0)
  906.     {
  907.         perror("blad tworzenia kolejki komunikatow");
  908.         exit(1);
  909.     }
  910.    
  911.     // Tworzenie semaforow
  912.    
  913.     key_t klucz;
  914.     klucz = ftok(".", 'a');                 // na podstawie pliku i pojedynczego znaku id wyznacza klucz semafora
  915.    
  916.     if(klucz == -1)
  917.     {
  918.         perror("blad wyznaczania klucza semafora");
  919.         exit(1);
  920.     }
  921.    
  922.     semafor = semget(klucz, 1, IPC_CREAT | 0777);           // tworzy na podstawie klucza semafor. 1 - ilosc semaforow
  923.    
  924.     if(semafor == -1)
  925.     {
  926.         perror("blad przy tworzeniu semafora");
  927.         exit(1);
  928.     }
  929.    
  930.     if(semctl(semafor, 0, SETVAL, 0) == -1)                         // ustawia poczatkowa wartosc semafora (klucz, numer w zbiorze od 0, polecenie, argument 0/1/2)
  931.     {
  932.         perror("blad przy ustawianiu wartosci poczatkowej semafora");
  933.         exit(1);
  934.     }
  935.    
  936.     // Tworzenie lacza nazwanego FIFO
  937.    
  938.     if(access("/tmp/fifo", F_OK) == -1)                             // sprawdza czy plik istnieje, jesli nie - tworzy go
  939.     {
  940.         if(mkfifo("/tmp/fifo", 0777) != 0)
  941.         {
  942.             perror("blad tworzenia FIFO w main");
  943.             exit(1);
  944.         }
  945.     }
  946.    
  947.     // Tworzenie pamieci dzielonej
  948.     // Lista pamieci wspoldzielonych, komenda "ipcs"
  949.     // usuwanie pamieci wspoldzielonej, komenta "ipcrm -m ID_PAMIECI"
  950.  
  951.     shmid = shmget(key, (BUFSIZE*30), 0666 | IPC_CREAT);
  952.    
  953.     if(shmid == -1)
  954.     {
  955.         perror("shmget");
  956.         exit(1);
  957.     }
  958.    
  959.     tab = (char *) shmat(shmid, NULL, 0);
  960.    
  961.     if(tab == (char *)(-1))
  962.     {
  963.         perror("shmat");
  964.         exit(1);
  965.     }
  966.    
  967.     memset(tab, 0, (BUFSIZE*30));
  968.    
  969.     tab[0] = 0;
  970.    
  971.     // Tworzenie lacza nienazwanego pipe
  972.    
  973.     if(pipe(file_des) == -1)
  974.     {
  975.         perror("pipe");
  976.         exit(1);
  977.     }
  978.    
  979.     // Tworzenie procesow potomnych
  980.     if(!(p0 = fork()))
  981.     {
  982.         des_pid[W] = open("pid0", O_WRONLY | O_TRUNC | O_CREAT);                    // 1 - zapis, 0 - odczyt
  983.        
  984.         sprintf(bufor_proces, "Proces0 ma ID: %d\n", getpid());
  985.    
  986.         if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
  987.         {
  988.             perror("blad przy zapisie pid do pliku w p0");
  989.             exit(1);
  990.         }
  991.    
  992.         close(des_pid[W]);
  993.        
  994.         proces0();
  995.     }
  996.     else if(p0 == -1)
  997.     {
  998.         perror("blad przy p0 fork w main");
  999.         exit(1);
  1000.     }
  1001.     else
  1002.     {
  1003.         if(!(p1 = fork()))
  1004.         {
  1005.             des_pid[W] = open("pid1", O_WRONLY | O_TRUNC | O_CREAT);                    // 1 - zapis, 0 - odczyt
  1006.        
  1007.             sprintf(bufor_proces, "Proces1 ma ID: %d\n", getpid());
  1008.    
  1009.             if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
  1010.             {
  1011.                 perror("blad przy zapisie pid do pliku w p1");
  1012.                 exit(1);
  1013.             }
  1014.    
  1015.             close(des_pid[W]);
  1016.        
  1017.             proces1();
  1018.         }
  1019.         else if(p1 == -1)
  1020.         {
  1021.             perror("blad przy p1 fork w main");
  1022.             exit(1);
  1023.         }
  1024.         else
  1025.         {
  1026.             if(!(p2 = fork()))
  1027.             {
  1028.                 des_pid[W] = open("pid2", O_WRONLY | O_TRUNC | O_CREAT);                    // 1 - zapis, 0 - odczyt
  1029.        
  1030.                 sprintf(bufor_proces, "Proces2 ma ID: %d\n", getpid());
  1031.    
  1032.                 if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
  1033.                 {
  1034.                     perror("blad przy zapisie pid do pliku w p2");
  1035.                     exit(1);
  1036.                 }
  1037.    
  1038.                 close(des_pid[W]);
  1039.                 proces2();
  1040.             }
  1041.             else if(p2 == -1)
  1042.             {
  1043.                 perror("blad przy p2 fork w main");
  1044.                 exit(1);
  1045.             }
  1046.             else
  1047.             {
  1048.                 if(!(p3 = fork()))
  1049.                 {
  1050.                     des_pid[W] = open("pid3", O_WRONLY | O_TRUNC | O_CREAT);                    // 1 - zapis, 0 - odczyt
  1051.        
  1052.                     sprintf(bufor_proces, "Proces3 ma ID: %d\n", getpid());
  1053.    
  1054.                     if(write(des_pid[W], bufor_proces, sizeof(bufor_proces)) != sizeof(bufor_proces))
  1055.                     {
  1056.                         perror("blad przy zapisie pid do pliku w p3");
  1057.                         exit(1);
  1058.                     }
  1059.    
  1060.                     close(des_pid[W]);
  1061.        
  1062.                     proces3();
  1063.                 }
  1064.                 else if(p3 == -1)
  1065.                 {
  1066.                     perror("blad przy p3 fork w main");
  1067.                     exit(1);
  1068.                 }
  1069.                 else
  1070.                 {
  1071.                     // proces macierzysty
  1072.                     waitpid(p0, &status, 0);
  1073.                     printf("\np0 zakonczyl sie\n");
  1074.                     waitpid(p1, &status, 0);
  1075.                     printf("\np1 zakonczyl sie\n");
  1076.                     waitpid(p2, &status, 0);
  1077.                     printf("\np2 zakonczyl sie\n");
  1078.                     waitpid(p3, &status, 0);
  1079.                     printf("\np3 zakonczyl sie\n");
  1080.                    
  1081.                     //wait(NULL);
  1082.                     // usuwanie kolejki komunikatow:
  1083.                     if(msgctl(mqid,IPC_RMID,NULL) < 0)
  1084.                     {
  1085.                         perror("blad przy usuwaniu kolejki komunikatow");
  1086.                         exit(1);
  1087.                     }
  1088.                     unlink("/tmp/fifo");
  1089.                     shmdt(tab);                             // odlaczenie pamieci dzielonej
  1090.                     shmctl(shmid, IPC_RMID, NULL);          // usuwanie pamieci wspoldzielonej
  1091.                     printf("\nKONIEC PROGRAMU\n");
  1092.                 }
  1093.             }
  1094.         }
  1095.     }
  1096.    
  1097.     exit(0);
  1098. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement