//params: room_name void print_room(char* name){ room_node* target = find_room(name); if (target == NULL) return; printf("=== %s ===\n",name); print_users(target->users); print_msgs(target->msgs); }
int main(int argc, char *argv[]) { /* Index */ int i; /* Flags to msgsnd */ int msgsnd_flag = 0; /* Flags to msgrcv */ int msgrcv_flg = 0; /* Number of processes to fork() */ int num_procs = 1; /* String read from input */ char *input = NULL; /* Placeholder for message type identifier */ long msgtyp_id; /* Indices of */ int msgtyp_idxs[26]; int *msgtyp_idxs_p = msgtyp_idxs; /* Struct for use with GNU getopt_long() */ struct option longopts[] = { { "number", required_argument, 0, 'n' }, { 0, 0, 0, 0 } }; /* Variable to hold flag currently * being ready by getopt() */ int c; /* Index of option currently * being considered */ int opt_index = 0; if(argc != 1 && argc != 3) usage(stderr, argv[0], "incorrect number of options", EXIT_FAILURE); /* * Loop adapted from example given at * http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html */ while((c = getopt_long(argc, argv, "n:", longopts, &opt_index)) != -1) { switch(c) { case 'n': num_procs = atoi(optarg); break; case('?'): default: usage(stderr, argv[0], "unrecognized option", EXIT_FAILURE); break; } } if(num_procs > MAX_PROCS) usage(stderr, argv[0], "invalid number of processes", EXIT_FAILURE); /* One queue each for parent and children */ num_queues = num_procs + 1; /* Calculate which queue/process a word * should be assigned to based on its * first letter */ msgtyp_idx_gen(&msgtyp_idxs_p, num_procs); /* Allocate space to store pids of * parent and children */ pids = xmalloc(sizeof(pid_t) * num_queues); /* Store parent pid */ pids[0] = parent_pid = getpid(); /* Create one key each for parent * and child processes */ keygen(&keys, num_queues); /* Create one queue each for parent * and child processes */ queue_init(&queues, keys, num_queues); /* Parent queue is first in array */ parent_queue = queues[0]; /* Set up handler for SIGCHLD, * SIGINT, and SIGTERM */ signal(SIGCHLD, &sig_handler); signal(SIGINT, &sig_handler); signal(SIGTERM, &sig_handler); /* Start subprocesses */ subproc_exec(queues, keys, num_procs); /* Assign string 'input' a message type that is * the pid of one of the subprocesses (that's why there's * a '+ 1' in the array index -- the parent pid is pid[0]). */ while((input = get_word(stdin, BUFLEN)) != NULL) { msgtyp_id = (long)pids[msgtyp_idxs[input[0] - 97] + 1]; /* Create msg_t from 'input' string and * place it in parent queue */ if(msgsnd_str(parent_queue, strlen(input) + 1, msgsnd_flag, msgtyp_id, input, 1) == -1) { perror("main: msgsnd"); clean_up_procs(queues, pids, num_queues); exit(EXIT_FAILURE); } free(input); } /* Send terminating message to each child */ for(i = 1; i < num_queues; i++) { msgtyp_id = (long)pids[i]; if(msgsnd_str(parent_queue, 1, msgsnd_flag, msgtyp_id, "", -1) == -1) { perror("msgsnd"); clean_up_procs(queues, pids, num_queues); exit(EXIT_FAILURE); } } /* Print messages received from children * in alphabetical order */ for(i = 1; i <= num_procs; i++) { if(print_msgs(queues[i], MSG_SZ, pids[i], msgrcv_flg) == -1) { perror("main: msgrcv"); clean_up_procs(queues, pids, num_queues); exit(EXIT_FAILURE); } } /* Wait for children to terminate */ for (i = 0; i < num_procs; i++) wait(NULL); /* Free memory and destroy queues */ clean_up_procs(queues, pids, num_queues); return 0; }