Untitled
unknown
plain_text
a year ago
4.8 kB
4
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