summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit5ed50ce747e44fac94ff882b46d5271a8ac6420f (patch)
tree242ef51f9afabb3715c7a313517d2f980817e207
parentcb385f96ef7caa1ae9652c498ae8458c30b3cf32 (diff)
got it working on simple cmds
-rw-r--r--exec.c99
1 files changed, 94 insertions, 5 deletions
diff --git a/exec.c b/exec.c
index 9d791fb..636edf4 100644
--- a/exec.c
+++ b/exec.c
@@ -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());
}