From da80405b345b58f9e1bd83039b1df3771b5ca193 Mon Sep 17 00:00:00 2001 From: Christopher Uhlig Date: Tue, 14 Jan 2025 18:18:58 +0100 Subject: [PATCH] update for exit bit norm removed staic stuff added prompt flag --- .vscode/c_cpp_properties.json | 18 + .vscode/launch.json | 13 + .vscode/settings.json | 64 ++ .vscode/tasks.json | 29 + garbage | 1229 +++++++++++++++++++++++++++++++++ include/env.h | 5 +- include/minishell.h | 8 +- lib/libft/ft_strcat.c | 4 +- lib/libft/ft_strcmp.c | 4 +- lib/libft/ft_strcpy.c | 4 +- src/builtins_part_one.c | 58 +- src/builtins_part_two.c | 27 +- src/collect_redirs.c | 132 +--- src/env.c | 23 +- src/env_to_strlst.c | 4 +- src/execute_cmd.c | 155 +++-- src/format_string.c | 16 +- src/init.c | 4 +- src/interpreter.c | 473 ++----------- src/main.c | 10 +- src/repl.c | 36 +- src/signal_handling.c | 4 +- src/tokenizer.c | 24 +- teest.txt | 1 + 24 files changed, 1635 insertions(+), 710 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 garbage create mode 100644 teest.txt diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..94b2ae4 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "macos-clang-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "macos-clang-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 + } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..86fa44a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,13 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "/Users/chuhlig/Desktop/merged_minishell/", + "program": "/Users/chuhlig/Desktop/merged_minishell/minishell" + } + ] + } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..91fa952 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,64 @@ +{ + "C_Cpp_Runner.cCompilerPath": "clang", + "C_Cpp_Runner.cppCompilerPath": "clang++", + "C_Cpp_Runner.debuggerPath": "lldb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false, + "files.associations": { + "minishell.h": "c", + "ast.h": "c", + "env.h": "c" + } + } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..4ede37a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,29 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: clang build active file", + "command": "/usr/bin/clang", + "args": [ + "-fcolor-diagnostics", + "-fansi-escape-codes", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/garbage b/garbage new file mode 100644 index 0000000..5b5afd8 --- /dev/null +++ b/garbage @@ -0,0 +1,1229 @@ +_=/Users/chuhlig/Desktop/merged_minishell/minishell/./minishell +TERM=xterm-256color +USER_ZDOTDIR=/Users/chuhlig +ZDOTDIR=/Users/chuhlig +VSCODE_INJECTION=1 +VSCODE_GIT_IPC_HANDLE=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/vscode-git-e47956ed09.sock +VSCODE_GIT_ASKPASS_MAIN=/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js +VSCODE_GIT_ASKPASS_EXTRA_ARGS= +VSCODE_GIT_ASKPASS_NODE=/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) +GIT_ASKPASS=/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass.sh +COLORTERM=truecolor +LANG=en_US.UTF-8 +TERM_PROGRAM_VERSION=1.95.3 +TERM_PROGRAM=vscode +OLDPWD=/Users/chuhlig/Desktop/merged_minishell +PWD=/Users/chuhlig/Desktop/merged_minishell/minishell +SHLVL=1 +ORIGINAL_XDG_CURRENT_DESKTOP=undefined +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +__CF_USER_TEXT_ENCODING=0x1928E:0x0:0x2 +SHELL=/bin/zsh +HOME=/Users/chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.ECcBYJZkxn/Listeners +LOGNAME=chuhlig +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Users/chuhlig/goinfre/.brew/bin +MallocNanoZone=0 +USER=chuhlig +_=/Users/chuhlig/Desktop/merged_minishell/minishell/./minishell +TERM=xterm-256color +USER_ZDOTDIR=/Users/chuhlig +ZDOTDIR=/Users/chuhlig +VSCODE_INJECTION=1 +VSCODE_GIT_IPC_HANDLE=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/vscode-git-e47956ed09.sock +VSCODE_GIT_ASKPASS_MAIN=/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js +VSCODE_GIT_ASKPASS_EXTRA_ARGS= +VSCODE_GIT_ASKPASS_NODE=/Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) +GIT_ASKPASS=/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass.sh +COLORTERM=truecolor +LANG=en_US.UTF-8 +TERM_PROGRAM_VERSION=1.95.3 +TERM_PROGRAM=vscode +OLDPWD=/Users/chuhlig/Desktop/merged_minishell +PWD=/Users/chuhlig/Desktop/merged_minishell/minishell +SHLVL=1 +ORIGINAL_XDG_CURRENT_DESKTOP=undefined +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +__CF_USER_TEXT_ENCODING=0x1928E:0x0:0x2 +SHELL=/bin/zsh +HOME=/Users/chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.ECcBYJZkxn/Listeners +LOGNAME=chuhlig +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Users/chuhlig/goinfre/.brew/bin +MallocNanoZone=0 +USER=chuhlig + + +//some test case about built in command + bash-3.2$ ls +Applications Music +Desktop Pictures +Documents francinette +Downloads getting-started +Library goinfre +Movies setup_docker_environment +bash-3.2$ pwd +/Users/chuhlig +bash-3.2$ ls | cd / | ls +Applications Music +Desktop Pictures +Documents francinette +Downloads getting-started +Library goinfre +Movies setup_docker_environment +bash-3.2$ pwd +/Users/chuhlig +bash-3.2$ env +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ export test=test | unset USER +bash-3.2$ env +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ env | grep test +bash-3.2$ ls | cd / | env +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ ls | cd / | env +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ ls | cd / | env +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ ls | cd / | env | cd / +bash-3.2$ pwd +/Users/chuhlig +bash-3.2$ ls | cd / | env | cd ~ +bash-3.2$ ls | cd / | env | cd - +bash: cd: OLDPWD not set +bash-3.2$ ls | cd - | env +bash: cd: OLDPWD not set +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ +bash-3.2$ ls | cd - | env +bash: cd: OLDPWD not set +TERM_PROGRAM=iTerm.app +TERM=xterm-256color +SHELL=/bin/zsh +TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n000ckjr0034mf/T/ +TERM_PROGRAM_VERSION=3.5.10 +TERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +USER=chuhlig +SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.BLODixwZXQ/Listeners +__CF_USER_TEXT_ENCODING=0x0:0:0 +TERM_FEATURES=T3LrMSc7UUw9Ts3BFGsSyHNoSxF +TERMINFO_DIRS=/Applications/iTerm.app/Contents/Resources/terminfo:/usr/share/terminfo +PATH=/Users/chuhlig/goinfre/.brew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/munki:/Library/Apple/usr/bin:/Applications/iTerm.app/Contents/Resources/utilities +PWD=/Users/chuhlig +LANG=en_US.UTF-8 +ITERM_PROFILE=Default +XPC_FLAGS=0x0 +XPC_SERVICE_NAME=0 +SHLVL=2 +HOME=/Users/chuhlig +COLORFGBG=7;0 +LC_TERMINAL_VERSION=3.5.10 +ITERM_SESSION_ID=w0t0p0:EC167FE5-607B-4E5F-A816-E8EF7FA09EC7 +LOGNAME=chuhlig +LC_TERMINAL=iTerm2 +COLORTERM=truecolor +_=/usr/bin/env +bash-3.2$ + + +////////////////////////////////////////////////////////////////// + +static int handle_redirections(t_redirection *redirs) { + if (redirs[0].type == INPUT_LIMITER) { + int pipe_fds[2]; + if (pipe(pipe_fds) == -1) { + perror("pipe"); + return -1; + } + write(pipe_fds[1], redirs[0].specifier, strlen(redirs[0].specifier)); + close(pipe_fds[1]); + dup2(pipe_fds[0], STDIN_FILENO); + close(pipe_fds[0]); + } else if (redirs[0].type == INPUT_FILE) { + int fd = open(redirs[0].specifier, O_RDONLY); + if (fd == -1) { + perror(redirs[0].specifier); + return -1; + } + dup2(fd, STDIN_FILENO); + close(fd); + } + + if (redirs[1].type == OUTPUT_OVERRIDE) { + int fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + perror(redirs[1].specifier); + return -1; + } + dup2(fd, STDOUT_FILENO); + close(fd); + } else if (redirs[1].type == OUTPUT_APPEND) { + int fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644); + if (fd == -1) { + perror(redirs[1].specifier); + return -1; + } + dup2(fd, STDOUT_FILENO); + close(fd); + } + return 0; +} + +static int eval_rec(t_node *node, t_env **env, int in_fd) { + pid_t pid; + int p[2], result; + + if (node->type == PIPE_NODE) { + pipe(p); + pid = fork(); + if (pid == 0) { + close(p[0]); + dup2(in_fd, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + result = eval_rec(node->content.pipe.left, env, in_fd); + exit(result); + } else { + close(p[1]); + dup2(p[0], STDIN_FILENO); + result = eval_rec(node->content.pipe.right, env, p[0]); + } + } else if (node->type == CMD_NODE) { + result = execute_cmd(&node->content.cmd, env); + } else { + panic("UNREACHABLE"); + result = EXIT_FAILURE; + } + return result; +} + +int eval(t_node *node, t_env **env) { + return eval_rec(node, env, STDIN_FILENO); +} + +int execute_cmd(t_cmd *cmd, t_env **env) { + if (handle_redirections(cmd->redirs) == -1) { + return EXIT_FAILURE; + } + + if (is_builtin(cmd->args[0])) { + return execute_builtin(cmd->args, env); + } else { + pid_t pid = fork(); + if (pid == 0) { + char *cmd_path = get_cmd_path(cmd->args[0], *env); + if (!cmd_path) { + fprintf(stderr, "%s: command not found\n", cmd->args[0]); + exit(EXIT_FAILURE); + } + execve(cmd_path, cmd->args, env_to_strlst(*env)); + perror("execve"); + exit(EXIT_FAILURE); + } else { + int status; + waitpid(pid, &status, 0); + return WEXITSTATUS(status); + } + } +} +have to update env list/tokenlist order or update the existing code to handle the order of the tokenlist/env list + +echo "Hello" | grep H this works + +also more to do on heredoc + +and for the for part of domenic removing the " ' frome the string +beside + + + +t_redirection *collect_redirs(t_token **tokens) +{ + t_redirection *result; + t_token *cur; + + cur = *tokens; + result = malloc(sizeof(t_redirection) * 2); + if (result == NULL) + return (free_tokens(*tokens), NULL); + set_redir(&result[0], 0, NULL); + set_redir(&result[1], 0, NULL); + while (cur != NULL && cur->next != NULL) + { + if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN) + collect_and_check_redir(result, &cur); + else if (cur->type == REDIR_TOKEN) + return (free(result), NULL); + else + cur = cur->next; + } + if (cur && cur->type == REDIR_TOKEN) + return (free(result), NULL); + return (result); +} + +static void collect_and_check_redir(t_redirection *result, t_token **cur) +{ + char *heredoc_data; + t_token *next_token; + + heredoc_data = NULL; + if ((*cur)->content.redir_type == INPUT_LIMITER) + { + // Handle Here Document (<<) + heredoc_data = read_heredoc((*cur)->next->content.string); + if (!heredoc_data) + { + perror("Heredoc allocation failed"); + return ; + } + set_redir(&result[0], INPUT_LIMITER, heredoc_data); + } + else if ((*cur)->content.redir_type == INPUT_FILE) + { + // Handle Input File (<) + set_redir(&result[0], INPUT_FILE, ft_strdup((*cur)->next->content.string)); + } + else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE) + { + // Handle Output File Overwrite (>) + set_redir(&result[1], OUTPUT_OVERRIDE, ft_strdup((*cur)->next->content.string)); + } + else if ((*cur)->content.redir_type == OUTPUT_APPEND) + { + // Handle Output File Append (>>) + set_redir(&result[1], OUTPUT_APPEND, ft_strdup((*cur)->next->content.string)); + } + else + { + // Handle unexpected cases + printf("Unknown redirection type encountered\n"); + } + // Advance the token pointer to skip the redirection token and its argument + next_token = (*cur)->next; + free_token_and_connect(*cur); // Free the current redirection token + if (next_token) + { + *cur = next_token->next; // Move to the next token after the argument + } + else + { + *cur = NULL; // No more tokens + } +} + +collect args apassen x +alsso fur arg x +muss in rpl parse x +und in parse cmd collect args and x + +format args seems to work later test x + + +Test 1: ✅ echo hello world +Test 2: ✅ echo "hello world" +Test 3: ✅ echo 'hello world' +Test 4: ✅ echo hello'world' +Test 5: ✅ echo hello""world +Test 6: ✅ echo '' +Test 7: ✅ echo "$PWD" +Test 8: ✅ echo '$PWD' + + + +Test 9: ❌ echo "aspas ->'" string formater checken +mini output = (aspas ->") +bash output = (aspas ->') +Test 10: ❌ echo "aspas -> ' " +mini output = (aspas -> ") +bash output = (aspas -> ' ) +Test 11: ✅ echo 'aspas ->"' +Test 12: ✅ echo 'aspas -> " ' + + +Test 13: ❌ echo "> >> < * ? [ ] | ; [ ] || && ( ) & # $ <<" +mini output = (> >> < README.md bash.supp bash_outfiles bonus bonus_bonus builtins extras local.supp loop.out manual_tests mini_outfiles os_specific outfiles pipes redirects syntax test_files tester wildcards ? [ ] | ; [ ] || && ( ) & # ) +bash output = (> >> < README.md bash.supp bash_outfiles bonus bonus_bonus builtins extras local.supp loop.out manual_tests mini_outfiles os_specific outfiles pipes redirects syntax test_files tester wildcards ? [ ] | ; [ ] || && ( ) & # $ <<) +Test 14: ✅ echo '> >> < * ? [ ] | ; [ ] || && ( ) & # $ <<' +Test 15: ❌ echo "exit_code ->$? user ->$USER home -> $HOME" +mini output = (exit_code ->/Users/dkaiser) +bash output = (exit_code ->0 user ->dkaiser home -> /Users/dkaiser) +Test 16: ✅ echo 'exit_code ->$? user ->$USER home -> $HOME' + +string formater checken +Test 17: ❌ echo "$" +mini output = (../minishell) +bash output = ($) +Test 18: ✅ echo '$' +Test 19: ❌ echo $ +mini output = (../minishell) +bash output = ($) +Test 20: ❌ echo $? +mini output = () +bash output = (0) +Test 21: ❌ echo $?HELLO +mini output = () +bash output = (0HELLO) +Test 22: ✅ pwd +Test 23: ✅ pwd oi +Test 24: ✅ export hello +Test 25: ✅ export HELLO=123 +Test 26: ❌ export A- +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( not a valid identifier) +Test 27: ✅ export HELLO=123 A +Test 28: ✅ export HELLO="123 A-" +Test 29: ✅ export hello world +Test 30: ❌ export HELLO-=123 +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( not a valid identifier) +Test 31: ❌ export = +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( not a valid identifier) +Test 32: ❌ export 123 +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( not a valid identifier) +Test 33: ✅ unset +Test 34: ✅ unset HELLO +Test 35: ✅ unset HELLO1 HELLO2 +Test 36: ✅ unset HOME +Test 37: ✅ unset PATH +Test 38: ✅ unset SHELL +Test 39: ❌ cd $PWD +mini exit code = 139 +bash exit code = 0 +Test 40: ❌ cd $PWD hi +mini exit code = 139 +bash exit code = 0 +Test 41: ❌ cd 123123 +mini exit code = 139 +bash exit code = 1 +mini error = () +bash error = ( No such file or directory) +Test 42: ❌ exit 123 +mini exit code = 0 +bash exit code = 123 +Test 43: ❌ exit 298 +mini exit code = 0 +bash exit code = 42 +Test 44: ❌ exit +100 +mini exit code = 0 +bash exit code = 100 +Test 45: ❌ exit "+100" +mini exit code = 0 +bash exit code = 100 +Test 46: ❌ exit +"100" +mini exit code = 0 +bash exit code = 100 +Test 47: ❌ exit -100 +mini exit code = 0 +bash exit code = 156 +Test 48: ❌ exit "-100" +mini exit code = 0 +bash exit code = 156 +Test 49: ❌ exit -"100" +mini exit code = 0 +bash exit code = 156 +Test 50: ❌ exit hello +mini exit code = 0 +bash exit code = 255 +mini error = () +bash error = ( numeric argument required) +Test 51: ❌ exit 42 world +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( too many arguments) +Test 52: ❌ +mini exit code = +bash exit code = 0 +———————————— pipes +Test 53: ✅ env | sort | grep -v SHLVL | grep -v ^_ +Test 54: ✅ cat ./test_files/infile_big | grep oi +Test 55: ✅ cat minishell.h | grep ");"$ +Test 56: ✅ export GHOST=123 | env | grep GHOST +———————————— redirects +Test 57: ✅ grep hi <./test_files/infile +Test 58: ✅ grep hi "./outfiles/outfile01 +Test 82: ✅ ls > ./outfiles/outfile01 +Test 83: ✅ echo hi > ./outfiles/outfile01 bye +Test 84: ❌ ls >./outfiles/outfile01 >./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +mini outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +bash outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +Test 85: ❌ ls >./outfiles/outfile01 >./test_files/invalid_permission +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +Test 86: ❌ ls >"./outfiles/outfile with spaces" +Only in ./bash_outfiles: outfile with spaces +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +mini exit code = 1 +bash exit code = 0 +mini error = ( No such file or directory) +bash error = () +Test 87: ❌ ls >"./outfiles/outfile""1""2""3""4""5" +Only in ./bash_outfiles: outfile12345 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +mini exit code = 1 +bash exit code = 0 +mini error = ( No such file or directory) +bash error = () +Test 88: ❌ ls >"./outfiles/outfile01" >./test_files/invalid_permission >"./outfiles/outfile02" +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +mini error = ( No such file or directory) +bash error = ( Permission denied) +Test 89: ✅ ls >./test_files/invalid_permission >"./outfiles/outfile01" >./test_files/invalid_permission +Test 90: ❌ cat <"./test_files/infile" >"./outfiles/outfile01" +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +hi +hello +world +42 +mini exit code = 1 +bash exit code = 0 +mini error = ( No such file or directory) +bash error = () +Test 91: ✅ echo hi >./outfiles/outfile01 | echo bye +Test 92: ❌ echo hi >./outfiles/outfile01 >./outfiles/outfile02 | echo bye +Only in ./bash_outfiles: outfile01 +mini outfiles: +hi +bash outfiles: +hi +Test 93: ✅ echo hi | echo >./outfiles/outfile01 bye +Test 94: ❌ echo hi | echo bye >./outfiles/outfile01 >./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +mini outfiles: +bye +bash outfiles: +bye +Test 95: ✅ echo hi >./outfiles/outfile01 | echo bye >./outfiles/outfile02 +Test 96: ❌ echo hi >./outfiles/outfile01 >./test_files/invalid_permission | echo bye +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +Test 97: ✅ echo hi >./test_files/invalid_permission | echo bye +Test 98: ❌ echo hi >./test_files/invalid_permission >./outfiles/outfile01 | echo bye +Only in ./mini_outfiles: outfile01 +mini outfiles: +hi +bash outfiles: +cat: ./bash_outfiles/*: No such file or directory +mini error = () +bash error = ( Permission denied) +Test 99: ✅ echo hi | echo bye >./test_files/invalid_permission +Test 100: ❌ echo hi | >./outfiles/outfile01 echo bye >./test_files/invalid_permission +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +mini exit code = 139 +bash exit code = 1 +mini error = () +bash error = ( Permission denied) +Test 101: ❌ echo hi | echo bye >./test_files/invalid_permission >./outfiles/outfile01 +Only in ./mini_outfiles: outfile01 +mini outfiles: +bye +bash outfiles: +cat: ./bash_outfiles/*: No such file or directory +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( Permission denied) +Test 102: ✅⚠️ cat <"./test_files/infile" >./test_files/invalid_permission +mini error = ( No such file or directory) +bash error = ( Permission denied) +Test 103: ✅⚠️ cat >./test_files/invalid_permission <"./test_files/infile" +mini error = ( No such file or directory) +bash error = ( Permission denied) +Test 104: ✅ cat ./outfiles/outfile01 +Test 105: ❌ cat >./outfiles/outfile01 ./test_files/invalid_permission +Test 107: ✅⚠️ cat >./test_files/invalid_permission ./outfiles/outfile01 ./test_files/invalid_permission +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +Test 109: ✅ ls >>./outfiles/outfile01 +Test 110: ✅ ls >> ./outfiles/outfile01 +Test 111: ✅ ls >>./outfiles/outfile01 >./outfiles/outfile01 +Test 112: ✅ ls >./outfiles/outfile01 >>./outfiles/outfile01 +Test 113: ❌ ls >./outfiles/outfile01 >>./outfiles/outfile01 >./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +mini outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +bash outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +Test 114: ❌ ls >>./outfiles/outfile01 >>./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +mini outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +bash outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +Test 115: ✅ ls >>./test_files/invalid_permission +Test 116: ❌ ls >>./test_files/invalid_permission >>./outfiles/outfile01 +Only in ./mini_outfiles: outfile01 +mini outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +bash outfiles: +cat: ./bash_outfiles/*: No such file or directory +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( Permission denied) +Test 117: ❌ ls >>./outfiles/outfile01 >>./test_files/invalid_permission +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +Test 118: ❌ ls >./outfiles/outfile01 >>./test_files/invalid_permission >>./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +Only in ./mini_outfiles: outfile02 +mini outfiles: +README.md +bash.supp +bash_outfiles +bonus +bonus_bonus +builtins +extras +local.supp +loop.out +manual_tests +mini_outfiles +os_specific +outfiles +pipes +redirects +syntax +test_files +tester +wildcards +bash outfiles: +mini exit code = 0 +bash exit code = 1 +mini error = () +bash error = ( Permission denied) +Test 119: ✅ ls >./test_files/invalid_permission >>./outfiles/outfile02 +Test 120: ✅⚠️ ls >>./test_files/invalid_permission >>./outfiles/outfile02 >./outfiles/outfile01 | echo bye +Test 122: ❌ echo hi >>./outfiles/outfile01 >>./outfiles/outfile02 | echo bye +Only in ./bash_outfiles: outfile01 +mini outfiles: +hi +bash outfiles: +hi +Test 123: ✅ echo hi | echo >>./outfiles/outfile01 bye +Test 124: ❌ echo hi | echo bye >>./outfiles/outfile01 >>./outfiles/outfile02 +Only in ./bash_outfiles: outfile01 +mini outfiles: +bye +bash outfiles: +bye +Test 125: ✅ echo hi >>./outfiles/outfile01 | echo bye >>./outfiles/outfile02 +Test 126: ✅ echo hi >>./test_files/invalid_permission | echo bye +Test 127: ❌ echo hi >>./test_files/invalid_permission >./outfiles/outfile01 | echo bye +Only in ./mini_outfiles: outfile01 +mini outfiles: +hi +bash outfiles: +cat: ./bash_outfiles/*: No such file or directory +mini error = () +bash error = ( Permission denied) +Test 128: ✅ echo hi | echo bye >>./test_files/invalid_permission +Test 129: ❌ echo hi | echo >>./outfiles/outfile01 bye >./test_files/invalid_permission +Only in ./bash_outfiles: outfile01 +mini outfiles: +cat: ./mini_outfiles/*: No such file or directory +bash outfiles: +Test 130: ✅ cat ./outfiles/outfile +Test 131: ✅ cat +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/08 16:53:39 by dkaiser #+# #+# */ -/* Updated: 2024/12/24 16:21:50 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 16:50:55 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,7 @@ typedef struct s_env struct s_env *next; } t_env; +void free_env_node(t_env *node); void getenvlst(t_env **env, char **en); void free_envlst(t_env **env); char *env_get(t_env *env, char *name); @@ -34,5 +35,7 @@ int echo(char **av); int pwd(t_env *env); int cd(t_env **env, char **args); int ft_env(t_env *env); +int builtin_exit(char **args, t_env **env); +t_env *env_new(char *name); #endif \ No newline at end of file diff --git a/include/minishell.h b/include/minishell.h index 028a4fc..9d586b1 100644 --- a/include/minishell.h +++ b/include/minishell.h @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:49 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 16:05:11 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 15:29:46 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,11 +25,13 @@ # include # include # include +# include +# include int init(void); int init_signal_handling(void); -void repl(const char *prompt, t_env **env); +void repl(const char *prompt, t_env **env, int *promptflag); t_list *parse(t_token *tokens, t_env **env); t_node *parse_cmd(t_token *tokens, t_env **env); @@ -40,6 +42,6 @@ int eval(t_node *node, t_env **env); char *get_cmd_path(char *cmd, t_env *env); int execute_cmd(t_cmd *cmd, t_env **env); char *format_string(char *str, t_env *env); - +int handle_redirections(t_redirection *redirs); #endif diff --git a/lib/libft/ft_strcat.c b/lib/libft/ft_strcat.c index 648c184..b21235b 100644 --- a/lib/libft/ft_strcat.c +++ b/lib/libft/ft_strcat.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/09 13:06:44 by chuhlig #+# #+# */ -/* Updated: 2025/01/09 13:07:15 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:09:49 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,4 +26,4 @@ char *ft_strcat(char *dest, char *src) } dest[i + j] = '\0'; return (dest); -} \ No newline at end of file +} diff --git a/lib/libft/ft_strcmp.c b/lib/libft/ft_strcmp.c index af7b2a1..a319c63 100644 --- a/lib/libft/ft_strcmp.c +++ b/lib/libft/ft_strcmp.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/18 19:03:14 by chuhlig #+# #+# */ -/* Updated: 2024/12/18 19:05:01 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:09:59 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,4 +20,4 @@ int ft_strcmp(char *s1, char *s2) while (s1[i] && s1[i] == s2[i]) i++; return (s1[i] - s2[i]); -} \ No newline at end of file +} diff --git a/lib/libft/ft_strcpy.c b/lib/libft/ft_strcpy.c index b5c612f..94a07f7 100644 --- a/lib/libft/ft_strcpy.c +++ b/lib/libft/ft_strcpy.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/01/09 14:38:30 by chuhlig #+# #+# */ -/* Updated: 2025/01/09 14:38:53 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:10:06 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,4 +22,4 @@ char *ft_strcpy(char *dest, char *src) } dest[i] = '\0'; return (dest); -} \ No newline at end of file +} diff --git a/src/builtins_part_one.c b/src/builtins_part_one.c index d64bb54..d8bdaa9 100644 --- a/src/builtins_part_one.c +++ b/src/builtins_part_one.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/09 17:01:16 by chuhlig #+# #+# */ -/* Updated: 2025/01/10 14:36:55 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 16:51:05 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,43 +41,22 @@ int echo(char **av) return (0); } -int pwd(t_env *env) +void exit_shell(t_env **env, int exit_status) { - while (env) - { - if (ft_strncmp(env->name, "PWD", 4) == 0) - { - ft_printf("%s\n", env->value); - break ; - } - env = env->next; - } - return (0); + free_envlst(env); + exit(exit_status); } -int ft_env(t_env *env) +int builtin_exit(char **args, t_env **env) { - while (env != NULL) - { - printf("%s", env->name); - printf("=%s\n", env->value); - env = env->next; - } - return (0); -} - -// int exit(char *av) -// { -// freenode free toke free sequence stop repl free env; -// clear history; -// } -//// + int exit_status; -void free_env_node(t_env *node) -{ - free(node->name); - free(node->value); - free(node); + if (args[1]) + exit_status = ft_atoi(args[1]); + else + exit_status = 0; + exit_shell(env, exit_status); + return (exit_status); } int unset(char **av, t_env **env) @@ -109,17 +88,6 @@ int unset(char **av, t_env **env) return (0); } -t_env *env_new(char *name) -{ - t_env *result; - - result = malloc(sizeof(t_env)); - if (!result) - return (NULL); - result->name = name; - return (result); -} - t_env *check_existing(t_env *env, char *av) { while (env) @@ -158,4 +126,4 @@ int export(char **av, t_env **env) } } return (0); -} \ No newline at end of file +} diff --git a/src/builtins_part_two.c b/src/builtins_part_two.c index f54e04f..5af6c68 100644 --- a/src/builtins_part_two.c +++ b/src/builtins_part_two.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/25 20:52:16 by chuhlig #+# #+# */ -/* Updated: 2024/12/20 18:53:03 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:26:39 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -82,3 +82,28 @@ int cd(t_env **env, char **av) } return (0); } + +int pwd(t_env *env) +{ + while (env) + { + if (ft_strncmp(env->name, "PWD", 4) == 0) + { + ft_printf("%s\n", env->value); + break ; + } + env = env->next; + } + return (0); +} + +int ft_env(t_env *env) +{ + while (env != NULL) + { + printf("%s", env->name); + printf("=%s\n", env->value); + env = env->next; + } + return (0); +} diff --git a/src/collect_redirs.c b/src/collect_redirs.c index 4b7b955..84ebd71 100644 --- a/src/collect_redirs.c +++ b/src/collect_redirs.c @@ -6,50 +6,14 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/02 13:49:31 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 11:43:13 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 16:55:20 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -// static t_token *collect_redir(t_token **tokens, t_redirection *result, -// t_token *cur); -// static void collect_and_check_redir(t_token **tokens, t_redirection *result, -// t_token **cur); static void collect_and_check_redir(t_redirection *result, t_token **cur); static void set_redir(t_redirection *redir, int type, char *specifier); -// static int is_output_redir(int i); - -// static char *read_heredoc(char *delimiter) -// { -// char *line; -// char *result; -// size_t len; - -// result = NULL; -// while (1) -// { -// line = readline("> "); -// if (!line || ft_strcmp(line, delimiter) == 0) -// { -// free(line); -// break ; -// } -// if (result) -// len = ft_strlen(result); -// else -// len = 0; -// result = realloc(result, len + ft_strlen(line) + 2); -// if (!result) -// return (NULL); -// ft_strcpy(result + len, line); -// strcat(result, "\n"); -// free(line); -// } -// return (result); -// } - -//v2.0 static char *read_heredoc(char *delimiter) { @@ -74,8 +38,7 @@ static char *read_heredoc(char *delimiter) if (!temp) { perror("malloc"); - free(result); - return (NULL); + return (free(result), NULL); } if (result) { @@ -83,9 +46,7 @@ static char *read_heredoc(char *delimiter) free(result); } else - { temp[0] = '\0'; - } ft_strcat(temp, line); ft_strcat(temp, "\n"); result = temp; @@ -109,7 +70,7 @@ t_redirection *collect_redirs(t_token **tokens) while (cur != NULL && cur->next != NULL) { if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN) - collect_and_check_redir(result, &cur);// her is diff + collect_and_check_redir(result, &cur); else if (cur->type == REDIR_TOKEN) return (free(result), NULL); else @@ -120,62 +81,12 @@ t_redirection *collect_redirs(t_token **tokens) return (result); } -// static void collect_and_check_redir(t_token **tokens, t_redirection *result, -// t_token **cur) -// { -// int is_redir_only; - -// is_redir_only = 0; -// if ((*cur)->previous == NULL && (*cur)->next->next == NULL) -// is_redir_only = 1; -// *cur = collect_redir(tokens, result, *cur); -// if (is_redir_only) -// *tokens = NULL; -// } - -// static t_token *collect_redir(t_token **tokens, t_redirection *result, -// t_token *cur) -// { -// set_redir(&result[is_output_redir(cur->content.redir_type)], -// cur->content.redir_type, cur->next->content.string); -// cur = cur->next; -// free_token_and_connect(cur->previous); -// if (cur->next != NULL) -// { -// if (cur->previous == NULL) -// *tokens = cur->next; -// cur = cur->next; -// free_token_and_connect(cur->previous); -// } -// else -// { -// free_token(cur); -// return (NULL); -// } -// return (cur); -// } - static void set_redir(t_redirection *redir, int type, char *specifier) { redir->type = type; redir->specifier = specifier; } -// static int is_output_redir(int i) -// { -// if (i & (INPUT_FILE | INPUT_LIMITER)) -// return (0); -// else if (i & (OUTPUT_APPEND | OUTPUT_OVERRIDE)) -// return (1); -// else -// { -// panic(UNREACHABLE); -// return (-1); -// } -// } - -//2.0 - static void collect_and_check_redir(t_redirection *result, t_token **cur) { char *heredoc_data; @@ -184,7 +95,6 @@ static void collect_and_check_redir(t_redirection *result, t_token **cur) heredoc_data = NULL; if ((*cur)->content.redir_type == INPUT_LIMITER) { - // Handle Here Document (<<) heredoc_data = read_heredoc((*cur)->next->content.string); if (!heredoc_data) { @@ -194,35 +104,21 @@ static void collect_and_check_redir(t_redirection *result, t_token **cur) set_redir(&result[0], INPUT_LIMITER, heredoc_data); } else if ((*cur)->content.redir_type == INPUT_FILE) - { - // Handle Input File (<) - set_redir(&result[0], INPUT_FILE, ft_strdup((*cur)->next->content.string)); - } + set_redir(&result[0], INPUT_FILE, + ft_strdup((*cur)->next->content.string)); else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE) - { - // Handle Output File Overwrite (>) - set_redir(&result[1], OUTPUT_OVERRIDE, ft_strdup((*cur)->next->content.string)); - } + set_redir(&result[1], OUTPUT_OVERRIDE, + ft_strdup((*cur)->next->content.string)); else if ((*cur)->content.redir_type == OUTPUT_APPEND) - { - // Handle Output File Append (>>) - set_redir(&result[1], OUTPUT_APPEND, ft_strdup((*cur)->next->content.string)); - } - else - { - // Handle unexpected cases - printf("Unknown redirection type encountered\n"); - } - // Advance the token pointer to skip the redirection token and its argument + set_redir(&result[1], OUTPUT_APPEND, + ft_strdup((*cur)->next->content.string)); next_token = (*cur)->next; - free_token_and_connect(*cur); // Free the current redirection token + free_token_and_connect(*cur); if (next_token) { - *cur = next_token->next; // Move to the next token after the argument - free_token_and_connect(next_token); // Free the argument token + *cur = next_token->next; + free_token_and_connect(next_token); } else - { - *cur = NULL; // No more tokens - } -} \ No newline at end of file + *cur = NULL; +} diff --git a/src/env.c b/src/env.c index 0213209..1972909 100644 --- a/src/env.c +++ b/src/env.c @@ -6,11 +6,12 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/17 14:31:07 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:36:14 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:44:34 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "env.h" +#include "minishell.h" #include void getenvlst(t_env **env, char **en) @@ -59,4 +60,22 @@ char *env_get(t_env *env, char *name) env = env->next; } return (NULL); -} \ No newline at end of file +} + +t_env *env_new(char *name) +{ + t_env *result; + + result = malloc(sizeof(t_env)); + if (!result) + return (NULL); + result->name = name; + return (result); +} + +void free_env_node(t_env *node) +{ + free(node->name); + free(node->value); + free(node); +} diff --git a/src/env_to_strlst.c b/src/env_to_strlst.c index c4c98c3..2031c24 100644 --- a/src/env_to_strlst.c +++ b/src/env_to_strlst.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:22:28 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:22:36 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:10:49 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -55,4 +55,4 @@ static char *get_var_assign(t_env *cur) result = ft_strjoin(left_side, cur->value); free(left_side); return (result); -} \ No newline at end of file +} diff --git a/src/execute_cmd.c b/src/execute_cmd.c index 7f93c5a..b9faf71 100644 --- a/src/execute_cmd.c +++ b/src/execute_cmd.c @@ -6,81 +6,96 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:21:35 by chuhlig #+# #+# */ -/* Updated: 2025/01/09 16:07:01 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 16:56:24 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -#include -#include -#include -#include -#include -#include -// static void format_args(char **args, t_env *env); +int is_builtin(char *cmd) +{ + return ((ft_strcmp(cmd, "export") == 0) + || (ft_strcmp(cmd, "unset") == 0) + || (ft_strcmp(cmd, "cd") == 0) + || (ft_strcmp(cmd, "exit") == 0) + || (ft_strcmp(cmd, "echo") == 0) + || (ft_strcmp(cmd, "pwd") == 0) + || (ft_strcmp(cmd, "env") == 0)); +} -// int execute_cmd(t_cmd *cmd, t_env **env) -// { -// int result; -// char *cmd_path; -// int fd; +int execute_builtin(char **args, t_env **env) +{ + if (ft_strcmp(args[0], "export") == 0) + return (export(args, env)); + else if (ft_strcmp(args[0], "unset") == 0) + return (unset(args, env)); + else if (ft_strcmp(args[0], "cd") == 0) + return (cd(env, args)); + else if (ft_strcmp(args[0], "echo") == 0) + return (echo(args)); + else if (ft_strcmp(args[0], "pwd") == 0) + return (pwd(*env)); + else if (ft_strcmp(args[0], "env") == 0) + return (ft_env(*env)); + else if (ft_strcmp(args[0], "exit") == 0) + return (builtin_exit(args, env)); + return (1); +} -// if (ft_strncmp(cmd->args[0], "pwd", 4) == 0) -// return (pwd(*env)); -// else if (ft_strncmp(cmd->args[0], "echo", 5) == 0) -// return (echo(cmd->args)); -// else if (ft_strncmp(cmd->args[0], "env", 4) == 0) -// return (ft_env(*env)); -// else if (ft_strncmp(cmd->args[0], "cd", 3) == 0) -// return (cd(env, cmd->args)); -// else if (ft_strncmp(cmd->args[0], "unset", 6) == 0) -// return (unset(cmd->args, env)); -// else if (ft_strncmp(cmd->args[0], "export", 7) == 0) -// return (export(cmd->args, env)); -// format_args(cmd->args, *env); -// cmd_path = get_cmd_path(cmd->args[0], *env); -// cmd->args[0] = cmd_path; -// if (cmd->redirs[0].type == INPUT_FILE) -// { -// fd = open(cmd->redirs[0].specifier, O_RDONLY); -// if (fd < 0) -// return (EXIT_FAILURE); -// dup2(fd, STDIN_FILENO); -// } -// else if (cmd->redirs[0].type == INPUT_LIMITER) -// { -// dbg("INPUT_LIMITER"); -// } -// if (cmd->redirs[1].type == OUTPUT_APPEND) -// { -// dbg("OUTPUT_APPEND"); -// fd = open(cmd->redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 644); -// if (fd < 0) -// return (EXIT_FAILURE); -// dup2(fd, STDOUT_FILENO); -// } -// else if (cmd->redirs[1].type == OUTPUT_OVERRIDE) -// { -// fd = open(cmd->redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 644); -// if (fd < 0) -// return (EXIT_FAILURE); -// dup2(fd, STDOUT_FILENO); -// dbg("OUTPUT_OVERRIDE"); -// } -// result = execve(cmd->args[0], cmd->args, env_to_strlst(*env)); -// return (result); -// } +int execute_cmd(t_cmd *cmd, t_env **env) +{ + char *cmd_path; + pid_t pid; + int status; + int original_stdout; + int original_stdin; + int result; -// static void format_args(char **args, t_env *env) -// { -// char *formatted; - -// while (*args != NULL) -// { -// formatted = format_string(*args, env); -// /* free(*args); */ -// *args = formatted; -// args++; -// } -// } \ No newline at end of file + original_stdout = dup(STDOUT_FILENO); + original_stdin = dup(STDIN_FILENO); + if (handle_redirections(cmd->redirs) == -1) + { + dup2(original_stdout, STDOUT_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdout); + close(original_stdin); + return (EXIT_FAILURE); + } + if (is_builtin(cmd->args[0])) + { + result = execute_builtin(cmd->args, env); + dup2(original_stdout, STDOUT_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdout); + close(original_stdin); + return (result); + } + pid = fork(); + if (pid == -1) + { + perror("fork"); + dup2(original_stdout, STDOUT_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdout); + close(original_stdin); + return (EXIT_FAILURE); + } + if (pid == 0) + { + cmd_path = get_cmd_path(cmd->args[0], *env); + if (!cmd_path) + { + printf("command not found\n"); + exit(EXIT_FAILURE); + } + execve(cmd_path, cmd->args, env_to_strlst(*env)); + perror("execve"); + exit(EXIT_FAILURE); + } + waitpid(pid, &status, 0); + dup2(original_stdout, STDOUT_FILENO); + dup2(original_stdin, STDIN_FILENO); + close(original_stdout); + close(original_stdin); + return (WEXITSTATUS(status)); +} diff --git a/src/format_string.c b/src/format_string.c index bd7f703..7168ea0 100644 --- a/src/format_string.c +++ b/src/format_string.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:30:11 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:31:54 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 14:21:36 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,12 +17,6 @@ static void append_slice(char **dst, char *src, int start, int end); static void append_var(char **dst, char *src, int *pos, t_env *env); -enum e_format_mode -{ - LITERAL = 1, - VARIABLE = 2, -}; - char *format_string(char *str, t_env *env) { char *result; @@ -42,14 +36,14 @@ char *format_string(char *str, t_env *env) { append_slice(&result, str, start, pos); start = pos + 1; - mode ^= LITERAL; + mode ^= 1; } - if (str[pos] == '"' && !(mode & LITERAL)) + if (str[pos] == '"' && !(mode & 1)) { append_slice(&result, str, start, pos); start = pos + 1; } - if (str[pos] == '$' && !(mode & LITERAL)) + if (str[pos] == '$' && !(mode & 1)) { append_slice(&result, str, start, pos); append_var(&result, str, &pos, env); @@ -100,7 +94,7 @@ static void append_var(char **dst, char *src, int *pos, t_env *env) i = 0; *pos += 1; while (src[*pos + i] != '\0' && src[*pos + i] != '\'' && src[*pos - + i] != '"' && src[*pos + i] != '$') + + i] != '"' && src[*pos + i] != '$') { i++; } diff --git a/src/init.c b/src/init.c index fd2c8ac..f41e64a 100644 --- a/src/init.c +++ b/src/init.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* init.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 15:02:24 by dkaiser #+# #+# */ -/* Updated: 2024/06/24 15:25:57 by dkaiser ### ########.fr */ +/* Updated: 2025/01/13 17:45:46 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/interpreter.c b/src/interpreter.c index 33d945c..af1eb82 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -6,326 +6,73 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:15:49 by chuhlig #+# #+# */ -/* Updated: 2025/01/11 12:52:57 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 16:59:45 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "debug_tools.h" #include "minishell.h" -#include -#include -#include -#include -#include -#include -#include - -// static int eval_rec(t_node *node, t_env **env, int in_fd); - -// int eval(t_node *node, t_env **env) -// { -// pid_t pid; -// int result; - -// if (node == NULL) -// return (EXIT_FAILURE); -// result = 0; -// pid = fork(); -// if (pid < 0) -// { -// return (EXIT_FAILURE); -// } -// if (pid == 0) -// { -// result = eval_rec(node, env, STDIN_FILENO); -// exit(result); -// } -// else -// { -// waitpid(pid, &result, 0); -// } -// return (result); -// } - -// static int eval_rec(t_node *node, t_env **env, int in_fd) -// { -// pid_t pid; -// int result; -// int p[2]; - -// result = pipe(p); -// if (result == -1) -// return (EXIT_FAILURE); -// if (node->type == PIPE_NODE) -// { -// pid = fork(); -// if (pid < 0) -// { -// return (EXIT_FAILURE); -// } -// if (pid == 0) -// { -// close(p[0]); -// dup2(in_fd, STDIN_FILENO); -// dup2(p[1], STDOUT_FILENO); -// result = execute_cmd(&node->content.pipe.left->content.cmd, env); -// exit(result); -// } -// else -// { -// close(p[1]); -// dup2(p[0], STDIN_FILENO); -// result = eval_rec(node->content.pipe.right, env, p[0]); -// } -// } -// else if (node->type == CMD_NODE) -// { -// result = execute_cmd(&node->content.cmd, env); -// } -// else -// { -// panic(UNREACHABLE); -// return (EXIT_FAILURE); -// } -// return (result); -// } - - -//old interpreter -// #include "minishell.h" -// #include - -// static int eval_pipe(t_pipe *pipe, t_env *env); -// static int eval_cmd(t_cmd *cmd, t_env **env); - -// int eval(t_node *node, t_env **env) -// { -// if (node->type == PIPE_NODE) -// return (eval_pipe(&node->content.pipe, *env)); -// else if (node->type == CMD_NODE) -// return (eval_cmd(&node->content.cmd, env)); -// else -// { -// panic(UNREACHABLE); -// return (-1); -// } -// } - -// static int eval_pipe(t_pipe *pipe, t_env *env) -// { -// dbg("TODO: PIPE"); -// eval_cmd(&pipe->left->content.cmd, &env); -// eval_cmd(&pipe->right->content.cmd, &env); -// return (0); -// } - -// static int eval_cmd(t_cmd *cmd, t_env **env) -// { -// if (ft_strncmp(cmd->args[0], "pwd", 4) == 0) -// pwd(*env); -// else if (ft_strncmp(cmd->args[0], "echo", 5) == 0) -// echo(cmd->args); -// else if (ft_strncmp(cmd->args[0], "env", 4) == 0) -// ft_env(*env); -// else if (ft_strncmp(cmd->args[0], "cd", 3) == 0) -// cd(env, cmd->args); -// else if (ft_strncmp(cmd->args[0], "unset", 6) == 0) -// unset(cmd->args, env); -// else if (ft_strncmp(cmd->args[0], "export", 7) == 0) -// export(cmd->args, env); -// return (0); -// } - -//v2.0 - -int is_builtin(char *cmd) +int handle_redirections(t_redirection *redirs) { - return ((ft_strcmp(cmd, "export") == 0) - || (ft_strcmp(cmd, "unset") == 0) - || (ft_strcmp(cmd, "cd") == 0) - || (ft_strcmp(cmd, "exit") == 0) - || (ft_strcmp(cmd, "echo") == 0) - || (ft_strcmp(cmd, "pwd") == 0) - || (ft_strcmp(cmd, "env") == 0)); -} + int fd; -int execute_builtin(char **args, t_env **env) -{ - if (ft_strcmp(args[0], "export") == 0) - return (export(args, env)); - else if (ft_strcmp(args[0], "unset") == 0) - return (unset(args, env)); - else if (ft_strcmp(args[0], "cd") == 0) - return (cd(env, args)); - else if (ft_strcmp(args[0], "exit") == 0) - return (EXIT_SUCCESS); - else if (ft_strcmp(args[0], "echo") == 0) - return (echo(args)); - else if (ft_strcmp(args[0], "pwd") == 0) - return (pwd(*env)); - else if (ft_strcmp(args[0], "env") == 0) - return (ft_env(*env)); - return (1); -} -// v1.0 - -// static int handle_redirections(t_redirection *redirs) -// { -// int fd; -// int pipe_fds[2]; - -// if (redirs[0].type == INPUT_LIMITER) -// { -// if (pipe(pipe_fds) == -1) -// { -// perror("pipe"); -// return (-1); -// } -// write(pipe_fds[1], redirs[0].specifier, strlen(redirs[0].specifier)); -// close(pipe_fds[1]); -// dup2(pipe_fds[0], STDIN_FILENO); -// close(pipe_fds[0]); -// } -// else if (redirs[0].type == INPUT_FILE) -// { -// fd = open(redirs[0].specifier, O_RDONLY); -// if (fd == -1) -// { -// perror(redirs[0].specifier); -// return (-1); -// } -// dup2(fd, STDIN_FILENO); -// close(fd); -// } -// if (redirs[1].type == OUTPUT_OVERRIDE) -// { -// fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644); -// if (fd == -1) -// { -// perror(redirs[1].specifier); -// return (-1); -// } -// dup2(fd, STDOUT_FILENO); -// close(fd); -// } -// else if (redirs[1].type == OUTPUT_APPEND) -// { -// fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644); -// if (fd == -1) -// { -// perror(redirs[1].specifier); -// return (-1); -// } -// dup2(fd, STDOUT_FILENO); -// close(fd); -// } -// return (0); -// } -//v 3.0 -static int handle_redirections(t_redirection *redirs) -{ - int fd; - - if (redirs[0].type == INPUT_FILE) - { - fd = open(redirs[0].specifier, O_RDONLY); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDIN_FILENO); - close(fd); - } - else if (redirs[0].type == INPUT_LIMITER) - { - // Handle here document (<<) - // Assuming heredoc_data is stored in redirs[0].specifier - fd = open("/tmp/heredoc_tmp", O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - write(fd, redirs[0].specifier, strlen(redirs[0].specifier)); - close(fd); - fd = open("/tmp/heredoc_tmp", O_RDONLY); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDIN_FILENO); - close(fd); - } - if (redirs[1].type == OUTPUT_OVERRIDE) - { - fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDOUT_FILENO); - close(fd); - } - else if (redirs[1].type == OUTPUT_APPEND) - { - fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644); - if (fd < 0) - { - perror("open"); - return (-1); - } - dup2(fd, STDOUT_FILENO); - close(fd); - } - return (0); + if (redirs[0].type == INPUT_FILE) + { + fd = open(redirs[0].specifier, O_RDONLY); + if (fd < 0) + { + perror(redirs[0].specifier); + return (-1); + } + dup2(fd, STDIN_FILENO); + close(fd); + } + else if (redirs[0].type == INPUT_LIMITER) + { + fd = open("/tmp/heredoc_tmp", O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + perror("open"); + return (-1); + } + write(fd, redirs[0].specifier, ft_strlen(redirs[0].specifier)); + close(fd); + fd = open("/tmp/heredoc_tmp", O_RDONLY); + if (fd < 0) + { + perror("open"); + return (-1); + } + dup2(fd, STDIN_FILENO); + close(fd); + } + if (redirs[1].type == OUTPUT_OVERRIDE) + { + fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) + { + perror("open"); + return (-1); + } + dup2(fd, STDOUT_FILENO); + close(fd); + } + else if (redirs[1].type == OUTPUT_APPEND) + { + fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644); + if (fd < 0) + { + perror("open"); + return (-1); + } + dup2(fd, STDOUT_FILENO); + close(fd); + } + return (0); } -//v 2.0 -// static int eval_rec(t_node *node, t_env **env, int in_fd) -// { -// pid_t pid; -// int p[2]; -// int result; -// int status; - -// if (node->type == PIPE_NODE) -// { -// pipe(p); -// pid = fork(); -// if (pid == 0) -// { -// close(p[0]); -// dup2(in_fd, STDIN_FILENO); -// dup2(p[1], STDOUT_FILENO); -// result = eval_rec(node->content.pipe.left, env, in_fd); -// exit(result); -// } -// else -// { -// close(p[1]); -// dup2(p[0], STDIN_FILENO); -// result = eval_rec(node->content.pipe.right, env, p[0]); -// waitpid(pid, &status, 0); -// } -// } -// else if (node->type == CMD_NODE) -// { -// result = execute_cmd(&node->content.cmd, env); -// } -// else -// { -// panic("UNREACHABLE"); -// result = EXIT_FAILURE; -// } -// return (result); -// } - -//v 3.0 -static int eval_rec(t_node *node, t_env **env, int in_fd) +int eval_rec(t_node *node, t_env **env, int in_fd) { pid_t pid; int p[2]; @@ -357,117 +104,13 @@ static int eval_rec(t_node *node, t_env **env, int in_fd) } } else if (node->type == CMD_NODE) - { result = execute_cmd(&node->content.cmd, env); - } else - { - printf("Handling unknown node type\n"); - panic("UNREACHABLE"); result = EXIT_FAILURE; - } return (result); } -int eval(t_node *node, t_env **env) +int eval(t_node *node, t_env **env) { return (eval_rec(node, env, STDIN_FILENO)); } -//v was auch immmer - -// int execute_cmd(t_cmd *cmd, t_env **env) -// { -// char *cmd_path; -// pid_t pid; -// int status; - -// if (handle_redirections(cmd->redirs) == -1) -// { -// return (EXIT_FAILURE); -// } -// if (is_builtin(cmd->args[0])) -// { -// return (execute_builtin(cmd->args, env)); -// } -// pid = fork(); -// if (pid == -1) -// { -// perror("fork"); -// return (EXIT_FAILURE); -// } -// if (pid == 0) -// { -// cmd_path = get_cmd_path(cmd->args[0], *env); -// if (!cmd_path) -// { -// printf("%s: command not found\n", cmd->args[0]); -// return (EXIT_FAILURE); -// } -// execve(cmd_path, cmd->args, env_to_strlst(*env)); -// perror("execve"); -// exit(EXIT_FAILURE); -// } -// waitpid(pid, &status, 0); -// return (WEXITSTATUS(status)); -// } -int execute_cmd(t_cmd *cmd, t_env **env) -{ - char *cmd_path; - pid_t pid; - int status; - int original_stdout; - int original_stdin; - - original_stdout = dup(STDOUT_FILENO); - original_stdin = dup(STDIN_FILENO); - - if (handle_redirections(cmd->redirs) == -1) - { - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); - return (EXIT_FAILURE); - } - - if (is_builtin(cmd->args[0])) - { - int result = execute_builtin(cmd->args, env); - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); - return (result); - } - - pid = fork(); - if (pid == -1) - { - perror("fork"); - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); - return (EXIT_FAILURE); - } - if (pid == 0) - { - cmd_path = get_cmd_path(cmd->args[0], *env); - if (!cmd_path) - { - printf("%s: command not found\n", cmd->args[0]); - exit(EXIT_FAILURE); - } - execve(cmd_path, cmd->args, env_to_strlst(*env)); - perror("execve"); - exit(EXIT_FAILURE); - } - waitpid(pid, &status, 0); - - dup2(original_stdout, STDOUT_FILENO); - dup2(original_stdin, STDIN_FILENO); - close(original_stdout); - close(original_stdin); - - return (WEXITSTATUS(status)); -} \ No newline at end of file diff --git a/src/main.c b/src/main.c index a53760c..8abc4c9 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/22 17:14:03 by dkaiser #+# #+# */ -/* Updated: 2024/12/17 19:26:42 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 15:29:20 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,13 +14,17 @@ int main(int argc, char *argv[], char *envp[]) { - t_env *env; + t_env *env; + static int promptflag; env = NULL; + promptflag = 0; if (!argc && !argv) return (1); if (init()) return (1); getenvlst(&env, envp); - repl("Minishell $ ", &env); + repl("Minishell $ ", &env, &promptflag); + free_envlst(&env); + return (0); } diff --git a/src/repl.c b/src/repl.c index 7ff80a8..7eb6c0d 100644 --- a/src/repl.c +++ b/src/repl.c @@ -6,56 +6,38 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 16:07:04 by dkaiser #+# #+# */ -/* Updated: 2025/01/11 16:01:44 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 15:39:58 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/minishell.h" #include "token.h" -t_token *reverse_token_list(t_token *head) -{ - t_token *prev; - t_token *current; - t_token *next; - - prev = NULL; - current = head; - next = NULL; - while (current != NULL) - { - next = current->previous; - current->next = prev; - current->previous = next; - prev = current; - current = next; - } - return (prev); -} - -void repl(const char *prompt, t_env **env) +void repl(const char *prompt, t_env **env, int *promptflag) { char *input; t_token *token_list; t_list *lines; + (*promptflag)++; while (1) { input = readline(prompt); if (input == NULL) - return ; + { + if (*promptflag > 1) + (*promptflag)--; + printf("exit\n"); + break ; + } if (input[0] == '\0') continue ; add_history(input); token_list = NULL; tokenizer(input, &token_list, '\0'); - token_list = reverse_token_list(token_list); lines = parse(token_list, env); if (lines) - { - print_ast(lines->content); eval(lines->content, env); - } free(input); } } diff --git a/src/signal_handling.c b/src/signal_handling.c index a19fa94..c6273d0 100644 --- a/src/signal_handling.c +++ b/src/signal_handling.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* signal_handling.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dkaiser +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/24 15:08:43 by dkaiser #+# #+# */ -/* Updated: 2024/06/25 13:33:26 by dkaiser ### ########.fr */ +/* Updated: 2025/01/14 14:11:29 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/tokenizer.c b/src/tokenizer.c index 26edd2e..6d16f1d 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -6,13 +6,33 @@ /* By: chuhlig +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/28 20:55:50 by chuhlig #+# #+# */ -/* Updated: 2025/01/11 15:22:07 by chuhlig ### ########.fr */ +/* Updated: 2025/01/14 15:58:41 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" #include "token.h" +t_token *reverse_token_list(t_token *head) +{ + t_token *prev; + t_token *current; + t_token *next; + + prev = NULL; + current = head; + next = NULL; + while (current != NULL) + { + next = current->previous; + current->next = prev; + current->previous = next; + prev = current; + current = next; + } + return (prev); +} + void print_token(t_token *token) { if (DEBUG) @@ -77,7 +97,6 @@ void handle_special_chars(char *s, int *i, int *start, t_token **token_list) *token_list = new_token(PIPE_TOKEN, *token_list, NULL); else if (s[*i] == '\n') *token_list = new_token(NEWLINE_TOKEN, *token_list, NULL); - print_token(*token_list); if (s[*i] == '<' && s[*i + 1] == '<') (*i)++; if (s[*i] == '>' && s[*i + 1] == '>') @@ -111,4 +130,5 @@ void tokenizer(char *s, t_token **token_list, char quote_check) pos = i + 1; } } + *token_list = reverse_token_list(*token_list); } diff --git a/teest.txt b/teest.txt new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/teest.txt @@ -0,0 +1 @@ +test -- 2.47.2