From a9107dbad1be67ab88f3f87ee8a2d8115744e118 Mon Sep 17 00:00:00 2001 From: d3m3t3r <46783027+d3m3t3r@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:37:24 +0000 Subject: [PATCH] Fix support for mksh mksh (MirBSD Korn shell) is handled separately as it substantially differs from pdksh (Public Domain Korn shell) based varaints. --- doc/man/mc.1.in | 8 ++++++-- lib/fileloc.h | 1 + lib/mcconfig/paths.c | 1 + lib/shell.c | 26 +++++++++++++++++++------- lib/shell.h | 3 ++- src/subshell/common.c | 24 ++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in index 0da3f9dbe..7e575adfa 100644 --- a/doc/man/mc.1.in +++ b/doc/man/mc.1.in @@ -2406,10 +2406,14 @@ and special keyboard maps in ~/.local/share/mc/inputrc (fallback ~/.inputrc). .B ash/dash users (BusyBox or Debian) may specify startup commands in ~/.local/share/mc/ashrc (fallback ~/.profile). .PP -.B ksh -users (ksh, oksh or mksh) may specify startup commands in ~/.local/share/mc/kshrc +.B ksh/oksh +users (PD ksh variants) may specify startup commands in ~/.local/share/mc/kshrc (fallback $ENV or ~/.profile). .PP +.B mksh +users (MirBSD ksh) may specify startup commands in ~/.local/share/mc/mkshrc +(fallback $ENV or ~/.mkshrc). +.PP .B zsh users may specify startup commands in ~/.local/share/mc/.zshrc (fallback ~/.zshrc). .PP diff --git a/lib/fileloc.h b/lib/fileloc.h index fe40a0fdc..fad3181bc 100644 --- a/lib/fileloc.h +++ b/lib/fileloc.h @@ -54,6 +54,7 @@ #define MC_ZSHRC_FILE ".zshrc" #define MC_ASHRC_FILE "ashrc" #define MC_KSHRC_FILE "kshrc" +#define MC_MKSHRC_FILE "mkshrc" #define MC_INPUTRC_FILE "inputrc" #define MC_CONFIG_FILE "ini" #define MC_EXT_FILE "mc.ext.ini" diff --git a/lib/mcconfig/paths.c b/lib/mcconfig/paths.c index 793ab9971..23b986bf2 100644 --- a/lib/mcconfig/paths.c +++ b/lib/mcconfig/paths.c @@ -76,6 +76,7 @@ static const struct { &mc_data_str, VFS_SHELL_PREFIX }, { &mc_data_str, MC_ASHRC_FILE }, { &mc_data_str, MC_KSHRC_FILE }, + { &mc_data_str, MC_MKSHRC_FILE }, { &mc_data_str, MC_BASHRC_FILE }, { &mc_data_str, MC_INPUTRC_FILE }, { &mc_data_str, MC_ZSHRC_FILE }, diff --git a/lib/shell.c b/lib/shell.c index d26aad50a..9d9a7f0d7 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -82,6 +82,10 @@ mc_shell_get_installed_in_system (void) mc_shell->path = g_strdup ("/bin/csh"); else if (access ("/bin/ksh", X_OK) == 0) mc_shell->path = g_strdup ("/bin/ksh"); + else if (access ("/bin/oksh", X_OK) == 0) + mc_shell->path = g_strdup ("/bin/oksh"); + else if (access ("/bin/mksh", X_OK) == 0) + mc_shell->path = g_strdup ("/bin/mksh"); /* No fish as fallback because it is so much different from other shells and * in a way exotic (even though user-friendly by name) that we should not * present it as a subshell without the user's explicit intention. We rather @@ -194,14 +198,17 @@ mc_shell_recognize_real_path (mc_shell_t *mc_shell) else if (strstr (mc_shell->path, "/ksh") != NULL || strstr (mc_shell->real_path, "/ksh") != NULL || strstr (mc_shell->path, "/oksh") != NULL - || strstr (mc_shell->real_path, "/oksh") != NULL - || strstr (mc_shell->path, "/mksh") != NULL - || strstr (mc_shell->real_path, "/mksh") != NULL) + || strstr (mc_shell->real_path, "/oksh") != NULL) { - /* Korn shell variants */ mc_shell->type = SHELL_KSH; mc_shell->name = "ksh"; } + else if (strstr (mc_shell->path, "/mksh") != NULL + || strstr (mc_shell->real_path, "/mksh") != NULL) + { + mc_shell->type = SHELL_MKSH; + mc_shell->name = "mksh"; + } else mc_shell->type = SHELL_NONE; } @@ -227,14 +234,19 @@ mc_shell_recognize_path (mc_shell_t *mc_shell) mc_shell->type = SHELL_ASH_BUSYBOX; mc_shell->name = "ash"; } - else if (strstr (mc_shell->path, "/ksh") != NULL + else if (strstr (mc_shell->path, "/ksh") != NULL || strstr (mc_shell->path, "/oksh") != NULL - || strstr (mc_shell->path, "/mksh") != NULL - || getenv ("KSH_VERSION") != NULL) + || (getenv ("KSH_VERSION") != NULL && strstr (getenv ("KSH_VERSION"), "PD KSH") != NULL)) { mc_shell->type = SHELL_KSH; mc_shell->name = "ksh"; } + else if (strstr (mc_shell->path, "/mksh") != NULL + || (getenv ("KSH_VERSION") != NULL && strstr (getenv ("KSH_VERSION"), "MIRBSD KSH") != NULL)) + { + mc_shell->type = SHELL_MKSH; + mc_shell->name = "mksh"; + } else mc_shell->type = SHELL_NONE; } diff --git a/lib/shell.h b/lib/shell.h index e2b733b91..bf5ada3ad 100644 --- a/lib/shell.h +++ b/lib/shell.h @@ -19,7 +19,8 @@ typedef enum SHELL_TCSH, SHELL_ZSH, SHELL_FISH, - SHELL_KSH + SHELL_KSH, /* Public Domain Korn shell (pdksh) and variants */ + SHELL_MKSH /* MirBSD Korn shell (mksh) */ } shell_type_t; /*** structures declarations (and typedefs of structures)*****************************************/ diff --git a/src/subshell/common.c b/src/subshell/common.c index 89eee770e..fc8a34967 100644 --- a/src/subshell/common.c +++ b/src/subshell/common.c @@ -385,6 +385,23 @@ init_subshell_child (const char *pty_name) break; + case SHELL_MKSH: + /* Do we have a custom init file ~/.local/share/mc/mkshrc? */ + init_file = mc_config_get_full_path (MC_MKSHRC_FILE); + + /* Otherwise use ~/.mkshrc */ + if (!exist_file (init_file)) + { + g_free (init_file); + init_file = g_strdup (".mkshrc"); + } + + /* Put init file to ENV variable used by mksh but only if it + * is not already set. */ + g_setenv ("ENV", init_file, FALSE); + + break; + case SHELL_ZSH: /* ZDOTDIR environment variable is the only way to point zsh * to an other rc file than the default. */ @@ -459,6 +476,7 @@ init_subshell_child (const char *pty_name) case SHELL_DASH: case SHELL_TCSH: case SHELL_KSH: + case SHELL_MKSH: execl (mc_global.shell->path, mc_global.shell->path, (char *) NULL); break; @@ -1190,6 +1208,12 @@ init_subshell_precmd (char *precmd, size_t buff_size) subshell_pipe[WRITE]); break; + case SHELL_MKSH: + g_snprintf (precmd, buff_size, + " PS1='$(pwd>&%d; kill -STOP $$)${USER:=$(id -un)}@${HOSTNAME:=$(hostname -s)}:$PWD\\$ '\n", + subshell_pipe[WRITE]); + break; + case SHELL_ZSH: g_snprintf (precmd, buff_size, " mc_print_command_buffer () { printf \"%%s\\\\n\" \"$BUFFER\" >&%d; }\n"