//Parse in parallel int parParse(char*** commands){ const char* whitespace = " \t\n"; char** arguments; bool is_built_in = true; pid_t pid; int i; int state = 1; pid_t waitArr[arrLen(*commands)]; memset(waitArr, 0, (arrLen(*commands)+1)*sizeof(pid_t)); for (i = 0; (*commands)[i] != NULL; i++){ arguments = tokenify((*commands)[i], whitespace); is_built_in = built_in(arguments, &state); //check if built in if (!is_built_in){ pid = fork(); //create child process if (pid == 0){ execv(arguments[0], arguments); freeTokens(arguments); printf("Command not valid\n"); exit(0); } else{ waitArr[i] = pid; } } freeTokens(arguments); } waitParallel(waitArr); return state; }
//used to free output of tokenify void freeTokens(char** tokens){ int i; for (i = 0; i < arrLen(tokens); i++){ free(tokens[i]); } free(tokens[i]); free(tokens); }
//Need to deal with string-literal input, parallel vs. sequential, user vs. kernal time, EOF-checkery int main(int argc, char **argv){ char *prompt = "CMAS> "; printf("%s", prompt); fflush(stdout); const int buffer_len=1024; char *buffer=malloc(sizeof(char *)*buffer_len); buffer[0]='\0'; //initial value char **cmd_arr; char mode = 's'; //Mode "bit." 's' means sequential while (fgets(buffer, buffer_len, stdin) != NULL) { //works as an EOF checker, according to Prof. /* process current command line in buffer */ killComments(buffer,buffer_len); //Buffer is always a string cmd_arr = tokenify(buffer,";"); //array of strings, everything is on the heap int i = 0; int clean_len = 0; char ***clean_cmd_arr=malloc(sizeof(char **)*arrLen(cmd_arr)); char **temp_c; printf("Length of cmd_arr: %d\n",arrLen(cmd_arr)); while(cmd_arr[i]!=NULL){ temp_c=breakCommand(cmd_arr[i]); //malloced, remember free(cmd_arr[i]); if(temp_c!=NULL){ clean_cmd_arr[clean_len++]=temp_c; } i++; } free(cmd_arr); clean_cmd_arr[clean_len]=NULL; printf("cca len: %d\n",arrLen2(clean_cmd_arr)); //char *cmd[] = { "/bin/ls", "-l","-t", "-r", ".", NULL }; i=0; char **cmd; char temp_m; int j; _Bool will_exit = 0; struct node *kids = NULL; for(;clean_cmd_arr[i]!=NULL;i++) //i < length of clean_cmd_array { cmd = clean_cmd_arr[i]; printf("Command: _%s_\n",cmd[0]); if(0==strcmp(cmd[0],"exit")){ //exit command given will_exit = 1; //will exit later }else { //not an "exit" command temp_m = modeCheck(cmd,mode); if('n'!=temp_m){ mode=temp_m; }else //no "mode" starting cmd { insert(execCmd(cmd, mode), &kids); } } j=0; for(;j<arrLen(clean_cmd_arr[i]);j++){ free(clean_cmd_arr[i][j]); } free(clean_cmd_arr[i]); } //after all commands executed struct node *copy = NULL; while (copy != NULL) { waitpid(copy->proc, NULL, 0); copy = copy->next; } clear_list(kids); free(copy); free(clean_cmd_arr); if(will_exit){//finished commands and exit given at some point struct rusage usage_self, usage_children; getrusage(RUSAGE_SELF, &usage_self); getrusage(RUSAGE_CHILDREN, &usage_children); printf("%ld.%06ld seconds spent in user mode\n", usage_self.ru_utime.tv_sec + usage_children.ru_utime.tv_sec, usage_self.ru_utime.tv_usec + usage_children.ru_utime.tv_usec); printf("%ld.%06ld seconds spent in kernel mode\n", usage_self.ru_stime.tv_sec + usage_children.ru_stime.tv_sec, usage_self.ru_stime.tv_usec + usage_children.ru_stime.tv_usec); break; //leave while loop } printf("%s", prompt); fflush(stdout); //printf("TESTING\n"); } free(buffer); return 0; }