Why was I dumb? #1
					 8 changed files with 401 additions and 4 deletions
				
			
		|  | @ -6,7 +6,8 @@ struct node* parse_csv(char* name) { | |||
|   file = fopen(name, "r"); | ||||
|   if(!file) { | ||||
|     perror("Error"); | ||||
|     exit(66); | ||||
|     printf("\n"); | ||||
|     return NULL; | ||||
| 
 | ||||
|   } | ||||
| // Buffer File For chars
 | ||||
|  | @ -35,7 +36,7 @@ struct node* parse_csv(char* name) { | |||
|   free(buffer); | ||||
|   fclose(file); | ||||
| 
 | ||||
|   printf("Processed file %s and processed data for %d movies.\n\n", name, count_nodes(head)); | ||||
|   printf("Processed file %s and processed data for %d movies.\n", name, count_nodes(head)); | ||||
| 
 | ||||
|   return head; | ||||
| 
 | ||||
|  |  | |||
|  | @ -92,11 +92,14 @@ void choose_movie(char* dir_str) { | |||
|   //printf("\nDirectory: %s\n", dir_str);
 | ||||
|   struct node* head = parse_csv(dir_str); | ||||
| 
 | ||||
|   if(!head) | ||||
|     return; | ||||
| 
 | ||||
|   // Generate the String for movies
 | ||||
|   char* dir = malloc(sizeof(char)*100); | ||||
|   sprintf(dir, "temp.movies.%d", rand() % 100000); | ||||
| 
 | ||||
|   printf("Created directory with the name %s\n", dir); | ||||
|   printf("Created directory with the name %s\n\n", dir); | ||||
|   print_csv(head, dir); | ||||
| 
 | ||||
|   free(dir_str); | ||||
|  | @ -132,6 +135,9 @@ void index_nodes(int* val, void* head) { | |||
| 
 | ||||
| void print_csv(struct node* head, char* dir) { | ||||
| 
 | ||||
|   if(!head) | ||||
|     return; | ||||
| 
 | ||||
|   int result = mkdir(dir, 0750); | ||||
| 
 | ||||
|   chdir(dir); | ||||
|  |  | |||
|  | @ -34,5 +34,5 @@ make run | |||
| To specify a CSV file, you can type: | ||||
| 
 | ||||
| ``` | ||||
| ./movies_by_year $(CSV_File_to_read.csv) | ||||
| ./movies_by_year  | ||||
| ``` | ||||
|  |  | |||
							
								
								
									
										265
									
								
								smallsh/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								smallsh/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,265 @@ | |||
| #include "main.h" | ||||
| 
 | ||||
| volatile sig_atomic_t stop_flag = 0; | ||||
| int stop_msg = 0; | ||||
| 
 | ||||
| int main() { | ||||
| 
 | ||||
|   /*
 | ||||
|   struct sigaction sa; | ||||
|     sa.sa_handler = sigstop_handle; | ||||
|     sa.sa_flags = 0; | ||||
|     sigemptyset(&sa.sa_mask); | ||||
|     */ | ||||
| 
 | ||||
|   signal(SIGINT, sigint_handle); | ||||
|   signal(SIGTSTP, sigstop_handle); | ||||
| 
 | ||||
|   int status = 0; | ||||
|   size_t input_size = 2048; | ||||
|   size_t getline_len; | ||||
|   char* input = malloc(sizeof(char) * input_size); | ||||
| 
 | ||||
|   while(1) { | ||||
| 
 | ||||
|     clean_children(); | ||||
| 
 | ||||
|     //signal handling
 | ||||
|     if(stop_msg) { | ||||
|       if(stop_flag)  | ||||
|         printf("Entering Stop Mode: Background Processes Do Not Work (&)\n"); | ||||
|       else  | ||||
|         printf("Exiting Stop Mode: Background Processes Now Work (&)\n"); | ||||
|       stop_msg = 0; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     printf(": "); | ||||
|     fflush(stdout); | ||||
|     getline_len = getline(&input, &input_size, stdin); | ||||
|     input[getline_len - 1] = '\0'; | ||||
| 
 | ||||
|     expand_dollar(input, input_size); | ||||
| 
 | ||||
|     // Ignore whitespace or comments
 | ||||
|     if(input[0] == '\0' || | ||||
|        input[0] == '#') { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     char*** array = malloc(sizeof(char**)); | ||||
|     int num_strings = input_format(input, input_size, array); | ||||
| 
 | ||||
|     char* first_array = (*array)[0]; | ||||
| 
 | ||||
|     // Built in shell commands
 | ||||
|     if(!strncmp(first_array, "exit", 4)) | ||||
|         return 0; | ||||
|     else if(!strncmp(first_array, "cd", 2)) | ||||
|       inbuilt_cd((*array)[1]); | ||||
|     else if (!strncmp(first_array, "status", 6)) | ||||
|       printf("%d\n", status); | ||||
|     else | ||||
|       status = run_command(array, num_strings); | ||||
|     fflush(stdout); | ||||
| 
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int input_format(char* input, size_t input_size, char*** array) { | ||||
| 
 | ||||
|   const int max_args = 512; | ||||
|   int num_strings = 0; | ||||
|   char* pch; | ||||
|   *array = malloc(sizeof(char*) * max_args); | ||||
| 
 | ||||
|   pch = strtok (input," "); | ||||
|   while (pch != NULL) | ||||
|   { | ||||
|     (*array)[num_strings] = malloc(sizeof(char*) * (strlen(pch) + 1)); | ||||
|     strcpy((*array)[num_strings], pch); | ||||
|     num_strings++; | ||||
| 
 | ||||
|     pch = strtok (NULL, " "); | ||||
|   } | ||||
| 
 | ||||
|   return num_strings; | ||||
| } | ||||
| 
 | ||||
| void inbuilt_cd(char* args) { | ||||
| 
 | ||||
|   if(args) | ||||
|     chdir(args); | ||||
|   else | ||||
|     chdir(getenv("HOME")); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| int run_command(char*** array, int num_array) { | ||||
| 
 | ||||
|   char* comb_string = malloc(sizeof(char) * 100); | ||||
|   sprintf(comb_string, "/usr/bin/"); | ||||
|   strcat(comb_string, (*array)[0]); | ||||
| 
 | ||||
| 
 | ||||
|   //Check to see if the process is ran in the background
 | ||||
|   int background = 0;  | ||||
|   if(!strncmp("&", (*array)[num_array - 1], 1)) { | ||||
|     if(!stop_flag) | ||||
|       background = 1; | ||||
|     (*array)[num_array - 1] = NULL; | ||||
|   } | ||||
| 
 | ||||
|   // Check to see if the process has output redirected
 | ||||
|   int redirect_o = 0; | ||||
|   char* redirect_o_str = NULL; | ||||
|   for(int i = 0; i < num_array; i++) { | ||||
| 
 | ||||
|     if((*array)[i] == NULL) | ||||
|       continue; | ||||
| 
 | ||||
|     if(!strncmp((*array)[i], ">", 1)) { | ||||
|       redirect_o = 1; | ||||
|       redirect_o_str = (*array)[i+1]; | ||||
| 
 | ||||
|       (*array)[i] = NULL; | ||||
|       (*array)[i+1] = NULL; | ||||
| 
 | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   sterilize_array(array, num_array); | ||||
| 
 | ||||
|   // Check to see if the process has input redirected
 | ||||
|   int redirect_i = 0; | ||||
|   char* redirect_i_str = NULL; | ||||
|   for(int i = 0; i < num_array; i++) { | ||||
| 
 | ||||
|     if((*array)[i] == NULL) | ||||
|       continue; | ||||
| 
 | ||||
|     if(!strncmp((*array)[i], "<", 1)) { | ||||
|       redirect_i = 1; | ||||
|       redirect_i_str = (*array)[i+1]; | ||||
| 
 | ||||
|       (*array)[i] = NULL; | ||||
|       (*array)[i+1] = NULL; | ||||
| 
 | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   sterilize_array(array, num_array); | ||||
| 
 | ||||
|   int f = fork(); | ||||
|   pid_t pid; | ||||
|   if(!f) { | ||||
|     if(redirect_o) { | ||||
|       int fd = open(redirect_o_str, O_WRONLY | O_CREAT, 0666); | ||||
|       dup2(fd, STDOUT_FILENO); | ||||
|       dup2(fd, STDERR_FILENO); | ||||
| 
 | ||||
|     } | ||||
|     else if(background) { | ||||
|       int fd = open("/dev/null", O_WRONLY, 0666); | ||||
|       //Direct to dev null
 | ||||
|       dup2(fd, STDOUT_FILENO); | ||||
|       dup2(fd, STDERR_FILENO); | ||||
|     } | ||||
| 
 | ||||
|     if(redirect_i) { | ||||
|       int fd = open(redirect_i_str, O_RDONLY); | ||||
|       dup2(fd, STDIN_FILENO); | ||||
|     } | ||||
|     else if(background) { | ||||
|       int fd = open("/dev/null", O_RDONLY); | ||||
|       dup2(fd, STDIN_FILENO); | ||||
|     } | ||||
| 
 | ||||
|     pid = execv(comb_string, (*array)); | ||||
| 
 | ||||
|     perror(comb_string); | ||||
|     exit(1); | ||||
|   } | ||||
|   else if(background){ | ||||
|     printf("background pid is %d\n", f); | ||||
|   } | ||||
| 
 | ||||
|   int status; | ||||
|   if(!background) | ||||
|     waitpid(f, &status, 0); | ||||
| 
 | ||||
|   free(comb_string); | ||||
| 
 | ||||
|   return status; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void expand_dollar(char* input, size_t input_size) { | ||||
| 
 | ||||
|   char pid[20]; | ||||
|   int pid_size = sprintf(pid, "%d", getpid()); | ||||
|   char* buffer = malloc(sizeof(char*) * (pid_size + input_size + 1)); | ||||
| 
 | ||||
|   char* dollar; | ||||
| 
 | ||||
|   dollar = strstr(input, "$$"); | ||||
|   while(dollar != NULL) { | ||||
| 
 | ||||
|   dollar[0] = '%'; | ||||
|   dollar[1] = 's'; | ||||
|   sprintf(buffer, input, pid); | ||||
|   strcpy(input, buffer); | ||||
|   dollar = strstr(input, "$$"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void sterilize_array(char*** array, size_t num_array) { | ||||
| 
 | ||||
|   for(int i = 0; i < num_array; i++) { | ||||
| 
 | ||||
|     //check to see if it can be the end of the array
 | ||||
|     if((*array)[i] == NULL) { | ||||
|       int is_end = 1; | ||||
|       //check if there is any more non-null values in the array
 | ||||
|       for(int j = i; j < num_array; j++) { | ||||
|         if((*array)[j]) | ||||
|           is_end = 0; | ||||
|       } | ||||
| 
 | ||||
|       if(!is_end) { | ||||
| 
 | ||||
|         //shift the array by 1 bit
 | ||||
|         for(int j = i; j < num_array; j++) { | ||||
|           (*array)[j] = (*array)[j+1]; | ||||
| 
 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void sigint_handle() { | ||||
| } | ||||
| 
 | ||||
| void sigstop_handle(int n) { | ||||
|   stop_flag = !stop_flag; | ||||
|   stop_msg = !stop_msg; | ||||
| } | ||||
| 
 | ||||
| void clean_children() { | ||||
| 
 | ||||
|   // Clean up any child process that has not been cleaned
 | ||||
|   int pid = 43110; | ||||
|   while(pid >0) { | ||||
|     int status; | ||||
|     pid = waitpid(0, &status, WNOHANG); | ||||
| 
 | ||||
|     if(pid > 0) | ||||
|       printf("\nbackground pid %d is done: exit value %d\n", pid, WEXITSTATUS(status)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										22
									
								
								smallsh/main.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								smallsh/main.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| 
 | ||||
| #ifndef MAIN | ||||
| #define MAIN | ||||
| 
 | ||||
| #include "stdlib.h" | ||||
| #include "stdio.h" | ||||
| #include "string.h" | ||||
| #include "unistd.h" | ||||
| #include "sys/wait.h" | ||||
| #include "fcntl.h" | ||||
| #include "signal.h" | ||||
| 
 | ||||
| int input_format(char*, size_t, char***); | ||||
| void inbuilt_cd(char*); | ||||
| int run_command(char***, int); | ||||
| void expand_dollar(char*, size_t); | ||||
| void sterilize_array(char***, size_t); | ||||
| void sigint_handle(); | ||||
| void sigstop_handle(); | ||||
| void clean_children(); | ||||
| 
 | ||||
| #endif  | ||||
							
								
								
									
										17
									
								
								smallsh/makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								smallsh/makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| CC=gcc --std=gnu99 -g | ||||
| output=smallsh | ||||
| 
 | ||||
| all: main.c main.h node.o input.o | ||||
| 	$(CC) main.c node.o input.o -o $(output) | ||||
| 
 | ||||
| node.o: node.c node.h | ||||
| 	$(CC) -c node.c -o node.o | ||||
| 
 | ||||
| input.o: input.h input.c | ||||
| 	$(CC) -c input.c -o input.o | ||||
| 
 | ||||
| test: all | ||||
| 	./p3testscript | ||||
| 
 | ||||
| clean: | ||||
| 	rm -fr *.o vgcore.* $(output) | ||||
							
								
								
									
										62
									
								
								smallsh/node.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								smallsh/node.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| 
 | ||||
| #include "node.h" | ||||
| 
 | ||||
| void append_node(struct node* head, struct node* node_app) { | ||||
| 	 | ||||
|   if(!head) { | ||||
|     head = node_app; | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   struct node* temp = head; | ||||
| 
 | ||||
|   while(temp->node != NULL) { | ||||
|     temp = temp->node; | ||||
|   } | ||||
|   temp->node = node_app; | ||||
|    | ||||
| }  | ||||
| 
 | ||||
| struct node* appendv_node(struct node* head, void* data) { | ||||
| 
 | ||||
|   struct node* node = malloc(sizeof(struct node)); | ||||
|   node->data = data; | ||||
|   node->node = NULL; | ||||
| 
 | ||||
|   append_node(head, node); | ||||
| 
 | ||||
|   return node; | ||||
| } | ||||
| 
 | ||||
| int count_nodes(struct node* head) { | ||||
| 
 | ||||
|   int num = 1; | ||||
| 
 | ||||
|   if(!head) | ||||
|     return -1; | ||||
| 
 | ||||
|   struct node* temp = head; | ||||
|   while(temp->node) { | ||||
| 
 | ||||
|     temp = temp->node; | ||||
|     num++; | ||||
|   } | ||||
|    | ||||
|   return num; | ||||
| } | ||||
| 
 | ||||
| void iterate_nodes(struct node* head, void *func (void*, void*), void* val) { | ||||
| 
 | ||||
|   if(!head) | ||||
|     return; | ||||
| 
 | ||||
|   func(head->data, val); | ||||
| 
 | ||||
|   struct node* temp = head; | ||||
| 
 | ||||
|   while(temp->node) { | ||||
|     temp = temp->node; | ||||
|     func(temp->data, val); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										24
									
								
								smallsh/node.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								smallsh/node.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| #include "stdlib.h" | ||||
| 
 | ||||
| #ifndef NODES | ||||
| #define NODES | ||||
| 
 | ||||
| struct node { | ||||
|   struct node* node; | ||||
|   void* data; | ||||
| }; | ||||
| 
 | ||||
| // Appends Node to list
 | ||||
| void append_node(struct node*, struct node*); | ||||
| 
 | ||||
| // Creates node with value and appends
 | ||||
| // Returns node that was created
 | ||||
| struct node* appendv_node(struct node*, void*); | ||||
| 
 | ||||
| // Counts the number of nodes in a list
 | ||||
| int count_nodes(struct node*); | ||||
| 
 | ||||
| // Iterates over every node in a list and runs the given function
 | ||||
| void iterate_nodes(struct node*, void *func(void*, void*), void*); | ||||
| 
 | ||||
| #endif | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue