#include #include #include #include #include #include "syntax.h" void execute_cmd(ExecutableCommand cmd, int* pgid) { printf("Ok\n"); fflush(stdout); 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.redirects.count; i++) { FdRedirect fd_rd = *get_from_FdRedirectVec(&cmd.redirects, i); dup2(fd_rd.to, fd_rd.redirected); } 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); } } ExecutableCommand process_pl_command(PlCommand pl_cmd) { StrVec arg_vec = make_StrVec(256); for (int i = 0; i < pl_cmd.args.count; i++) { Arg arg = *get_from_ArgVec(&pl_cmd.args, i); switch (arg.kind) { case ARG_LIT: push_to_StrVec(&arg_vec, arg.as.lit_str); break; default: exit(67); } } FdRedirectVec fd_redirs = make_FdRedirectVec(256); IntVec open_fds = make_IntVec(256); for (int j = 0; j < pl_cmd.redirects.count; j++) { Redirect redir = *get_from_RedirectVec(&pl_cmd.redirects, j); FdRedirect fd_redir; int fd; switch (redir.kind) { case REDIR_READ: fd = open(redir.as.filename, O_RDONLY, 0644); push_to_IntVec(&open_fds, fd); fd_redir = (FdRedirect){.to = fd, .redirected = STDIN_FILENO}; break; case REDIR_WRITE_APPEND: fd = open(redir.as.filename, O_WRONLY | O_CREAT | O_APPEND, 0644); push_to_IntVec(&open_fds, fd); fd_redir = (FdRedirect){.to = fd, .redirected = STDOUT_FILENO}; break; case REDIR_WRITE_TRUNC: fd = open(redir.as.filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); push_to_IntVec(&open_fds, fd); fd_redir = (FdRedirect){.to = fd, .redirected = STDOUT_FILENO}; break; default: exit(67); } push_to_FdRedirectVec(&fd_redirs, fd_redir); } char** args = malloc(sizeof(char*) * (arg_vec.count + 1)); for (int i = 0; i < arg_vec.count; i++) { args[i] = *get_from_StrVec(&arg_vec, i); } args[arg_vec.count] = NULL; return (ExecutableCommand){.args = args, .redirects = fd_redirs, .open_fds = open_fds}; } void execute_command_pipeline(Pipeline pipeline) { int trunk_fd = STDIN_FILENO; int pgid = -1; printf("Starting pipeline of length %d\n", pipeline.count); fflush(stdout); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); for (int i = 0; i < pipeline.count; i++) { printf("Processing cmd %d\n", i); fflush(stdout); PlCommand cmd = *get_from_Pipeline(&pipeline, i); ExecutableCommand exec_cmd = process_pl_command(cmd); exec_cmd.stdin_fd = trunk_fd; exec_cmd.stdout_fd = STDOUT_FILENO; if (cmd.conn == CONN_PIPE) { int pipe_fds[2]; pipe(pipe_fds); exec_cmd.stdout_fd = pipe_fds[1]; push_to_IntVec(&exec_cmd.open_fds, pipe_fds[1]); trunk_fd = pipe_fds[0]; } execute_cmd(exec_cmd, &pgid); for (int j = 0; j < exec_cmd.open_fds.count; j++) { int fd = *get_from_IntVec(&exec_cmd.open_fds, j); close(fd); } } tcsetpgrp(STDIN_FILENO, pgid); while (waitpid(-pgid, NULL, 0) > 0); tcsetpgrp(STDIN_FILENO, getpgrp()); } void execute_pipeline_tree(PipelineTree pltree) { printf("Hello\n"); fflush(stdout); execute_command_pipeline(*pltree.root); }