Untitled
unknown
plain_text
a year ago
4.8 kB
3
Indexable
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> #define MAX_INPUT_SIZE 1024 #define MAX_ARG_SIZE 100 // Function prototypes void execute_command(char *command); int handle_builtin(char **args); void update_path(char *operation, char *dir); void redirect_io(char **args, int *in_redir, int *out_redir); char *find_command(char *command); // Global variable to store the custom path environment char *path_env[MAX_ARG_SIZE]; int path_count = 0; int main() { char input[MAX_INPUT_SIZE]; path_env[0] = NULL; // Initialize path environment to empty while (1) { // Display prompt printf("myshell> "); fflush(stdout); // Read user input if (fgets(input, MAX_INPUT_SIZE, stdin) == NULL) { perror("fgets failed"); exit(1); } // Remove newline character input[strcspn(input, "\n")] = '\0'; // Execute the command execute_command(input); } return 0; } void execute_command(char *input) { char *args[MAX_ARG_SIZE]; char *token; int i = 0; int in_redir = -1, out_redir = -1; // Tokenize the input into arguments token = strtok(input, " "); while (token != NULL) { args[i++] = token; token = strtok(NULL, " "); } args[i] = NULL; // Handle built-in commands if (handle_builtin(args)) { return; } // Handle I/O redirection redirect_io(args, &in_redir, &out_redir); // Find the command in the custom path environment char *cmd_path = find_command(args[0]); if (cmd_path == NULL) { printf("Command not found: %s\n", args[0]); return; } // Fork and execute the command pid_t pid = fork(); if (pid < 0) { perror("fork failed"); exit(1); } else if (pid == 0) { if (in_redir != -1) { dup2(in_redir, STDIN_FILENO); close(in_redir); } if (out_redir != -1) { dup2(out_redir, STDOUT_FILENO); close(out_redir); } execv(cmd_path, args); perror("execv failed"); exit(1); } else { wait(NULL); } } int handle_builtin(char **args) { if (strcmp(args[0], "cd") == 0) { if (args[1] == NULL) { fprintf(stderr, "cd: missing argument\n"); } else if (chdir(args[1]) != 0) { perror("chdir failed"); } return 1; } else if (strcmp(args[0], "path") == 0) { if (args[1] == NULL) { for (int i = 0; i < path_count; i++) { printf("%s:", path_env[i]); } printf("\n"); } else { if (args[1][0] == '+') { update_path("+", args[1] + 1); } else if (args[1][0] == '-') { update_path("-", args[1] + 1); } else { fprintf(stderr, "path: invalid argument\n"); } } return 1; } else if (strcmp(args[0], "quit") == 0) { exit(0); } return 0; } void update_path(char *operation, char *dir) { if (strcmp(operation, "+") == 0) { path_env[path_count++] = strdup(dir); } else if (strcmp(operation, "-") == 0) { for (int i = 0; i < path_count; i++) { if (strcmp(path_env[i], dir) == 0) { free(path_env[i]); for (int j = i; j < path_count - 1; j++) { path_env[j] = path_env[j + 1]; } path_env[--path_count] = NULL; break; } } } } void redirect_io(char **args, int *in_redir, int *out_redir) { for (int i = 0; args[i] != NULL; i++) { if (strcmp(args[i], "<") == 0) { *in_redir = open(args[i + 1], O_RDONLY); if (*in_redir == -1) { perror("open failed"); exit(1); } args[i] = NULL; } else if (strcmp(args[i], ">") == 0) { *out_redir = open(args[i + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644); if (*out_redir == -1) { perror("open failed"); exit(1); } args[i] = NULL; } } } char *find_command(char *command) { char *cmd_path = malloc(MAX_INPUT_SIZE); for (int i = 0; i < path_count; i++) { snprintf(cmd_path, MAX_INPUT_SIZE, "%s/%s", path_env[i], command); if (access(cmd_path, X_OK) == 0) { return cmd_path; } } free(cmd_path); return NULL; }
Editor is loading...
Leave a Comment