Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
0
//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;
}
Exemple #4
0
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.);
}
Exemple #5
0
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;
}
Exemple #6
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;
}
Exemple #7
0
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;
}
Exemple #8
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);
}
Exemple #9
0
/* 
 * 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;
}
Exemple #10
0
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;
}
Exemple #12
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++;
	}
Exemple #13
0
/* 
 * 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));
            }
        }
    }
}
Exemple #14
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

	//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;
}
Exemple #16
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);

}
Exemple #17
0
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;
}
Exemple #18
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;
}