diff options
Diffstat (limited to 'redes/exec.c')
| -rw-r--r-- | redes/exec.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/redes/exec.c b/redes/exec.c index 18ea59e..f7928af 100644 --- a/redes/exec.c +++ b/redes/exec.c @@ -2,7 +2,7 @@ #include "syntax.h" -void exec_cmd(ExecutableCommand cmd, int* pgid) { +void execute_cmd(ExecutableCommand cmd, int* pgid) { pid_t pid = fork(); @@ -55,15 +55,40 @@ ExecutableCommand process_pl_command(PlCommand pl_cmd) { } 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_FILE_IN: - fd = + 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}; } @@ -75,6 +100,28 @@ void execute_command_pipeline(PlCommand* pipeline) { Connector last_conn; do { PlCommand cmd = 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.count, j); + close(fd); + } } while (last_conn != CONN_EOL); + + tcsetpgrp(STDIN_FILENO, pgid); + while (waitpid(-pgid, NULL, 0) > 0); + tcsetpgrp(STDIN_FILENO, getpgrp()); } |
