From 0e79be1b7ac3a4718981c12cb3c4bb6e0cde5180 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Tue, 10 Nov 2015 17:23:09 +0300 Subject: [PATCH] Introduce mc_shell_t type. Signed-off-by: Slava Zanko --- lib/Makefile.am | 1 + lib/global.c | 5 +-- lib/global.h | 9 +++-- lib/shell.h | 40 ++++++++++++++++++++ src/clipboard.c | 2 +- src/execute.c | 8 ++-- src/main.c | 21 +++++++---- src/subshell/common.c | 76 +++++++++++++++++++------------------- src/vfs/extfs/extfs.c | 2 +- tests/src/filemanager/examine_cd.c | 2 +- 10 files changed, 106 insertions(+), 60 deletions(-) create mode 100644 lib/shell.h diff --git a/lib/Makefile.am b/lib/Makefile.am index db231fc85..602fd5764 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -40,6 +40,7 @@ libmc_la_SOURCES = \ keybind.c keybind.h \ lock.c lock.h \ serialize.c serialize.h \ + shell.h \ timefmt.c timefmt.h \ timer.c timer.h diff --git a/lib/global.c b/lib/global.c index b52f91a71..58212b938 100644 --- a/lib/global.c +++ b/lib/global.c @@ -79,6 +79,8 @@ mc_global_t mc_global = { .is_right = FALSE }, + .shell = NULL, + .tty = { .skin = NULL, @@ -96,9 +98,6 @@ mc_global_t mc_global = { .subshell_pty = 0, #endif /* !ENABLE_SUBSHELL */ - .shell = NULL, - .shell_realpath = NULL, - .xterm_flag = FALSE, .disable_x11 = FALSE, .slow_terminal = FALSE, diff --git a/lib/global.h b/lib/global.h index fc2c5432e..6da449774 100644 --- a/lib/global.h +++ b/lib/global.h @@ -94,6 +94,7 @@ #endif /* !ENABLE_NLS */ #include "fs.h" +#include "shell.h" #ifdef USE_MAINTAINER_MODE #include "lib/logging.h" @@ -231,6 +232,9 @@ typedef struct gboolean is_right; /* If the selected menu was the right */ } widget; + /* The user's shell */ + mc_shell_t *shell; + struct { /* Use the specified skin */ @@ -248,15 +252,12 @@ typedef struct #endif /* !LINUX_CONS_SAVER_C */ /* If using a subshell for evaluating commands this is true */ gboolean use_subshell; + #ifdef ENABLE_SUBSHELL /* File descriptors of the pseudoterminal used by the subshell */ int subshell_pty; #endif /* !ENABLE_SUBSHELL */ - /* The user's shell */ - char *shell; - char *shell_realpath; - /* This flag is set by xterm detection routine in function main() */ /* It is used by function view_other_cmd() */ gboolean xterm_flag; diff --git a/lib/shell.h b/lib/shell.h new file mode 100644 index 000000000..231f2eedb --- /dev/null +++ b/lib/shell.h @@ -0,0 +1,40 @@ +/** \file timer.h + * \brief Header: shell structure + */ + +#ifndef MC_SHELL_H +#define MC_SHELL_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +typedef enum +{ + BASH, + ASH_BUSYBOX, /* BusyBox default shell (ash) */ + DASH, /* Debian variant of ash */ + TCSH, + ZSH, + FISH +} shell_type_t; + + +/*** structures declarations (and typedefs of structures)*****************************************/ + +typedef struct +{ + shell_type_t type; + const char *name; + char *path; + char *real_path; +} mc_shell_t; + + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +/*** inline functions **************************************************/ + +#endif /* MC_SHELL_H */ diff --git a/src/clipboard.c b/src/clipboard.c index 26745f6d0..8a1364435 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -85,7 +85,7 @@ clipboard_file_to_ext_clip (const gchar * event_group_name, const gchar * event_ cmd = g_strconcat (clipboard_store_path, " ", tmp, " 2>/dev/null", (char *) NULL); if (cmd != NULL) - my_system (EXECUTE_AS_SHELL, mc_global.tty.shell, cmd); + my_system (EXECUTE_AS_SHELL, mc_global.shell->path, cmd); g_free (cmd); g_free (tmp); diff --git a/src/execute.c b/src/execute.c index 550df7458..b778a731f 100644 --- a/src/execute.c +++ b/src/execute.c @@ -430,12 +430,12 @@ shell_execute (const char *command, int flags) #ifdef ENABLE_SUBSHELL if (mc_global.tty.use_subshell) if (subshell_state == INACTIVE) - do_execute (mc_global.tty.shell, cmd ? cmd : command, flags | EXECUTE_AS_SHELL); + do_execute (mc_global.shell->path, cmd ? cmd : command, flags | EXECUTE_AS_SHELL); else message (D_ERROR, MSG_ERROR, _("The shell is already running a command")); else #endif /* ENABLE_SUBSHELL */ - do_execute (mc_global.tty.shell, cmd ? cmd : command, flags | EXECUTE_AS_SHELL); + do_execute (mc_global.shell->path, cmd ? cmd : command, flags | EXECUTE_AS_SHELL); g_free (cmd); } @@ -445,7 +445,7 @@ shell_execute (const char *command, int flags) void exec_shell (void) { - do_execute (mc_global.tty.shell, 0, 0); + do_execute (mc_global.shell->path, 0, 0); } /* --------------------------------------------------------------------------------------------- */ @@ -496,7 +496,7 @@ toggle_panels (void) fprintf (stderr, _("Type 'exit' to return to the Midnight Commander")); fprintf (stderr, "\n\r\n\r"); - my_system (EXECUTE_INTERNAL, mc_global.tty.shell, NULL); + my_system (EXECUTE_INTERNAL, mc_global.shell->path, NULL); } else get_key_code (0); diff --git a/src/main.c b/src/main.c index 7b2e70caf..5cdbd8728 100644 --- a/src/main.c +++ b/src/main.c @@ -168,6 +168,8 @@ OS_Setup (void) const char *datadir_env; + mc_global.shell = g_new0 (mc_shell_t, 1); + shell_env = getenv ("SHELL"); if ((shell_env == NULL) || (shell_env[0] == '\0')) { @@ -176,18 +178,18 @@ OS_Setup (void) pwd = getpwuid (geteuid ()); if (pwd != NULL) - mc_global.tty.shell = g_strdup (pwd->pw_shell); + mc_global.shell->path = g_strdup (pwd->pw_shell); } else /* 1st choice: SHELL environment variable */ - mc_global.tty.shell = g_strdup (shell_env); + mc_global.shell->path = g_strdup (shell_env); - if ((mc_global.tty.shell == NULL) || (mc_global.tty.shell[0] == '\0')) + if ((mc_global.shell->path == NULL) || (mc_global.shell->path[0] == '\0')) { - g_free (mc_global.tty.shell); - mc_global.tty.shell = mc_get_system_shell (); + g_free (mc_global.shell->path); + mc_global.shell->path = mc_get_system_shell (); } - mc_global.tty.shell_realpath = mc_realpath (mc_global.tty.shell, rp_shell); + mc_global.shell->real_path = mc_realpath (mc_global.shell->path, rp_shell); /* This is the directory, where MC was installed, on Unix this is DATADIR */ /* and can be overriden by the MC_DATADIR environment variable */ @@ -301,7 +303,9 @@ main (int argc, char *argv[]) startup_exit_falure: fprintf (stderr, _("Failed to run:\n%s\n"), mcerror->message); g_error_free (mcerror); - g_free (mc_global.tty.shell); + + g_free (mc_global.shell->path); + g_free (mc_global.shell); startup_exit_ok: str_uninit_strings (); mc_timer_destroy (mc_global.timer); @@ -508,7 +512,8 @@ main (int argc, char *argv[]) } g_free (last_wd_string); - g_free (mc_global.tty.shell); + g_free (mc_global.shell->path); + g_free (mc_global.shell); done_key (); diff --git a/src/subshell/common.c b/src/subshell/common.c index c5eb4f6a6..bc297af61 100644 --- a/src/subshell/common.c +++ b/src/subshell/common.c @@ -132,15 +132,15 @@ enum }; /* Subshell type (gleaned from the SHELL environment variable, if available) */ -static enum -{ - BASH, - ASH_BUSYBOX, /* BusyBox default shell (ash) */ - DASH, /* Debian variant of ash */ - TCSH, - ZSH, - FISH -} subshell_type; +//static enum +//{ +// BASH, +// ASH_BUSYBOX, /* BusyBox default shell (ash) */ +// DASH, /* Debian variant of ash */ +// TCSH, +// ZSH, +// FISH +//} subshell_type; /*** file scope variables ************************************************************************/ @@ -280,7 +280,7 @@ init_subshell_child (const char *pty_name) putenv (g_strdup (sid_str)); } - switch (subshell_type) + switch (mc_global.shell->type) { case BASH: /* Do we have a custom init file ~/.local/share/mc/bashrc? */ @@ -338,7 +338,7 @@ init_subshell_child (const char *pty_name) break; default: - fprintf (stderr, __FILE__ ": unimplemented subshell type %d\r\n", subshell_type); + fprintf (stderr, __FILE__ ": unimplemented subshell type %d\r\n", mc_global.shell->type); my_exit (FORK_FAILURE); } @@ -363,16 +363,16 @@ init_subshell_child (const char *pty_name) /* Execute the subshell at last */ - switch (subshell_type) + switch (mc_global.shell->type) { case BASH: - execl (mc_global.tty.shell, "bash", "-rcfile", init_file, (char *) NULL); + execl (mc_global.shell->path, "bash", "-rcfile", init_file, (char *) NULL); break; case ZSH: /* Use -g to exclude cmds beginning with space from history * and -Z to use the line editor on non-interactive term */ - execl (mc_global.tty.shell, "zsh", "-Z", "-g", (char *) NULL); + execl (mc_global.shell->path, "zsh", "-Z", "-g", (char *) NULL); break; @@ -380,7 +380,7 @@ init_subshell_child (const char *pty_name) case DASH: case TCSH: case FISH: - execl (mc_global.tty.shell, mc_global.tty.shell, (char *) NULL); + execl (mc_global.shell->path, mc_global.shell->path, (char *) NULL); break; default: @@ -805,22 +805,22 @@ init_subshell_type (void) /* Find out what type of shell we have. Also consider real paths (resolved symlinks) * because e.g. csh might point to tcsh, ash to dash or busybox, sh to anything. */ - if (strstr (mc_global.tty.shell, "/zsh") != NULL - || strstr (mc_global.tty.shell_realpath, "/zsh") != NULL || getenv ("ZSH_VERSION") != NULL) + if (strstr (mc_global.shell->path, "/zsh") != NULL + || strstr (mc_global.shell->real_path, "/zsh") != NULL || getenv ("ZSH_VERSION") != NULL) /* Also detects ksh symlinked to zsh */ - subshell_type = ZSH; - else if (strstr (mc_global.tty.shell, "/tcsh") != NULL - || strstr (mc_global.tty.shell_realpath, "/tcsh") != NULL) + mc_global.shell->type = ZSH; + else if (strstr (mc_global.shell->path, "/tcsh") != NULL + || strstr (mc_global.shell->real_path, "/tcsh") != NULL) /* Also detects csh symlinked to tcsh */ - subshell_type = TCSH; - else if (strstr (mc_global.tty.shell, "/fish") != NULL - || strstr (mc_global.tty.shell_realpath, "/fish") != NULL) - subshell_type = FISH; - else if (strstr (mc_global.tty.shell, "/dash") != NULL - || strstr (mc_global.tty.shell_realpath, "/dash") != NULL) + mc_global.shell->type = TCSH; + else if (strstr (mc_global.shell->path, "/fish") != NULL + || strstr (mc_global.shell->real_path, "/fish") != NULL) + mc_global.shell->type = FISH; + else if (strstr (mc_global.shell->path, "/dash") != NULL + || strstr (mc_global.shell->real_path, "/dash") != NULL) /* Debian ash (also found if symlinked to by ash/sh) */ - subshell_type = DASH; - else if (strstr (mc_global.tty.shell_realpath, "/busybox") != NULL) + mc_global.shell->type = DASH; + else if (strstr (mc_global.shell->real_path, "/busybox") != NULL) { /* If shell is symlinked to busybox, assume it is an ash, even though theoretically * it could also be a hush (a mini shell for non-MMU systems deactivated by default). @@ -829,11 +829,11 @@ init_subshell_type (void) * Sometimes even bash is symlinked to busybox (CONFIG_FEATURE_BASH_IS_ASH option), * so we need to check busybox symlinks *before* checking for the name "bash" * in order to avoid that case. */ - subshell_type = ASH_BUSYBOX; + mc_global.shell->type = ASH_BUSYBOX; } - else if (strstr (mc_global.tty.shell, "/bash") != NULL || getenv ("BASH") != NULL) + else if (strstr (mc_global.shell->path, "/bash") != NULL || getenv ("BASH") != NULL) /* If bash is not symlinked to busybox, it is safe to assume it is a real bash */ - subshell_type = BASH; + mc_global.shell->type = BASH; else { mc_global.tty.use_subshell = FALSE; @@ -856,7 +856,7 @@ init_subshell_type (void) static void init_subshell_precmd (char *precmd, size_t buff_size) { - switch (subshell_type) + switch (mc_global.shell->type) { case BASH: g_snprintf (precmd, buff_size, @@ -978,7 +978,7 @@ subshell_name_quote (const char *s) const char *su, *n; const char *quote_cmd_start, *quote_cmd_end; - if (subshell_type == FISH) + if (mc_global.shell->type == FISH) { quote_cmd_start = "(printf \"%b\" '"; quote_cmd_end = "')"; @@ -1096,7 +1096,7 @@ init_subshell (void) /* Create a pipe for receiving the subshell's CWD */ - if (subshell_type == TCSH) + if (mc_global.shell->type == TCSH) { g_snprintf (tcsh_fifo, sizeof (tcsh_fifo), "%s/mc.pipe.%d", mc_tmpdir (), (int) getpid ()); @@ -1155,7 +1155,7 @@ init_subshell (void) * shell code. It is vital that each one-liner ends with a line feed character ("\n" ). */ - switch (subshell_type) + switch (mc_global.shell->type) { case BASH: g_snprintf (precmd, sizeof (precmd), @@ -1414,7 +1414,7 @@ exit_subshell (void) if (subshell_quit) { - if (subshell_type == TCSH) + if (mc_global.shell->type == TCSH) { if (unlink (tcsh_fifo) == -1) fprintf (stderr, "Cannot remove named pipe %s: %s\r\n", @@ -1488,7 +1488,7 @@ do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt) bPathNotEq = strcmp (subshell_cwd, pcwd) != 0; - if (bPathNotEq && subshell_type == TCSH) + if (bPathNotEq && mc_global.shell->type == TCSH) { char rp_subshell_cwd[PATH_MAX]; char rp_current_panel_cwd[PATH_MAX]; @@ -1517,7 +1517,7 @@ do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt) } /* Really escape Zsh history */ - if (subshell_type == ZSH) + if (mc_global.shell->type == ZSH) { /* Per Zsh documentation last command prefixed with space lingers in the internal history * until the next command is entered before it vanishes. To make it vanish right away, diff --git a/src/vfs/extfs/extfs.c b/src/vfs/extfs/extfs.c index c9144c501..52458c6ca 100644 --- a/src/vfs/extfs/extfs.c +++ b/src/vfs/extfs/extfs.c @@ -848,7 +848,7 @@ extfs_cmd (const char *str_extfs_cmd, struct archive *archive, g_free (quoted_archive_name); open_error_pipe (); - retval = my_system (EXECUTE_AS_SHELL, mc_global.tty.shell, cmd); + retval = my_system (EXECUTE_AS_SHELL, mc_global.shell->path, cmd); g_free (cmd); close_error_pipe (D_ERROR, NULL); return retval; diff --git a/tests/src/filemanager/examine_cd.c b/tests/src/filemanager/examine_cd.c index bbb5c70cf..572f16f5b 100644 --- a/tests/src/filemanager/examine_cd.c +++ b/tests/src/filemanager/examine_cd.c @@ -35,7 +35,7 @@ #include "src/filemanager/midnight.h" #include "src/filemanager/tree.h" #ifdef ENABLE_SUBSHELL -#include "src/subshell.h" +#include "src/subshell/subshell.h" #endif /* ENABLE_SUBSHELL */ #include "src/filemanager/command.c" -- 2.11.4.GIT