Guest User

Untitled

a guest
Apr 9th, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.68 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <sys/wait.h>
  7. #include <fcntl.h>
  8. #include <time.h>
  9. #include <limits.h>
  10. #include <signal.h>
  11.  
  12. #define READ 0
  13. #define WRITE 1
  14. #define MAX_PROCESSES 5
  15. #define MAX_FILENAME_LENGTH 20
  16.  
  17. int main(int argc, char *argv[])
  18. {
  19.       int num_processes;
  20.       pid_t process_ids[MAX_PROCESSES];
  21.       int fd[MAX_PROCESSES][2];
  22.       int i;
  23.       int child_num;
  24.       int rand_number;
  25.  
  26.       char pipe_message_input[LINE_MAX], pipe_message_output[LINE_MAX];
  27.       char input_file_name[MAX_FILENAME_LENGTH], output_file_name[MAX_FILENAME_LENGTH];
  28.  
  29.       FILE *input, *output;
  30.  
  31.       int is_child = 0;
  32.  
  33.       if (argc < 3 ) {
  34.           printf("Please enter correct number of slave processes (2-5) and the input file name.\n");
  35.           exit(1);
  36.       }
  37.  
  38.       num_processes = atoi(argv[1]);
  39.       if (num_processes < 2 || num_processes > 5) {
  40.           printf("Please input a number between 2 and 5\n");
  41.           exit(1);
  42.       }
  43.       printf("Number of child processes: %d\n", num_processes);
  44.  
  45.       srand(time(NULL));
  46.  
  47.       //create n pipes
  48.       for (i = 0; i < num_processes; i++) {
  49.               if (pipe(fd[i]) == -1) {
  50.               //pipe failed
  51.               printf("Creating pipe #%d failed!\n", i);
  52.               exit(1);
  53.             }
  54.       }
  55.  
  56.       //fork processes and setup is_child == 1 for children
  57.       for (i = 0; i < num_processes; i++) {
  58.               //making sure slave processes are not forking
  59.               if (!is_child) {
  60.  
  61.               process_ids[i] = fork();
  62.  
  63.               if (process_ids[i] < 0) {
  64.                   printf("fork() #%d failed!\n", i);
  65.                   exit(1);
  66.               }
  67.  
  68.               if (process_ids[i] == 0) {
  69.                   //this is the child, let's make him aware of it
  70.                   is_child = 1;
  71.                   child_num = i;
  72.               }
  73.  
  74.             }
  75.       }
  76.  
  77.       //closing pipe ends
  78.       if (is_child) {
  79.               //close write end for children
  80.               close(fd[child_num][WRITE]);
  81.       } else {
  82.               //close read end for all pipes in parent
  83.               for (i = 0; i < num_processes; i++) {
  84.                 close(fd[i][READ]);
  85.             }
  86.       }
  87.  
  88.       //input file name and open file
  89.       if (!is_child) {
  90.           memcpy(input_file_name, argv[2], strlen(argv[2]) + 1);
  91.           input = fopen(input_file_name, "r");
  92.           if (input == NULL) {
  93.               printf("Error opening file in master process.\n");
  94.               exit(1);
  95.           }
  96.          
  97.           printf("Master: opened file %s.\n", input_file_name);
  98.       }
  99.  
  100.       //output file name for each child
  101.       if (is_child) {
  102.               sprintf(output_file_name, "%d.txt", child_num + 1);
  103.               output = fopen(output_file_name, "w");
  104.               if (output == NULL) {
  105.                 printf("Error opening file in slave process %d.\n", child_num + 1);
  106.                 exit(1);
  107.             }
  108.           printf("Child: opened file %d.txt\n", child_num+1);
  109.       }
  110.  
  111.       if (!is_child) {
  112.               printf("Master: getting ready to read from file!\n");
  113.           //read from file and write into pipes
  114.           while (fgets(pipe_message_input, LINE_MAX, input) != NULL) {
  115.               rand_number = (rand() % num_processes);
  116.               write(fd[rand_number][WRITE], pipe_message_input, strlen(pipe_message_input)+1);
  117.               printf("\t Main: sent message to pipe %d  -> %s", rand_number+1, pipe_message_input);
  118.               //parent unhangs child after sending him the message
  119.               printf("\t Main: continuing child %d\n", rand_number+1);
  120.               kill(process_ids[rand_number], SIGCONT);
  121.               waitpid(process_ids[rand_number], NULL, WUNTRACED);
  122.           }
  123.           fclose(input);
  124.  
  125.           printf("Master: closing pipes!\n");
  126.           for (i = 0; i < num_processes; i++) {
  127.               close(fd[i][WRITE]);
  128.               close(fd[i][READ]);
  129.           }
  130.  
  131.           for (i = 0; i < num_processes; i++) {
  132.               kill(process_ids[i], SIGCONT);
  133.           }
  134.       }
  135.  
  136.       if (is_child) {
  137.           while (1) {
  138.                   //read until WRITE side of pipe is closed
  139.                   printf("Child %d: holding...\n", child_num+1);
  140.                   //child stops itself
  141.                   kill(getpid(), SIGSTOP);
  142.                   printf("Child %d continued.\n", child_num+1);
  143.                   printf("Child %d: Reading from pipe.\n", child_num+1);
  144.  
  145.               if (read(fd[child_num][READ], pipe_message_output, LINE_MAX) == 0) {
  146.                       printf("Child %d: pipe closed. exiting.\n");
  147.                       fclose(output);
  148.                       exit(1);
  149.                       break;
  150.  
  151.               } else {
  152.                   printf("Child #%d recieved message %s\n", child_num+1, pipe_message_output);
  153.                   fputs(pipe_message_output, output);
  154.               }
  155.  
  156.           }
  157.               fclose(output);
  158.       }
  159.  
  160.       wait(NULL);
  161.  
  162.       return 0;
  163. }
Advertisement
Add Comment
Please, Sign In to add comment