Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <fcntl.h>
- #include <time.h>
- #include <limits.h>
- #include <signal.h>
- #define READ 0
- #define WRITE 1
- #define MAX_PROCESSES 5
- #define MAX_FILENAME_LENGTH 20
- int main(int argc, char *argv[])
- {
- int num_processes;
- pid_t process_ids[MAX_PROCESSES];
- int fd[MAX_PROCESSES][2];
- int i;
- int child_num;
- int rand_number;
- char pipe_message_input[LINE_MAX], pipe_message_output[LINE_MAX];
- char input_file_name[MAX_FILENAME_LENGTH], output_file_name[MAX_FILENAME_LENGTH];
- FILE *input, *output;
- int is_child = 0;
- if (argc < 3 ) {
- printf("Please enter correct number of slave processes (2-5) and the input file name.\n");
- exit(1);
- }
- num_processes = atoi(argv[1]);
- if (num_processes < 2 || num_processes > 5) {
- printf("Please input a number between 2 and 5\n");
- exit(1);
- }
- printf("Number of child processes: %d\n", num_processes);
- srand(time(NULL));
- //create n pipes
- for (i = 0; i < num_processes; i++) {
- if (pipe(fd[i]) == -1) {
- //pipe failed
- printf("Creating pipe #%d failed!\n", i);
- exit(1);
- }
- }
- //fork processes and setup is_child == 1 for children
- for (i = 0; i < num_processes; i++) {
- //making sure slave processes are not forking
- if (!is_child) {
- process_ids[i] = fork();
- if (process_ids[i] < 0) {
- printf("fork() #%d failed!\n", i);
- exit(1);
- }
- if (process_ids[i] == 0) {
- //this is the child, let's make him aware of it
- is_child = 1;
- child_num = i;
- }
- }
- }
- //closing pipe ends
- if (is_child) {
- //close write end for children
- close(fd[child_num][WRITE]);
- } else {
- //close read end for all pipes in parent
- for (i = 0; i < num_processes; i++) {
- close(fd[i][READ]);
- }
- }
- //input file name and open file
- if (!is_child) {
- memcpy(input_file_name, argv[2], strlen(argv[2]) + 1);
- input = fopen(input_file_name, "r");
- if (input == NULL) {
- printf("Error opening file in master process.\n");
- exit(1);
- }
- printf("Master: opened file %s.\n", input_file_name);
- }
- //output file name for each child
- if (is_child) {
- sprintf(output_file_name, "%d.txt", child_num + 1);
- output = fopen(output_file_name, "w");
- if (output == NULL) {
- printf("Error opening file in slave process %d.\n", child_num + 1);
- exit(1);
- }
- printf("Child: opened file %d.txt\n", child_num+1);
- }
- if (!is_child) {
- printf("Master: getting ready to read from file!\n");
- //read from file and write into pipes
- while (fgets(pipe_message_input, LINE_MAX, input) != NULL) {
- rand_number = (rand() % num_processes);
- write(fd[rand_number][WRITE], pipe_message_input, strlen(pipe_message_input)+1);
- printf("\t Main: sent message to pipe %d -> %s", rand_number+1, pipe_message_input);
- //parent unhangs child after sending him the message
- printf("\t Main: continuing child %d\n", rand_number+1);
- kill(process_ids[rand_number], SIGCONT);
- waitpid(process_ids[rand_number], NULL, WUNTRACED);
- }
- fclose(input);
- printf("Master: closing pipes!\n");
- for (i = 0; i < num_processes; i++) {
- close(fd[i][WRITE]);
- close(fd[i][READ]);
- }
- for (i = 0; i < num_processes; i++) {
- kill(process_ids[i], SIGCONT);
- }
- }
- if (is_child) {
- while (1) {
- //read until WRITE side of pipe is closed
- printf("Child %d: holding...\n", child_num+1);
- //child stops itself
- kill(getpid(), SIGSTOP);
- printf("Child %d continued.\n", child_num+1);
- printf("Child %d: Reading from pipe.\n", child_num+1);
- if (read(fd[child_num][READ], pipe_message_output, LINE_MAX) == 0) {
- printf("Child %d: pipe closed. exiting.\n");
- fclose(output);
- exit(1);
- break;
- } else {
- printf("Child #%d recieved message %s\n", child_num+1, pipe_message_output);
- fputs(pipe_message_output, output);
- }
- }
- fclose(output);
- }
- wait(NULL);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment