#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#define BUFFER_SIZE 1024
#define TOKEN_DELIMITERS " \t\r\n\a"
void execute_command(char **args) {
pid_t pid, wpid;
int status;
pid = fork();
if (pid == 0) {
// 子进程
if (execvp(args[0], args) == -1) {
perror("execvp");
}
exit(EXIT_FAILURE);
} else if (pid < 0) {
// fork 失败
perror("fork");
} else {
// 父进程
do {
wpid = waitpid(pid, &status, WUNTRACED);
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
}
}
char **parse_command(char *command) {
int buffer_size = BUFFER_SIZE;
int position = 0;
char **tokens = malloc(buffer_size * sizeof(char *));
char *token;
if (!tokens) {
fprintf(stderr, "Allocation error\n");
exit(EXIT_FAILURE);
}
token = strtok(command, TOKEN_DELIMITERS);
while (token != NULL) {
tokens[position] = token;
position++;
if (position >= buffer_size) {
buffer_size += BUFFER_SIZE;
tokens = realloc(tokens, buffer_size * sizeof(char *));
if (!tokens) {
fprintf(stderr, "Allocation error\n");
exit(EXIT_FAILURE);
}
}
token = strtok(NULL, TOKEN_DELIMITERS);
}
tokens[position] = NULL;
return tokens;
}
void shell_loop() {
char *command;
char **args;
int status;
do {
printf("> ");
command = malloc(BUFFER_SIZE * sizeof(char));
if (!command) {
fprintf(stderr, "Allocation error\n");
exit(EXIT_FAILURE);
}
if (fgets(command, BUFFER_SIZE, stdin) == NULL) {
printf("\n");
break;
}
args = parse_command(command);
execute_command(args);
free(command);
free(args);
} while (status);
}
int main() {
shell_loop();
return 0;
}