Fix support for mksh

mksh (MirBSD Korn shell) is handled separately as it substantially
differs from pdksh (Public Domain Korn shell) based varaints.
This commit is contained in:
d3m3t3r 2024-11-07 21:37:24 +00:00
parent c3b9d69147
commit a9107dbad1
6 changed files with 53 additions and 10 deletions

View File

@ -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

View File

@ -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"

View File

@ -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 },

View File

@ -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;
}

View File

@ -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)*****************************************/

View File

@ -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"