int main(int argc, char **argv) { char buffer[1024]; int continueloop = 0; char** commands; int state = 0; // 0 = sequential, 1 = parallel, 2 = exit while(continueloop == 0){ if (state == 0) printf("\nOperating in sequential mode\n"); else if (state == 1) printf("\nOperating in parallel mode\n"); printf("Type away>> "); fgets(buffer, 1024, stdin); removeComments(buffer); commands = tokenify(buffer, ";"); if (state == 0){ state = seqParse(&commands); } else if (state == 1){ state = parParse(&commands); } if (state == 2){ printf("Goodbye\n"); freeTokens(commands); return 0; } freeTokens(commands); } return 0; }
//Parses commands sequentially int seqParse(char*** commands){ const char* whitespace = " \t\n"; char** arguments; bool is_built_in = true; int* status = 0; pid_t pid; int state = 0; for (int i = 0; (*commands)[i] != NULL; i++){ arguments = tokenify((*commands)[i], whitespace); is_built_in = built_in(arguments, &state); if (!is_built_in){ pid = fork(); if (pid == 0){ //child process execv(arguments[0], arguments);//execv the command freeTokens(arguments); printf("Command not valid\n"); //if execv returns, command was invalid exit(0); } else{ //parent process waitpid(pid, status, 0); // wait for child process to end } } freeTokens(arguments); } return state; }
//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; }
void process_data(FILE *input_file) { struct rusage usage; struct timeval user_end, sys_end; //assume each line contains less than or equal to 100 characters char *line = malloc(101*sizeof(char)); //initialize linked list struct node *tokens = NULL; while(fgets(line, 100, input_file)!=NULL){ tokenify(line, &tokens); } list_sort(&tokens); printf("*** List Contents Begin ***\n"); list_print(tokens); printf("*** List Contents End ***\n"); free(line); list_clear(tokens); getrusage(RUSAGE_SELF, &usage); user_end = usage.ru_utime; sys_end = usage.ru_stime; //print out resource stat printf("User time:\t%f\n", user_end.tv_sec + (user_end.tv_usec)/1000000.); printf("System time:\t%f\n", sys_end.tv_sec + (sys_end.tv_usec)/1000000.); }
int main(int argc, char **argv) { char s1[] = " the \tinternet is a series of tubes "; char s2[] = " \t\n"; char s3[] = " the \tinternet is not a series of tubes "; char s4[] = " \t\n"; char s5[] = "8"; removewhitespace(s1); removewhitespace(s2); printf("Remove whitespace - s1: %s\n", s1); printf("Remove whitespace - s2: %s\n", s2); printtokens(tokenify(s3)); printtokens(tokenify(s4)); printtokens(tokenify(s5)); return 0; }
//sees if a string is empty bool is_empty(char* input){ char* temp = strdup(input); char** tokens = tokenify(temp, " \n\t"); if (tokens[0] == NULL){ free(temp); freeTokens(tokens); return true; } free(temp); freeTokens(tokens); return false; }
int main(int argc, char **argv) { display_prompt(); FILE *datafile = NULL; datafile = fopen("shell-config", "r"); Node *head = NULL; if (datafile != NULL) { char line[1024]; while (fgets(line, 1024, datafile) != NULL) { int slen = strlen(line); line[slen-1] = '\0'; list_append(line, "", &head); } fclose(datafile); } char curr_mode = 's'; char buffer[1024]; Node *paused_list = NULL; Node *cpidlist = NULL; while (fgets(buffer, 1024, stdin) != NULL) { char *newbuffer = replace_pound(buffer); newbuffer[strlen(newbuffer)-1] = '\0'; char **pointers_to_commands = tokenify(newbuffer, ";"); free(newbuffer); if (pointers_to_commands[0] == NULL) { display_prompt(); continue; } if (curr_mode == 's') { curr_mode = sequential_mode(pointers_to_commands, head); } else if (curr_mode == 'p') { curr_mode = parallel_mode(pointers_to_commands, head, &paused_list, &cpidlist); } if (curr_mode == 'e') { free_tokens(pointers_to_commands); list_clear(paused_list); list_clear(cpidlist); list_clear(head); exit(0); } display_prompt(); free_tokens(pointers_to_commands); } list_clear(head); list_clear(paused_list); list_clear(cpidlist); printf("\n"); return 0; }
void loop(void) { char *line; char **args; int isdone; do { printf("> "); line = reading_line(); args = tokenify(line); isdone = execute(args); free(line); free(args); } while (isdone); }
/* * Runs commands in sequential mode. */ char sequential_mode(char **pointers_to_commands, Node *head) { char mode = 's'; pid_t cpid, w; char **command; char return_char = 's'; int i = 0; while (pointers_to_commands[i] != NULL) { command = tokenify(pointers_to_commands[i], " \n\t"); if (command[0] == NULL) { i++; free_tokens(command); continue; } if (handle_exit(command) != 'n') { free_tokens(command); return 'e'; } if (return_char != 'e' && is_mode(command)) { return_char = handle_mode(command, mode, return_char); i++; free_tokens(command); continue; } handle_parallel_builtins(command, NULL, NULL, mode); cpid = fork(); if (cpid == 0) { char *tempcommand; tempcommand = prepend_path(command, head); command[0] = tempcommand; if (execv(command[0], command) < 0) { fprintf(stderr, "execv failed: %s\n", strerror(errno)); printf("That's not a valid command! \n"); free_tokens(command); exit(EXIT_FAILURE); } free(tempcommand); } else { int status = 0; w = wait(&status); i++; } free_tokens(command); } return return_char; }
void shell_loop(void) { char *line; char **args; int status; char buffer[1024]; printf("> "); fflush(stdout); while (fgets(buffer, 1024, stdin) != NULL){ while (status){ printf("> "); line = shell_read_line(); args = tokenify(line); status = shell_execute(args); free(line); free(args); } } }
int main(int argc, char **argv) { // strdup makes a newly allocated (malloced) copy of a string char *orig = strdup("the internet is a series of tubes"); char *copy = strdup(orig); /* ********************************** */ /* test of whitespace removal */ /* ********************************** */ printf("remove whitespace: before <%s> after <%s>\n", orig, removewhitespace(copy)); free(copy); // free modified copy copy = strdup(orig); // make new copy /* ********************************** */ /* c to pascal and back to c tests */ /* ********************************** */ char *pascalstr = c2pascal(copy); printf("made pascal string out of %s; orig strlen was %d and pascal strlen is %d\n", orig, (int)strlen(orig), (int)pascalstr[0]); char *cstr = pascal2c(pascalstr); printf("converted pascal string back to c. orig: <%s> reconversion: <%s>\n", orig, cstr); free(copy); /* ********************************** */ /* tokenify test */ /* ********************************** */ copy = strdup(orig); char **x = tokenify(copy); int i = 0; printf("tokenified <%s>. next output should show each token on a separate line.\n", orig); while (x[i]) { printf("\t<%s>\n", x[i]); i++; } return 0; }
void sequential (int * new_mode, int *ex, char **commands, char ** dir_list){ char **one_command; int i = 0; int special = 0; while (commands[i] != NULL){ one_command = tokenify(commands[i]," \n\t"); if (one_command[0] == NULL) { special = 1; } if (strcmp(one_command[0],"exit") == 0) { *ex=1; } else if ((strcmp(one_command[0], "mode")) == 0) { if (one_command[1] != NULL) { if ((strcmp(one_command[1], "sequential")) == 0 || (strcmp(one_command[1], "s")) == 0) { *new_mode = SEQUENTIAL; } else if ((strcmp(one_command[1], "parallel")) == 0 || (strcmp(one_command[1], "p")) == 0) { *new_mode = PARALLEL; } else { printf("Invalid mode, please try again.\n"); } } else { printf("Current mode: sequential\n"); } special = 1 } else if (strcmp(one_command[0],"jobs") == 0){ printf("No parallel jobs running in sequential mode.\n"); special = 1; } else if (strcmp(one_command[0],"pause")==0){ printf("Pause is not a valid command in sequential mode\n"); special = 1; } else if (strcmp(one_command[0],"resume")==0){ printf("Resume is not a valid command in sequential mode\n"); special = 1; } if (special) { special = 0; free_array(one_command); i++; continue; } struct stat statresult; int rv = stat(one_command[0], &statresult); if (rv < 0){ //stat failed, no such file //find another one and change it rv = command_check(dir_list, &one_command); if (rv < 0){ printf("Invalid command: %s\n", one_command[0]); i++; continue; } } int child_pid = fork(); int child_status; if (child_pid < 0){ fprintf(stderr,"fork failed, could not create child process\n"); } else if (child_pid == 0) { if (execv(one_command[0],one_command)<0){ fprintf(stderr,"Execution failed: %s\n",strerror(errno)); } } else { waitpid(child_pid, &child_status, 0); free_array(one_command); } i++; }
/* * Runs commands in parallel mode, with support for background processes. */ char parallel_mode(char **pointers_to_commands, Node *head, Node **paused_list, Node **cpidlist) { int count = 0; // counts the no. of times we've been in the loop; // if more than 1, we need to free // pointers_to_commands, which is different from what we got from main. while (1) { count++; char mode = 'p'; pid_t cpid; char **command; char return_char = 'p'; int i = 0; while (pointers_to_commands[i] != NULL) { command = tokenify(pointers_to_commands[i], " \n\t"); if (command[0] == NULL) { i++; free_tokens(command); continue; } if (handle_exit(command) != 'n') { if (*cpidlist == NULL && pointers_to_commands[i+1] == NULL) { return_char = 'e'; } else { printf("There are processes still running. You cannot exit yet. \n"); } free_tokens(command); i++; continue; } if (is_mode(command)) { return_char = handle_mode(command, mode, return_char); if (return_char == 's') { if (*cpidlist != NULL || pointers_to_commands[i+1] != NULL) { printf("There are processes running. You cannot switch modes yet.\n"); return_char = 'p'; } } free_tokens(command); i++; continue; } if (handle_parallel_builtins(command, paused_list, cpidlist, mode) == 1) { i++; free_tokens(command); continue; } cpid = fork(); if (cpid == 0) { char *tempcommand; tempcommand = prepend_path(command, head); command[0]= tempcommand; if (execv(command[0], command) < 0) { fprintf(stderr, "execv failed: %s\n", strerror(errno)); printf("That's not a valid command! \n"); free_tokens(command); exit(EXIT_FAILURE); } } else { char whole_command[128]; memset(whole_command, '\0', 128); strcat(whole_command, command[0]); if (command[1] != NULL) { strcat(whole_command, " "); strcat(whole_command, command[1]); } char cpidstr[128]; sprintf(cpidstr, "%d", cpid); list_append(cpidstr, whole_command, cpidlist); } i++; free_tokens(command); } if (count > 1) { free_tokens(pointers_to_commands); } if (return_char != 'p') { return return_char; } struct pollfd pfd[1]; pfd[0].fd = 0; pfd[0].events = POLLIN; pfd[0].revents = 0; display_prompt(); int some_process_completed = 0; while (1) { int status; int rv = poll(&pfd[0], 1, 800); Node *to_delete_list = NULL; Node *tempcpidlist = *cpidlist; pid_t w; if (rv == 0) { some_process_completed = 0; while (tempcpidlist != NULL) { w = atoi(tempcpidlist->data); // I know that the ideal way to check for child process death is to use a macro such as WIFEXITED on status, // but it wasn't working for me. // status always had the value 0. So I'm doing this instead to check for process completion. if (waitpid(w, &status, WUNTRACED|WNOHANG) == -1) { list_append(tempcpidlist->data, "", &to_delete_list); printf("\nProcess %s (%s) completed.\n", tempcpidlist->data, tempcpidlist->additional_data); some_process_completed = 1; } tempcpidlist = tempcpidlist->next; } Node *curr = to_delete_list; while (curr != NULL) { list_delete(curr->data, cpidlist); curr = curr->next; } list_clear(to_delete_list); if (some_process_completed == 1) { display_prompt(); } } else if (rv > 0) { char buffer[1024]; if (fgets(buffer, 1024, stdin) == NULL) { if (*cpidlist != NULL) { printf("There are processes still running. You can't exit now.\n"); display_prompt(); } else { return_char = 'e'; return return_char; } } else { char *newbuffer = replace_pound(buffer); newbuffer[strlen(newbuffer)-1] = '\0'; pointers_to_commands = tokenify(newbuffer, ";"); free(newbuffer); break; } } else { printf("there was some kind of error: %s \n", strerror(errno)); } } } }
void process_data(FILE *input_file) { // !! your code should start here. the input_file parameter // is an already-open file. you can read data from it using // the fgets() C library function. close it with the fclose() // built-in function //CPU time starting stuff struct rusage userUsage, systemUsage; struct timeval userStart, userEnd, systemStart, systemEnd; getrusage(RUSAGE_SELF, &userUsage); getrusage(RUSAGE_SELF, &systemUsage); userStart = userUsage.ru_utime; systemStart = systemUsage.ru_stime; /* //this is from when we tried to be fancy //input from stdin if(input_file == stdin) { char buffer[240]; char finalstr[666]; while(1) { printf("Enter a value (Ctrl+D to exit): "); if(fgets(buffer,240,stdin) == NULL) { break; } strcat(finalstr,buffer); printf("%s\n",finalstr); } printf("\n"); } */ //iterate through the file + make a counter to count up the total size of the file char str[sizeof(*input_file)] = ""; int maxSize = 0; while(fgets(str,sizeof(*input_file),input_file) != NULL) { maxSize += sizeof(*input_file); //counting up total size of the file } char finalstr[maxSize]; //initialize a single string for the whole file //iterate through the file again, this time putting the whole thing as a single string for tokenify to work with rewind(input_file); //resets fgets while(fgets(str,sizeof(*input_file),input_file) != NULL) { strcat(finalstr,str); } deleteComments(finalstr); char** tokens = tokenify(finalstr); //printf("%s",finalstr); refineToken(tokens); //print_tokens(tokens); //linked list creation struct node *head = NULL; int i = 0; while (tokens[i] != NULL) { list_append(tokens[i],&head); i++; } free_tokens(tokens); //appears to work (checked using valgrind ... --leak-check=full) //list_print(head); list_sort(&head); //CPU time ending stuff getrusage(RUSAGE_SELF, &userUsage); getrusage(RUSAGE_SELF, &systemUsage); systemEnd = systemUsage.ru_stime; userEnd = userUsage.ru_utime; float userTime = (userEnd.tv_sec + userEnd.tv_usec) - (userStart.tv_sec + userStart.tv_usec); float systemTime = (systemEnd.tv_sec + systemEnd.tv_usec) - (systemStart.tv_sec + systemStart.tv_usec); printStats(head,userTime,systemTime); list_clear(head); }
//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; }
void process_data(FILE *input_file) { // !! your code should start here. the input_file parameter // is an already-open file. you can read data from it using // the fgets() C library function. close it with the fclose() // built-in function /* Basic Algorithm 0) Open file 1) Read through each line -- fgets(). 2) Tokenify the line. Ignore comments (#) and blanklines. a) If not in comment-->if token == int --> add to link list. b) Else ignore. 3) Sort linked list. 4) Print to command line: a) Linked List b) CPU Resource Statistics (formatted) i) amount of time program spent executing in user space ii) amount of time spent executing in kernel space. */ printf("Starting..\n"); struct node *head=NULL; char line[1024]; while (fgets(line, 1024, input_file)!=NULL){ //printf("Line: "); //printf("%s", line); char ** tokens = tokenify(line); for (int i = 0; tokens[i]!=NULL; i++){ //loop through all indexes in the token...isdigt then.... int is_int = 1; for (int j=0; j<strlen(tokens[i]); j++){ if (j==0){ //check if first char in a word is negative symbol. if (tokens[i][j]=='-'){ continue; } } if (!isdigit(tokens[i][j])){ //check negative numbers... is_int=0; break; } } if (is_int){ //do not to worry if atoi=0 [can't convert] b/c we already check if its a number. int int_token = atoi(tokens[i]); list_append(int_token, &head); } } free(tokens); } printf("*** List Contents Begin ***\n"); list_print(head); list_delete(head); }
int main(int argc, char **argv) { //Establish anything we'll need constantly. int mode = 1;//Start in sequential mode. int usepath = 0;//does our path file exist? int futuremode = mode;//This keeps track of mode changes until the end of the line. int printPrompt = 0; char *prompt = "s-term> ";//The prompt string. printf("%s", prompt);//Print the prompt. fflush(stdout); //do pathstuff char **paths = readFile("shell-config"); if(paths != NULL){ usepath = 1; } char **firststep = NULL;//The array of commands made by splitting the buffer along semicolons. char ***secondstep = NULL;//The array of commands, with each command split along whitespace into its arguments. struct node *head = NULL;//The head of the linked list of ongoing jobs. char buffer[1024];//The buffer. while (1) {// struct pollfd pfd = {0, POLLIN}; if(printPrompt){ //Need to reprint the prompt. printf("%s",prompt); fflush(stdout); printPrompt = 0; } int rv = poll(&pfd, 1, 1000); if (rv==0){ //No change, use time to do other tasks struct node *anode = head; while(anode != NULL){ int pstatus = 0; int pstate = waitpid((*anode).pid,&pstatus,WNOHANG); if(pstate>0){ //Process has returned; print confirmation message and delete this node. printf("Command %s, id %i was executed.\n",(*anode).command, anode->pid); anode = (*anode).next; listDelete(pstate, &head); printPrompt = 1; } else if(pstate<0){ //Error in waitpid, print error message and break from while loop. printf("Error retrieving process status.\n"); break; } else{ //Process has not returned. anode = (*anode).next; } } } else if (rv < 0){ //Poll went horribly wrong and we're bailing out of the flaming wreckage, screaming at the tops of our lungs. printf("Polling error; shutting the (s)hell down."); } else { //Keyboard I/O if(fgets(buffer, 1024, stdin) != NULL){ mode = futuremode;//Ensure that mode is up-to-date. //Remove any comments after a hash. removeComment(buffer); //Tokenize buffer by semicolons- each will be an executable command. firststep = tokenify(buffer,";"); secondstep = tokenify2(firststep," \t\n"); //Free firststep, as it is no longer needed. Free the sub-arrays first, then the array proper. freeAll1(firststep); free(firststep); int j = 0; int futureExit = 0; int status = 0; pid_t p = 1; //Execute all commands in a loop. while(secondstep[j] != NULL && secondstep[j][0] != NULL){ //check for the special commands mode or exit. If neither of these, fork and execv. if(!strcasecmp(secondstep[j][0],"exit")){ int canwequit = 1; struct node *tmp = head; while(tmp != NULL){ if(tmp->state != 1){ canwequit = 0; } tmp = tmp->next; } if (canwequit){ futureExit = 1;//Will be checked at the end of the loop. } else { printf("Error: Jobs are currently running. Please wait for tasks to finish before exiting.\n"); } } else if(!strcasecmp(secondstep[j][0],"pause")){ setState(atoi(secondstep[j][1]), 1, head); if(kill(atoi(secondstep[j][1]), SIGSTOP) != -1){ printf("Paused process %i\n",atoi(secondstep[j][1])); } else{ printf("Something went terribly wrong\n"); } } else if(!strcasecmp(secondstep[j][0],"resume")){ setState(atoi(secondstep[j][1]), 0, head); if(kill(atoi(secondstep[j][1]), SIGCONT) != -1){ printf("Resumed process %i\n",atoi(secondstep[j][1])); } } else if(!strcasecmp(secondstep[j][0],"jobs")){ struct node *tmp = head; printf("\npid cmd paused\n"); while(tmp != NULL){ printf("%i %s %i\n",tmp->pid,tmp->command,tmp->state); tmp = tmp->next; } } /*else if(!strcasecmp(secondstep[j][0],"path")&& !strcasecmp(secondstep[j][1],"refresh")){ if(paths != NULL){ freeAll1(paths); free(paths); } //do pathstuff char **paths = readFile("shell-config"); if(paths == NULL){ usepath = 0; }else{ usepath = 1; } }*/ else if(!strcasecmp(secondstep[j][0],"MODE")){ if(secondstep[j][1] == NULL){ if(mode == 0){ printf("\nCurrent mode is parallel\n"); } else { printf("\nCurrent mode is sequential\n"); } } else if(!strcasecmp(secondstep[j][1],"PARALLEL") || !strcasecmp(secondstep[j][1],"p")){ futuremode = 0; } else if(!strcasecmp(secondstep[j][1],"SEQUENTIAL") || !strcasecmp(secondstep[j][1],"s")){ futuremode = 1; } else { //Bullshit users with their bullshit commands - throw an error. printf("\nError: Your command was pretty awful.\n"); } } else{ //Fork and execute/wait depending on process id. p = fork(); if (p == 0){ break;//Child processes handled outside the while loop. } if(mode==1){//Sequential mode. wait(&status); //Do something with childp; error checking, probably } else {//Parallel mode; add this to the list listInsert(p, secondstep[j][0], 0, &head); } } j++; } if (p == 0){ if(usepath==1){ int k = 0; while(paths[k] != NULL){ struct stat sr; char tempbuffer[1024]; strcpy(tempbuffer, paths[k]); strcat(tempbuffer, "/"); strcat(tempbuffer, secondstep[j][0]); int rv = stat(tempbuffer, &sr); if (rv < 0){ k++; } else{ secondstep[j][0]=tempbuffer; if(execv(secondstep[j][0],secondstep[j])<0){ exit(0); } } } } //Execv for an actual, non-hardcoded command. printf("\n%s\n",secondstep[j][0]); if(execv(secondstep[j][0],secondstep[j])<0){ fprintf(stderr, "Your command failed, and here's why you're a bad person: %s\n", strerror(errno)); } exit(0);//Close out the child process corpse. } //check if there was an exit command earlier if(futureExit == 1){ break; } //If we don't exit, free current buffer freeAll2(secondstep); free(secondstep); //Make sure firststep and secondstep have an assigned value in case of early termination. firststep = NULL; secondstep = NULL; printf("%s", prompt); fflush(stdout); } if(feof(stdin)){ break;//End of file or Ctrl+D } } } //on a quit, flush our command array if it's not null already if(secondstep != NULL){ freeAll2(secondstep); free(secondstep); } //Free the paths array as well. if(paths!=NULL){ freeAll1(paths); free(paths); } //Check time spent in user mode and kernel mode. Right now I've got it separated by shell and processes, but we can add it together later. int idParent = RUSAGE_SELF; int idChild = RUSAGE_CHILDREN; int statParent = 0; int statChildren = 0; struct rusage dataParent; struct rusage dataChildren; statParent = getrusage(idParent, &dataParent); statChildren = getrusage(idChild, &dataChildren); if(!statParent){//If the getrvalue operation was a success printf("Shell time in user mode: %ld.%06ld seconds.\n", dataParent.ru_utime.tv_sec, dataParent.ru_utime.tv_usec); printf("Shell time in kernel mode: %ld.%06ld seconds. \n", dataParent.ru_stime.tv_sec, dataParent.ru_stime.tv_usec); } if(!statChildren){ printf("Process time in user mode: %ld.%06ld seconds. \n", dataChildren.ru_utime.tv_sec, dataChildren.ru_utime.tv_usec); printf("Process time in kernel mode: %ld.%06ld seconds. \n", dataChildren.ru_stime.tv_sec, dataChildren.ru_stime.tv_usec); } exit(0); //Ctrl+D will drop you down here; need to make sure any cleanup also happens here too. return 0; }
int main(int argc, char **argv) { //get Input int sequential = 1; int count = 0; printf("Prompt: "); fflush(stdout); char line[1024]; for(;fgets(line, 1024, stdin) != NULL; printf("Prompt: ")) { for (int i =0; i<1024; i++){ if (line[i]=='\n'){ line[i]='\0'; } } //tokenify the line. Returns separate commands. char ** tokens = tokenify(line); int exit_terminal = 0; int mode_switch = 0; pid_t pid; for (int i=0; tokens[i]!=NULL; i++){ char ** results = parse_command(tokens[i]); int overhead_command = overhead(results, sequential); //if (overhead_command==0) do nothing. if (overhead_command > 0) { // free } if (overhead_command==1){ //exit command issued exit_terminal = 1; free(results); continue; } if (overhead_command==2){ //switch to sequential mode mode_switch = 1; continue; } if (overhead_command==3){ //switch to parallel mode_switch = 2; continue; } if (overhead_command==4){ //already printed what mode we are in continue; } pid = fork(); if (pid==0){ FILE *fp; fp = fopen("shell-config", "r"); char holder[20]; // initialize linked list to store paths struct node *head = NULL; while (fscanf(fp, "%s/n", holder) != EOF) { list_insert(holder, &head); } fclose(fp); struct node *iterator = head; struct stat statresult; int rv = stat(results[0], &statresult); //printf("%i\n", rv); // this loop checks to see if there are any path folders that may contain the command if (rv < 0){ //printf("RV not negative\n"); //printf("%s\n", iterator -> name); while (iterator != NULL){ char* name = strdup(iterator -> name); rv = stat(iterator->name, &statresult); if (rv < 0){ // not found continue; } else { results[0] = iterator -> name; } rv = stat(iterator->name, &statresult); iterator = iterator -> next; } } list_delete(head); //printf("results[0]: %s\n", results[0]); if (execv(results[0],results)<0){ printf("Process entered is wrong.\n"); exit(0); } } if (sequential) { wait(&pid); } } if (sequential == 0){ wait(&pid); } if (exit_terminal==1){ free(tokens); return 0; } if (mode_switch==1){ sequential = 1; //switch to sequential } if (mode_switch==2){ sequential = 0; //switch to parallel } count ++; } return 0; }