Advertisement
rnort

SPO-2-NIX-RC1

Oct 20th, 2012
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <ncurses.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <signal.h>
  5. #include <string.h>
  6. #include <sys/wait.h>
  7.  
  8. #define MAX_PROCESS_NUMBER 10
  9.  
  10. void printString();
  11. void setQuitFlag(int);
  12. void setPrintingFlag(int);
  13. void bindSignals();
  14. void init();
  15. void child();
  16. int waitForChild(pid_t);
  17. void onQuit(pid_t*);
  18. int analyzePid(pid_t);
  19. int addChildProcess(pid_t*);
  20. void removeChildProcess(pid_t*);
  21. /*
  22.  * Global variables
  23.  */
  24. struct sigaction  endProcessSignal, printingSignal;
  25. int numberOfProcesses = 0;
  26. char textStrings[MAX_PROCESS_NUMBER][50] = {
  27.         "<00>",
  28.         "<11>",
  29.         "<22>",
  30.         "<33>",
  31.         "<44>",
  32.         "<55>",
  33.         "<66>",
  34.         "<77>",
  35.         "<88>",
  36.         "<99>"};
  37.  
  38. int allowPrint = 1,
  39.     quitFlag = 0;
  40. int parentPid;
  41.  
  42.  
  43. int main()
  44. {
  45.     init();
  46.     pid_t   childPids[MAX_PROCESS_NUMBER];
  47.     int     currentProcessIndex = 0;
  48.     while(1)
  49.     {
  50.         fflush(stdin);
  51.         char s = getchar();
  52.        
  53.         switch(s)
  54.         {
  55.         case 'q':
  56.             onQuit(childPids);
  57.             exit(EXIT_SUCCESS);
  58.             break;
  59.         case '+':
  60.             addChildProcess(childPids);
  61.             break;
  62.         case '-':
  63.             removeChildProcess(childPids);     
  64.             break;
  65.         default:
  66.             break;
  67.         }
  68.        
  69.         if( allowPrint && numberOfProcesses)
  70.         {
  71.             currentProcessIndex = currentProcessIndex >= numberOfProcesses ? 0 : currentProcessIndex;
  72.             kill(childPids[currentProcessIndex], SIGUSR2);
  73.             allowPrint = 0;
  74.             currentProcessIndex++;    
  75.         }
  76.     }
  77.     clear();
  78.     endwin();
  79.     exit(EXIT_SUCCESS);
  80. }
  81.  
  82. void removeChildProcess(pid_t* childPids)
  83. {
  84.     if( numberOfProcesses )
  85.     {
  86.         kill(childPids[numberOfProcesses-1], SIGUSR1);
  87.         waitForChild(childPids[numberOfProcesses-1]);
  88.         --numberOfProcesses;
  89.     }
  90. }
  91.  
  92. int addChildProcess(pid_t* childPids)
  93. {
  94.     if ( MAX_PROCESS_NUMBER == numberOfProcesses )
  95.     {
  96.         return 1;
  97.     }
  98.     pid_t pid = fork();
  99.     if (analyzePid(pid))
  100.     {
  101.         return 1;
  102.     }  
  103.     allowPrint = numberOfProcesses ? allowPrint : 1;
  104.     ++numberOfProcesses;
  105.     childPids[numberOfProcesses-1] = pid;
  106.     usleep(10);     // wait for sigaction binding in child process      
  107.     return 0;
  108. }
  109.  
  110. int analyzePid(pid_t pid)
  111. {
  112.     if ( !pid )
  113.     {
  114.         child();
  115.         exit(EXIT_SUCCESS);
  116.     }
  117.     if ( pid == -1) // ERROR
  118.     {
  119.         printw("Error!\n");
  120.         refresh();
  121.         return 1;
  122.     }
  123.     return 0;
  124. }
  125.  
  126. int getPosition()
  127. {
  128.     int pos = getpid();
  129.     pos -= parentPid;
  130.     return pos > numberOfProcesses ? numberOfProcesses : pos;          
  131. }
  132.  
  133. void printString()
  134. {
  135.     int position = getPosition();
  136.     for(int i = 0; i < strlen(textStrings[position]); i++)
  137.     {
  138.         printw("%c", textStrings[position][i]);
  139.         refresh();
  140.         usleep(100000);
  141.     }      
  142. }
  143.  
  144. void setQuitFlag(int arg)
  145. {
  146.     quitFlag = 1;
  147. }
  148.  
  149. void setPrintingFlag(int arg)
  150. {
  151.     allowPrint = 1;
  152. }
  153.  
  154. void bindSignals()
  155. {
  156.     endProcessSignal.sa_handler = setQuitFlag;
  157.     sigaction(SIGUSR1,&endProcessSignal,NULL);
  158.     printingSignal.sa_handler = setPrintingFlag;
  159.     sigaction(SIGUSR2,&printingSignal,NULL);
  160. }
  161.  
  162. void init()
  163. {
  164.     initscr();
  165.     curs_set(0);
  166.     refresh();
  167.     bindSignals();
  168.  
  169. }
  170.  
  171. void child()
  172. {
  173.     allowPrint = 0;
  174.     int position = getPosition();
  175.     while(!quitFlag)
  176.     {  
  177.         if(allowPrint)
  178.         {              
  179.             printString();
  180.             allowPrint = 0;
  181.             kill(getppid(), SIGUSR2);
  182.         }
  183.     }
  184. }
  185.  
  186. int waitForChild(pid_t childPid)
  187. {
  188.     pid_t w;
  189.     int status;
  190.     do
  191.     {
  192.         w = waitpid(childPid, &status, WUNTRACED | WCONTINUED);
  193.     }while(!WIFEXITED(status) && !WIFSIGNALED(status));
  194.     return status;
  195. }
  196. /*
  197.  * Ends child processes.
  198.  */
  199. void onQuit(pid_t* pidArray)
  200. {
  201.     for(int i = 0; i < numberOfProcesses; i++ )
  202.     {
  203.         kill(pidArray[i], SIGUSR1);
  204.         waitForChild(pidArray[i]);
  205.     }
  206.     clear();
  207.     endwin();
  208. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement