progress: make gmsh great again

This commit is contained in:
2026-01-07 20:02:39 +09:00
parent db1e2c2364
commit 7f6de0567a
7 changed files with 442 additions and 231 deletions
+57 -174
View File
@@ -9,122 +9,62 @@
#include <fcntl.h>
#include <stdbool.h>
#include "para.h"
#include "builtin.h"
#include "para.h"
#include "job.h"
job_t *parse_line(char *line);
void launch_job(job_t *job);
static bool verbose = false;
volatile pid_t fg_pgid = 0;
int parse_cmd(char *cmd, char *argv[]) {
int argc = 0;
char *ptr = cmd;
char *token_start;
char quote_char = 0;
while (*ptr) {
while (*ptr == ' ' && quote_char == 0) ptr++;
if (*ptr == '\0') break;
token_start = ptr;
char *write_ptr = ptr;
while (*ptr) {
if (quote_char == 0 && *ptr == ' ') {
ptr++;
break;
}
if (*ptr == '"' || *ptr == '\'') {
if (quote_char == *ptr) quote_char = 0;
else if (quote_char == 0) quote_char = *ptr;
else *write_ptr++ = *ptr;
}
else {
*write_ptr++ = *ptr;
}
ptr++;
}
*write_ptr = '\0';
argv[argc++] = token_start;
if (argc >= MAX_ARGS - 1) break;
}
argv[argc] = NULL;
return argc;
void handle_sigint(int sig) {
printf("\n");
}
// 반환값: 1(처리함), 0(파이프 없음)
int handle_pipe(char *argv[]) {
int pipe_idx = -1;
for (int i = 0; argv[i] != NULL; i++) {
if (strcmp(argv[i], "|") == 0) {
pipe_idx = i;
break;
}
}
if (pipe_idx == -1) return 0;
argv[pipe_idx] = NULL;
char **left_cmd = &argv[0];
char **right_cmd = &argv[pipe_idx + 1];
if (right_cmd[0] == NULL) {
printf("gmsh: syntax error near unexpected token `|'\n");
return 1;
}
int fds[2];
if (pipe(fds) == -1) {
perror("pipe");
return 1;
}
pid_t pid1 = fork();
if (pid1 == 0) {
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
handle_redirection((const char**) left_cmd);
execvp(left_cmd[0], left_cmd);
perror("execvp left");
exit(1);
}
pid_t pid2 = fork();
if (pid2 == 0) {
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
if (handle_pipe(right_cmd) == 1) {
exit(0);
}
else {
handle_redirection((const char**) right_cmd);
execvp(right_cmd[0], right_cmd);
perror("execvp right");
exit(1);
}
}
close(fds[0]);
close(fds[1]);
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
return 1; // 처리 완료
void handle_sigchld(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int builtin_cmd(job_t *job) {
command_t *cmd = job->head;
if (!cmd || !cmd->argv[0]) return 0;
// if (strcmp(cmd->argv[0], "exit") == 0) exit(0);
// if (strcmp(cmd->argv[0], "cd") == 0) {
// if (cmd->argc < 2) fprintf(stderr, "cd: missing argument\n");
// else if (chdir(cmd->argv[1]) != 0) perror("cd");
// return 1;
// }
bool ret = 0;
if (strcmp(cmd->argv[0], "exit") == 0) exit(0), ret = 1;
else if (strcmp(cmd->argv[0], "ls") == 0) cmd_ls(cmd->argv[1]), ret = 1;
else if (strcmp(cmd->argv[0], "cd") == 0) cmd_cd(cmd->argv[1]), ret = 1;
else if (strcmp(cmd->argv[0], "pwd") == 0) cmd_pwd(), ret = 1;
// else if (strcmp(cmd->argv[0], "cat") == 0) cmd_cat(argc, (const char**) argv);
// else if (strcmp(cmd->argv[0], "proc") == 0) cmd_proc();
// else if (strcmp(cmd->argv[0], "echo") == 0) cmd_echo(argc, (const char**) argv);
else if (strcmp(cmd->argv[0], "size") == 0) cmd_size(), ret = 1;
else if (strcmp(cmd->argv[0], "resize") == 0){
if(cmd->argc != 3){
printf("Usage: resize <rows> <cols>\n");
}
else cmd_resize(cmd->argv[1], cmd->argv[2]);
ret = 1;
}
else if (strcmp(cmd->argv[0], "poweroff") == 0) cmd_poweroff(), ret = 1;
else if (strcmp(cmd->argv[0], "reboot") == 0) cmd_reboot(), ret = 1;
else if (strcmp(cmd->argv[0], "help") == 0) cmd_help(), ret = 1;
return ret;
}
void run_shell() {
char cmd_buf[MAX_CMD_LEN];
char *args[MAX_ARGS];
char cwd[1024];
while (1) {
@@ -136,82 +76,23 @@ void run_shell() {
cmd_buf[strcspn(cmd_buf, "\n")] = 0;
if (strlen(cmd_buf) == 0) continue;
// int argc = 0;
// args[argc] = strtok(cmd_buf, " ");
// while (args[argc] != NULL && argc < MAX_ARGS - 1) args[++argc] = strtok(NULL, " ");
job_t *job = parse_line(cmd_buf);
if (job == NULL) continue;
int argc = parse_cmd(cmd_buf, args);
if (argc == 0) continue;
if (handle_pipe(args)) {
if (builtin_cmd(job)) {
free_job(job);
continue;
}
if (verbose) {
printf("[debug] argc: %d\n", argc);
for(int i=0; i<argc; i++) printf("[debug] argv[%d]: '%s'\n", i, args[i]);
}
if (strcmp(args[0], "exit") == 0) exit(0);
else if (strcmp(args[0], "ls") == 0) cmd_ls(args[1]);
else if (strcmp(args[0], "cd") == 0) cmd_cd(args[1]);
else if (strcmp(args[0], "pwd") == 0) cmd_pwd();
// else if (strcmp(args[0], "cat") == 0) cmd_cat(argc, (const char**) args);
// else if (strcmp(args[0], "proc") == 0) cmd_proc();
// else if (strcmp(args[0], "echo") == 0) cmd_echo(argc, (const char**) args);
else if (strcmp(args[0], "size") == 0) cmd_size();
else if (strcmp(args[0], "resize") == 0){
if(argc != 3){
printf("Usage: resize <rows> <cols>\n");
}
else cmd_resize(args[1], args[2]);
}
else if (strcmp(args[0], "poweroff") == 0) cmd_poweroff();
else if (strcmp(args[0], "reboot") == 0) cmd_reboot();
else if (strcmp(args[0], "help") == 0) cmd_help();
else {
pid_t pid = fork();
// if (pid == 0) {
// execvp(args[0], args);
// printf("%s: command not found\n", args[0]);
// exit(1);
// } else wait(NULL);
if (pid == 0) {
handle_redirection((const char**) args);
execvp(args[0], args);
fprintf(stderr, "%s: command not found\n", args[0]);
exit(127);
} else if (pid > 0) {
int status;
if (verbose) {
printf("[debug] Spawned child PID: %d\n", pid);
}
waitpid(pid, &status, 0);
if (verbose) {
if (WIFEXITED(status)) {
printf("[debug] Process %d exited with code %d\n", pid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("[debug] Process %d killed by signal %d\n", pid, WTERMSIG(status));
}
}
} else {
perror("fork");
}
}
launch_job(job);
if (!job->is_bg) free_job(job);
}
}
int main(int argc, char** argv) {
printf("GMSH (GMS Minimal SHell) v1.0 initialized.\n");
signal(SIGINT, handle_sigint);
signal(SIGCHLD, handle_sigchld);
signal(SIGTTOU, SIG_IGN);
int opt;
while ((opt = getopt(argc, argv, "v")) != -1) {
@@ -225,7 +106,9 @@ int main(int argc, char** argv) {
exit(1);
}
}
if(verbose) printf("GMSH (GMS Minimal SHell) v1.0 initialized.\n");
run_shell();
return 0;
}