diff options
| author | _ov4 <ov4@ov4.org> | 2026-09-16 11:56:49 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-09-16 11:56:49 +0000 |
| commit | a692ff50c9c0ef169a2c672ad5d9a063a3818f9e (patch) | |
| tree | 83e16ebd99fbcb243203ef861297973cbfb1bef4 | |
| parent | e489a2db5a1e56e66f6df12642ad8cfd988d4b30 (diff) | |
merge eval_exe and eval_subshell, and fix typo
| -rw-r--r-- | include/eval.h | 3 | ||||
| -rw-r--r-- | src/eval.cc | 121 |
2 files changed, 46 insertions, 78 deletions
diff --git a/include/eval.h b/include/eval.h index 214a1ae..0466cb4 100644 --- a/include/eval.h +++ b/include/eval.h @@ -5,7 +5,8 @@ namespace ov4 { -int eval_exe(const std::string &s, bool is_aync); +int eval_exe(const string &s, bool is_async); +int eval_exe(const string &s, bool is_async, const T_lexer *lexer_instance, size_t i); int eval_tree_cd(size_t i, const T_lexer &lexer_instance, bool inside_subshell); void eval(char *cmdline); diff --git a/src/eval.cc b/src/eval.cc index 6d16cf7..41cd5b0 100644 --- a/src/eval.cc +++ b/src/eval.cc @@ -30,41 +30,61 @@ extern char **environ; namespace ov4 { -int eval_exe(const string &s, bool is_aync) +int eval_exe(const string &s, bool is_async) +{ + return eval_exe(s, is_async, nullptr, string::npos); +} + +int eval_exe(const string &s, bool is_async, const T_lexer *lexer_instance, size_t i) { loggerln("eval_exe: receive {}", s); + bool task_type_is_subshell = false; char cmdline[MAXLINE]; - strcpy(cmdline, s.c_str()); char arg[MAXARGS][MAXLINE]; char *argv[MAXARGS]; - for (int i = 0 ; i < MAXARGS; i++) + char cmd_c[MAXLINE]; + + // subshell type + if (lexer_instance != nullptr) { - argv[i] = &arg[i][0]; - } - parseline(cmdline, argv); + task_type_is_subshell = true; + strcpy(cmdline, "SUBSHELL"); + } + // command type + else + { + task_type_is_subshell = false; + strcpy(cmdline, s.c_str()); + + for (int i = 0 ; i < MAXARGS; i++) + { + argv[i] = &arg[i][0]; + } + parseline(cmdline, argv); - if (argv == nullptr || argv[0] == nullptr) return 0; + if (argv == nullptr || argv[0] == nullptr) return 0; - if (exe_bultin_command(argv)) return 0; + if (exe_bultin_command(argv)) return 0; + + string cmd = find_cmd(argv[0]); + strcpy(cmd_c, cmd.c_str()); + } // block_io signals can stop shell // when child is at foreground, parent shell is at background - sigprocmask(SIG_BLOCK, &block_io, nullptr); + sigprocmask(SIG_BLOCK, &block_io, nullptr); sigset_t prev; block_all(&prev); - string cmd = find_cmd(argv[0]); - const char* cmd_c = cmd.c_str(); - shell_pgid = getpgid(0); pid_t pid = fork(); if (pid == 0) // child { setpgid(0, 0); - if (!is_aync) // foreground + if (!is_async) // foreground tcsetpgrp(tty_fd, getpgrp()); sigprocmask(SIG_SETMASK, &prev, nullptr); @@ -72,6 +92,15 @@ int eval_exe(const string &s, bool is_aync) // program inside execve may use SIGTTIN/SIGTTOU // so just restore in child sigprocmask(SIG_UNBLOCK, &block_io, nullptr); + + // subshell + if (task_type_is_subshell) + { + eval_tree_cd(i, *lexer_instance, true); + exit(0); + } + + // normal command execve(cmd_c, argv, environ); // execve: if success, never returns @@ -110,7 +139,7 @@ int eval_exe(const string &s, bool is_aync) exit_required_pid = pid; - if (!is_aync) // foreground + if (!is_async) // foreground { addjob(pid, FG, cmdline); sigset_t prev_with_sigchld_blocked = prev; @@ -138,68 +167,6 @@ int eval_exe(const string &s, bool is_aync) return 0; } -int eval_subshell(size_t i, const T_lexer &lexer_instance) -{ - println("eval_tree_cd: processing subshell"); - - // TODO: implement async - bool is_aync = false; - - char cmdline[] = "subshell"; - - // block_io signals can stop shell - // when child is at foreground, parent shell is at background - sigprocmask(SIG_BLOCK, &block_io, nullptr); - - sigset_t prev; - block_all(&prev); - - shell_pgid = getpgid(0); - pid_t pid = fork(); - - if (pid == 0) // child - { - setpgid(0, 0); - if (!is_aync) // foreground - tcsetpgrp(tty_fd, getpgrp()); - - sigprocmask(SIG_SETMASK, &prev, nullptr); - - // program inside execve may use SIGTTIN/SIGTTOU - // so just restore in child - sigprocmask(SIG_UNBLOCK, &block_io, nullptr); - eval_tree_cd(i, lexer_instance, true); - exit(0); - } - - // parent - - exit_required_pid = pid; - - if (!is_aync) // foreground - { - addjob(pid, FG, cmdline); - sigset_t prev_with_sigchld_blocked = prev; - sigaddset(&prev_with_sigchld_blocked, SIGCHLD); - sigprocmask(SIG_SETMASK, &prev_with_sigchld_blocked, NULL); - waitfg(pid); - sigprocmask(SIG_SETMASK, &prev, NULL); - - return exit_code; - } - else // background - { - addjob(pid, BG, cmdline); - sigprocmask(SIG_SETMASK, &prev, NULL); - cout << "[" << pid2jid(pid) << "] (" << pid << ") " << cmdline; - - // POSIX: - // async command returns 0 immediately - // TODO: recurring async - return 0; - } -} - int eval_tree_cd(size_t i, const T_lexer &lexer_instance, bool inside_subshell) { // TODO: async @@ -213,7 +180,7 @@ int eval_tree_cd(size_t i, const T_lexer &lexer_instance, bool inside_subshell) // fork itself if (lexer_instance.ast[i].subshell && !inside_subshell) { - eval_subshell(i, lexer_instance); + eval_exe("", false, &lexer_instance, i); return 0; } |
