From 312c3f0d46ee749b2e4f4b918ff26c082a4b7445 Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Sat, 12 Oct 2024 21:06:30 +0200 Subject: [PATCH] Terminal: Move some boilerplate setup code outside of the child shell process Salvaged from @zwim's original code in #12384 --- plugins/terminal.koplugin/main.lua | 64 +++++++++++++++++------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/plugins/terminal.koplugin/main.lua b/plugins/terminal.koplugin/main.lua index ec9647258..4b1dcbcac 100644 --- a/plugins/terminal.koplugin/main.lua +++ b/plugins/terminal.koplugin/main.lua @@ -106,6 +106,7 @@ function Terminal:getDefaultShellExecutable() "sh", "dash", "ash", + "hush", "zsh", "ksh", "mksh", @@ -161,7 +162,7 @@ function Terminal:spawnShell(cols, rows) return false end if C.unlockpt(self.ptmx) ~= 0 then - logger.err("Terminal: can not unockpt:", ffi.string(C.strerror(ffi.errno()))) + logger.err("Terminal: can not unlockpt:", ffi.string(C.strerror(ffi.errno()))) C.close(self.ptmx) return false end @@ -177,6 +178,29 @@ function Terminal:spawnShell(cols, rows) logger.dbg("Terminal: slave_pty", self.slave_pty) + -- Prepare shell call + local function get_readline_wrapper() + if self:isExecutable("rlfe") then + return "rlfe" + elseif self:isExecutable("rlwrap") then + return "rlwrap" + end + end + local profile_file = "./plugins/terminal.koplugin/profile" + local rlw = get_readline_wrapper() + local shell = G_reader_settings:readSetting("terminal_shell") + local args = {} + if shell:find("bash") then + args = { "--rcfile", profile_file} + end + + if not self:isExecutable(shell) then + UIManager:show(InfoMessage:new{ + text = _("Shell is not executable"), + }) + return false + end + local pid = C.fork() if pid < 0 then logger.err("Terminal: fork failed:", ffi.string(C.strerror(ffi.errno()))) @@ -209,7 +233,6 @@ function Terminal:spawnShell(cols, rows) end end - local profile_file = "./plugins/terminal.koplugin/profile" C.setenv("TERM", "vt52", 1) C.setenv("ENV", profile_file, 1) -- when bash is started as sh C.setenv("BASH_ENV", profile_file, 1) -- when bash is started non-interactive @@ -218,27 +241,8 @@ function Terminal:spawnShell(cols, rows) C.setenv("ANDROID", "ANDROID", 1) end - local function get_readline_wrapper() - if self:isExecutable("rlfe") then - return "rlfe" - elseif self:isExecutable("rlwrap") then - return "rlwrap" - else - return - end - end - - -- Here we use an existing readline wrapper - local rlw = get_readline_wrapper() - local shell = G_reader_settings:readSetting("terminal_shell") - - local args = {} - if shell:find("bash") then - args = { "--rcfile", profile_file} - end - - if not self:isExecutable(shell) - or (rlw and C.execlp(rlw, rlw, shell, unpack(args)) ~= 0) + -- Here we attempt to use an existing readline wrapper + if (rlw and C.execlp(rlw, rlw, shell, unpack(args)) ~= 0) or C.execlp(shell, shell, unpack(args)) ~= 0 then -- the following two prints are shown in the terminal emulator. @@ -658,10 +662,16 @@ Aliases (shortcuts) to frequently used commands can be placed in: if new_shell == "" then new_shell = "sh" end - G_reader_settings:saveSetting("terminal_shell", new_shell) - UIManager:close(self.shell_dialog) - if touchmenu_instance then - touchmenu_instance:updateItems() + if self:isExecutable(new_shell) then + G_reader_settings:saveSetting("terminal_shell", new_shell) + UIManager:close(self.shell_dialog) + if touchmenu_instance then + touchmenu_instance:updateItems() + end + else + UIManager:show(InfoMessage:new{ + text = _("Shell is not executable"), + }) end end },