int main(int argc, char* argv[]) { // Declarations for getopt extern int optind; extern char* optarg; int ch; char* format = "f:hn"; // Variables you'll want to use char* filename = "Dimefile"; bool execute = true; // Part 2.2.1: Use getopt code to take input appropriately. while((ch = getopt(argc, argv, format)) != -1) { switch(ch) { case 'f': filename = strdup(optarg); break; case 'n': execute = false; break; case 'h': dime_usage(argv[0]); break; } } argc -= optind; argv += optind; /* at this point, what is left in argv is the targets that were specified on the command line. argc has the number of them. If getopt is still really confusing, try printing out what's in argv right here, then just running dime with various command-line arguments. */ parse_file(filename); /* after parsing the file, you'll want to execute all of the targets that were specified on the command line, along with their dependencies, etc. */ return 0; }
int main(int argc, char* argv[]) { // Declarations for getopt extern int optind; extern char* optarg; int ch; char* format = "hanf:l:"; FILE* fd; char* filename = "Dimefile"; char* output_file = "dime.log"; bool execute = true; bool execute_all = false; bool output = false; // Part 2.2.1: Use getopt code to take input appropriately. while((ch = getopt(argc, argv, format)) != -1) { switch(ch) { case 'f': filename = strdup(optarg); break; case 'a': //execute all targets execute_all = true; break; case 'l': //change output output_file = strdup(optarg); output = true; case 'n': execute = false; break; case 'h': dime_usage(argv[0]); break; case '?': exit(0); } } argc -= optind; argv += optind; //Setup the logfile fd = file_open(output_file, "w+");//Always appends. Switch to w+ to overwrite int dup_result; if((dup_result = dup2(fileno(fd), fileno(DEBUG))) != fileno(DEBUG)) { fprintf(DEBUG, "\nError in redirecting output [%d] \n", dup_result); fclose(fd); exit(0); } parse_file(filename); fprintf(DEBUG, "\n\n----------------DONE PARSING-------------\n\n"); print_targets(); //Execute depending on the flags int i; if(execute_all) { TARGET* curr_tar = root; while(curr_tar != NULL) { fprintf(stdout, "\nExecuting Target[%s]\n", curr_tar->name); execute_target(curr_tar->name, execute); fprintf(stdout, "Execution Done..Maybe[%s]\n", curr_tar->name); curr_tar = curr_tar->next; } } else //Just execute a single target { //execute commands/print out commands for a given target for(i = 0; i < argc; i++) { char* target = argv[i]; if(find(target) == NULL) { fprintf(stdout, "Bad Target\n"); exit(0); } fprintf(stdout, "\nExecuting Target[%s]\n", target); execute_target(target, execute); fprintf(stdout, "\nExecution Done..Maybe[%s]\n", target); } } fprintf(DEBUG, "-------------------Exiting Main program---------------------\n"); fclose(fd); return 0; }
int main(int argc, char* argv[]) { // Declarations for getopt extern int optind; extern char* optarg; int ch; char* format = "f:hq:t:"; // Variables you'll want to use char* filename = "Dimefile"; int num_threads = 3; char* queue_size = "5"; // Part 2.2.1: Use getopt code to take input appropriately. while((ch = getopt(argc, argv, format)) != -1) { switch(ch) { case 'f': filename = strdup(optarg); break; case 'h': dime_usage(argv[0]); break; case 't': num_threads = atoi(optarg); if (num_threads < 1) { error("The number of helper threads must be at least 1."); } break; case 'q': queue_size = optarg; if (atoi(queue_size) < 1) { error("The queue size must be at least 1."); } break; } } argc -= optind; argv += optind; //Set up queue for targets rule_node_t* rule_queue = (rule_node_t*)(malloc(sizeof(rule_node_t))); rule_node_t* output_queue = (rule_node_t*)(malloc(sizeof(rule_node_t))); //The first "real" entry of rule_queue is the second, so we can change it //while keeping the address of rule_queue constant rule_queue->rule = NULL; rule_queue->next = NULL; ARG_HOLDER argholder; argholder.rule_queue = rule_queue; argholder.output_queue = output_queue; argholder.max_queue_length = atoi(queue_size); argholder.threads_not_done = 0; argholder.finished_adding = 0; argholder.done = 0; pthread_mutex_init(&mutex, NULL); sem_init(&sem_lock, 0, 1); pthread_cond_init(&queue_full, NULL); pthread_cond_init(&queue_empty, NULL); pthread_cond_init(&finished_execution, NULL); //Set up threads PTHREAD_NODE* threads = NULL; int i; for (i = 0; i < num_threads; i++) { pthread_t* thread = (pthread_t*)(malloc(sizeof(pthread_t))); if (pthread_create(thread, NULL, helper_thread, (void*)(&argholder)) != 0) { error("Failed to create helper thread."); } else { PTHREAD_NODE* cur_node = (PTHREAD_NODE*)(malloc(sizeof(PTHREAD_NODE))); cur_node->thread = thread; cur_node->next = threads; threads = cur_node; } } // parse the given file, then execute targets rule_node_t* list = parse_file(filename); execute_targets(argc, argv, list, &argholder); rule_node_free(list); rule_queue_free(rule_queue); rule_queue_free(output_queue); //Rejoin threads PTHREAD_NODE* pthread_ptr = threads; while (pthread_ptr != NULL) { if (pthread_join(*(pthread_ptr->thread),NULL) != 0) { error("Couldn't join helper thread."); } else { printf("Joined helper thread.\n"); } PTHREAD_NODE* temp = pthread_ptr; pthread_ptr = pthread_ptr->next; free(temp->thread); free(temp); } pthread_mutex_destroy(&mutex); sem_destroy(&sem_lock); pthread_cond_destroy(&queue_full); pthread_cond_destroy(&queue_empty); pthread_cond_destroy(&finished_execution); return 0; }
int main(int argc, char* argv[]) { // Declarations for getopt extern int optind; extern char* optarg; int ch; char* format = "f:hn"; // Variables you'll want to use char* filename = "Dimefile"; bool execute = true; // Part 2.2.1: Use getopt code to take input appropriately. while((ch = getopt(argc, argv, format)) != -1) { switch(ch) { case 'f': filename = strdup(optarg); break; case 'n': execute = false; break; case 'h': dime_usage(argv[0]); break; } } argc -= optind; argv += optind; /* at this point, what is left in argv is the targets that were specified on the command line. argc has the number of them. If getopt is still really confusing, try printing out what's in argv right here, then just running dime with various command-line arguments. */ parse_file(filename); //TODO:: /* after parsing the file, you'll want to execute all of the targets that were specified on the command line, along with their dependencies, etc. */ //TODO:: Turn everything below into a function, so only need 2 function calls. Not enough time right now int i; pid_t child_pid; if(execute == false) { for(i = 0; i < argc; i++) { char* target = argv[i]; char* commands; char** hold; TARGET* curr_tar = find(target); TARGET* curr_dep_tar; DEP* curr_dep; if(curr_tar == NULL) { fprintf(stdout, "\nInvalid target\n"); } else { //TODO:: all the curr_dep, curr_dep_tar , curr_tar is ambiguous if(curr_tar->dependencies != NULL) // we have dependencies { curr_dep = curr_tar->dependencies; curr_dep_tar = curr_dep->dep; while(true) { int deps = Dlist_length(curr_dep); //get number of dependencies that the current dependency list has if(curr_dep != NULL) { //fork a child for each dependency in the current dependency list for(i = 0; i < deps; i++) { if((child_pid = fork()) <= 0) { break; } else { //Changes where the current dependency is pointing at for the children fprintf(stdout, "Fork : Forked Child [%d] with Parent [%d] in Group [%d] to Exec [%s]\n", child_pid, getpid(), getgid(), curr_dep->dep_name); curr_dep = curr_dep->next; if(curr_dep != NULL) curr_dep_tar = curr_dep->dep; } } } if(child_pid > 0) //Parent { //wait for the last child TODO: Use proccess group instead of last child. WNOHANG was returning -1 not sure how to fix fprintf(stdout, "Wait : Parent Process [%d] waiting for Child [%d] in Group [%d]\n", getpid(), child_pid, getgid()); i = waitpid(child_pid, NULL, 0); //wait for last child to exec //execute target //fprintf(stdout, "Execute : Parent Process [%d] Executing [%s]\n", getppid(), curr_tar->name); while((commands = getCommands(curr_tar, commands)) != NULL) { fprintf(stdout, "Commands: %s\n", commands); } exit(0); } if(child_pid == 0) { //If child has dependencies, need to fork to execute those if(curr_dep_tar->dependencies != NULL) //has dependencies { curr_tar = curr_dep_tar; curr_dep = curr_dep_tar->dependencies; curr_dep_tar = curr_dep->dep; fprintf(stdout, "Fork : Child Process [%d] forking to execute [%s]\n", getpid(), curr_dep->dep_name); } else //execute { //fprintf(stdout, "Execute : Child Process [%d] with Parent [%d] Executing [%s]\n", getpid(), getppid(), curr_dep_tar->name); exit(0); } } } } } } } else //--------------------------------------------------------------------------actually execute commands { //TODO:: Get rid of this crap for a function call, see previous todo for(i = 0; i < argc; i++) { char* target = argv[i]; char* commands; TARGET* curr_tar = find(target); TARGET* curr_dep_tar; DEP* curr_dep; if(curr_tar == NULL) { fprintf(stdout, "\nInvalid target\n"); } else { //TODO:: all the curr_dep, curr_dep_tar , curr_tar is ambiguous if(curr_tar->dependencies != NULL) // we have dependencies { curr_dep = curr_tar->dependencies; curr_dep_tar = curr_dep->dep; while(true) { int deps = Dlist_length(curr_dep); //get number of dependencies that the current dependency list has if(curr_dep != NULL) { //fork a child for each dependency in the current dependency list for(i = 0; i < deps; i++) { if((child_pid = fork()) <= 0) { break; } else { //Changes where the current dependency is pointing at for the children fprintf(stdout, "Fork : Forked Child [%d] with Parent [%d] in Group [%d] to Exec [%s]\n", child_pid, getpid(), getgid(), curr_dep->dep_name); curr_dep = curr_dep->next; if(curr_dep != NULL) curr_dep_tar = curr_dep->dep; } } } if(child_pid > 0) //Parent { //wait for the last child TODO: Use proccess group instead of last child. WNOHANG was returning -1 not sure how to fix fprintf(stdout, "Wait : Parent Process [%d] waiting for Child [%d] in Group [%d]\n", getpid(), child_pid, getgid()); i = waitpid(child_pid, NULL, 0); //wait for last child to exec //execute target fprintf(stdout, "Execute : Parent Process [%d] Executing [%s]\n", getppid(), curr_tar->name); while((commands = getCommands(curr_tar, commands)) != NULL) { fprintf(stdout, "Executing Command: %s\n", commands); } exit(0); } if(child_pid == 0) { //If child has dependencies, need to fork to execute those if(curr_dep_tar->dependencies != NULL) //has dependencies { curr_tar = curr_dep_tar; curr_dep = curr_dep_tar->dependencies; curr_dep_tar = curr_dep->dep; fprintf(stdout, "Fork : Child Process [%d] forking to execute [%s]\n", getpid(), curr_dep->dep_name); } else //execute { fprintf(stdout, "Execute : Child Process [%d] with Parent [%d] Executing [%s]\n", getpid(), getppid(), curr_dep_tar->name); exit(0); } } } } } } } return 0; }