diff options
| author | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-16 00:44:15 +0200 |
|---|---|---|
| committer | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-16 00:44:15 +0200 |
| commit | 5ed50ce747e44fac94ff882b46d5271a8ac6420f (patch) | |
| tree | 242ef51f9afabb3715c7a313517d2f980817e207 /exec.c | |
| parent | cb385f96ef7caa1ae9652c498ae8458c30b3cf32 (diff) | |
got it working on simple cmds
Diffstat (limited to 'exec.c')
| -rw-r--r-- | exec.c | 99 |
1 files changed, 94 insertions, 5 deletions
@@ -6,6 +6,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <signal.h> @@ -134,7 +136,10 @@ void merge_strvecs(StrVec* target, StrVec* source) { } } -void command_thing(Command command, ShellState* shstate) { + + + +char** make_cmd_args(Command command, ShellState* shstate) { StrVec arg_str_vec = make_StrVec(256); for (int i = 0; i < command.args.count; i++) { Token arg_i = *get_from_TokenVec(&command.args, i); @@ -149,30 +154,114 @@ void command_thing(Command command, ShellState* shstate) { } } int argcount = arg_str_vec.count; - char** arg_str_arr = malloc(sizeof(char*) * argcount); + char** arg_str_arr = malloc(sizeof(char*) * (argcount + 1)); for (int j = 0; j < argcount; j++) { arg_str_arr[j] = *get_from_StrVec(&arg_str_vec, j); } + arg_str_arr[argcount] = NULL; for (int k = 0; k < argcount; k++) { printf("\t\tArg%d: %s\n", k, arg_str_arr[k]); } + return arg_str_arr; } -DECLARE_VEC(int, IntVec) +DECLARE_VEC(int, IntVec) + typedef struct { + char** args; int stdin_fd; int stdout_fd; -} CommandProcessInfo; + IntVec child_close_fds; + IntVec parent_close_fds; +} ExecutableCommand; + + +void execute_command(ExecutableCommand cmd, int* pgid) { + printf("Stdin: %d vs %d. Stdout: %d vs %d.", cmd.stdin_fd, STDIN_FILENO, cmd.stdout_fd, STDOUT_FILENO); + for (int j = 0; cmd.args[j] != NULL; j++) { + printf("'%s'\n", cmd.args[j]); + } + pid_t pid = fork(); + + if (pid == 0) { + if (*pgid == -1) { + setpgid(0, 0); + } else { + setpgid(0, *pgid); + } + + dup2(cmd.stdin_fd, STDIN_FILENO); + dup2(cmd.stdout_fd, STDOUT_FILENO); + + for (int i = 0; i < cmd.child_close_fds.count; i++) { + close(*get_from_IntVec(&cmd.child_close_fds, i)); + } + + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGTTIN, SIG_DFL); + signal(SIGTTOU, SIG_DFL); + + execvp(cmd.args[0], cmd.args); + exit(67); + } + + if (*pgid == -1) { + setpgid(pid, pid); + *pgid = pid; + } else { + setpgid(pid, *pgid); + } +} void run_pipeline(Pipeline pl, ShellState* shstate) { + signal(SIGTTIN, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + + int last_pipe_fd; + int pgid = -1; for (int i = 0; i < pl.count; i++) { printf("\tCommand %d:\n", i); - command_thing(get_from_Pipeline(&pl, i)->cmd, shstate); + PipelineElement elem = *get_from_Pipeline(&pl, i); + + ExecutableCommand cmd = {.child_close_fds = make_IntVec(64), .parent_close_fds = make_IntVec(64)}; + cmd.args = make_cmd_args(elem.cmd, shstate); + + if (i == 0) { + cmd.stdin_fd = STDIN_FILENO; + } else { + cmd.stdin_fd = last_pipe_fd; + push_to_IntVec(&cmd.child_close_fds, last_pipe_fd); + push_to_IntVec(&cmd.parent_close_fds, last_pipe_fd); + } + + if (elem.conn == CONN_PIPE) { + int pipe_fds[2]; + pipe(pipe_fds); + cmd.stdout_fd = pipe_fds[1]; + push_to_IntVec(&cmd.child_close_fds, pipe_fds[1]); + push_to_IntVec(&cmd.parent_close_fds, pipe_fds[1]); + last_pipe_fd = pipe_fds[0]; + } else { + cmd.stdout_fd = STDOUT_FILENO; + } + + execute_command(cmd, &pgid); + + for (int j = 0; j < cmd.parent_close_fds.count; j++) { + printf("Closing %d\n", j); + close(*get_from_IntVec(&cmd.parent_close_fds, j)); + } } + tcsetpgrp(STDIN_FILENO, pgid); + while (waitpid(-pgid, NULL, 0) > 0); + printf("%d\n", pgid); + tcsetpgrp(STDIN_FILENO, getpgrp()); } |
