From 3653e558f949ad876a19871ad64f80b7fecd8cc0 Mon Sep 17 00:00:00 2001 From: starnakin Date: Sun, 2 Jul 2023 12:10:28 +0200 Subject: [PATCH] add: redirections --- src/exec/exec.c | 4 +- src/parsing/parsing.c | 2 + src/redirection/redirection.c | 113 +++++++++++++++++++++++++++++++++- src/redirection/redirection.h | 11 ++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/redirection/redirection.h diff --git a/src/exec/exec.c b/src/exec/exec.c index a2209f9..e25b007 100644 --- a/src/exec/exec.c +++ b/src/exec/exec.c @@ -93,7 +93,9 @@ int cmds_list_exec(lst** cmds, lst** env) content->fd_out = fds[1]; ((cmd*)current->next->content)->fd_in = fds[0]; } - if (content->executable == NULL) + if (content->args[0] == NULL) + ; + else if (content->executable == NULL) dprintf(2, "zzsh: command not found: %s\n", content->args[0]); else if (builtin_execute(content, env) == 1) execute(content, env); diff --git a/src/parsing/parsing.c b/src/parsing/parsing.c index 4cab058..56cdfc2 100644 --- a/src/parsing/parsing.c +++ b/src/parsing/parsing.c @@ -1,6 +1,8 @@ #include "parsing.h" char* parsing_executable(const char* executable, lst** env) { + if (executable == NULL) + return NULL; if (strchr("./", executable[0])) return strdup(executable); return (get_executable_path(executable, env)); diff --git a/src/redirection/redirection.c b/src/redirection/redirection.c index 44bc1f8..67e733f 100644 --- a/src/redirection/redirection.c +++ b/src/redirection/redirection.c @@ -1,3 +1,114 @@ -#include "../../lib/bozolib/bozolib.h" +#include "./redirection.h" +#include +#include +#include +char* get_path(const char* start_path) +{ + size_t i, j; + char* out; + i = 0; + while (strchr(" \t", start_path[i])) + i++; + j = i; + while (start_path[j] != '\0' && strchr(" \t", start_path[j]) == NULL) + j++; + if (str_contain_only(start_path + i, "\t ")) + return NULL; + out = strndup(start_path + i, j); + if (out == NULL) + { + dprintf(2, "zzsh: malloc failed\n"); + return NULL; + } + quote_remover(out); + return out; +} + +static size_t get_path_size(const char* str) +{ + size_t i = 0; + while (strchr("\t ", str[i]) != NULL) + i++; + while (str[i] != '\0' && strchr("\t ", str[i]) == NULL) + i++; + return i; +} + +int redirection_fill(const char* str, size_t nb_symbols, cmd* command, const char *path) +{ + int problem = 0; + if (str[0] == '>') + { + if (command->fd_out > 2) + close(command->fd_out); + if (nb_symbols == 1) + command->fd_out = open(path, O_TRUNC | O_CREAT | O_WRONLY, 0644); + else + command->fd_out = open(path, O_APPEND | O_CREAT | O_WRONLY, 0644); + problem = command->fd_out == -1; + } + else + { + if (command->fd_in > 2) + close(command->fd_in); + if (nb_symbols == 1) + command->fd_in = open(path, O_RDONLY); + else + command->fd_in = open(path, O_RDONLY); + problem = command->fd_in == -1; + } + if (problem) + dprintf(2, "zzsh: \"%s\": file error\n", path); + return problem; +} + +static size_t get_concecutive(const char *str) +{ + size_t i; + for (i = 1; str[i] == str[0]; i++); + return (i); +} + +int get_redirections(char *str, cmd* command) +{ + char *redirection; + char redirection_symbol[3] = "<>"; + char *path; + size_t redirection_type; + + for (size_t i = 0; redirection_symbol[i] != '\0'; i++) + { + redirection = str; + while (redirection != NULL) + { + redirection = strchr(redirection, redirection_symbol[i]); + while (redirection != NULL && is_in_quote(str, redirection - str)) + redirection = strchr(redirection, '>'); + if (redirection == NULL) + break; + redirection_type = get_concecutive(redirection); + if (redirection_type > 2) + { + dprintf(2, "zzsh: invalid redirection type\n"); + return 1; + } + else + { + path = get_path(redirection + redirection_type); + if (path == NULL) + return 1; + if (redirection_fill(redirection, redirection_type, command, path)) + { + free(path); + return (1); + } + str_shift(redirection, (get_path_size(redirection + redirection_type) + redirection_type) * -1); + free(path); + } + redirection = redirection + redirection_type; + } + } + return (0); +} diff --git a/src/redirection/redirection.h b/src/redirection/redirection.h new file mode 100644 index 0000000..a559dd8 --- /dev/null +++ b/src/redirection/redirection.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include +#include +#include "../../lib/bozolib/bozolib.h" +#include "../cmd/cmd.h" +#include "../utils/utils.h" + +int get_redirections(char *str, cmd* command);