From 974ab368ec30fcd68e595252668d1542a5352619 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Tue, 10 Nov 2015 15:54:40 +0300 Subject: [PATCH] Ticket #3547: code cleanup before 4.8.16 release. Move subshell stuff into subdir. Signed-off-by: Slava Zanko --- configure.ac | 1 + src/Makefile.am | 13 +- src/execute.c | 2 +- src/filemanager/command.c | 2 +- src/filemanager/layout.c | 2 +- src/filemanager/midnight.c | 2 +- src/filemanager/panel.c | 2 +- src/main.c | 2 +- src/subshell/Makefile.am | 8 + src/{subshell.c => subshell/common.c} | 225 +++++++++++++------------- src/subshell/internal.h | 29 ++++ src/subshell/proxyfunc.c | 107 ++++++++++++ src/{ => subshell}/subshell.h | 0 13 files changed, 277 insertions(+), 118 deletions(-) create mode 100644 src/subshell/Makefile.am rename src/{subshell.c => subshell/common.c} (96%) create mode 100644 src/subshell/internal.h create mode 100644 src/subshell/proxyfunc.c rename src/{ => subshell}/subshell.h (100%) diff --git a/configure.ac b/configure.ac index 91be803ab..c1c6d9577 100644 --- a/configure.ac +++ b/configure.ac @@ -526,6 +526,7 @@ src/Makefile src/consaver/Makefile src/editor/Makefile src/man2hlp/Makefile +src/subshell/Makefile src/viewer/Makefile src/diffviewer/Makefile src/filemanager/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 13edbab0d..2c6248e21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,10 @@ if USE_DIFF SUBDIRS += diffviewer endif +if ENABLE_SUBSHELL +SUBDIRS += subshell +endif + noinst_LTLIBRARIES = libinternal.la AM_CPPFLAGS = \ @@ -37,11 +41,15 @@ if USE_DIFF DIFFLIB = diffviewer/libdiffviewer.la endif +if ENABLE_SUBSHELL +SUBSHELLLIB = subshell/libsubshell.la +endif + libinternal_la_LIBADD = \ filemanager/libmcfilemanager.la \ vfs/libmc-vfs.la \ viewer/libmcviewer.la \ - $(DIFFLIB) $(EDITLIB) + $(DIFFLIB) $(EDITLIB) $(SUBSHELLLIB) mc_LDADD = \ libinternal.la \ @@ -76,9 +84,6 @@ if CHARSET libinternal_la_SOURCES += selcodepage.c selcodepage.h endif -if ENABLE_SUBSHELL - libinternal_la_SOURCES += subshell.c subshell.h -endif if ENABLE_BACKGROUND libinternal_la_SOURCES += background.c background.h diff --git a/src/execute.c b/src/execute.c index df2f12d80..550df7458 100644 --- a/src/execute.c +++ b/src/execute.c @@ -49,7 +49,7 @@ #include "filemanager/layout.h" /* use_dash() */ #include "consaver/cons.saver.h" #ifdef ENABLE_SUBSHELL -#include "subshell.h" +#include "subshell/subshell.h" #endif #include "setup.h" /* clear_before_exec */ diff --git a/src/filemanager/command.c b/src/filemanager/command.c index 7d8cee238..521f49bc1 100644 --- a/src/filemanager/command.c +++ b/src/filemanager/command.c @@ -46,7 +46,7 @@ #include "src/setup.h" /* quit */ #ifdef ENABLE_SUBSHELL -#include "src/subshell.h" +#include "src/subshell/subshell.h" #endif #include "src/execute.h" /* shell_execute */ diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index 33d5d79e2..8c56c350c 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -55,7 +55,7 @@ #include "src/viewer/mcviewer.h" /* The view widget */ #include "src/setup.h" #ifdef ENABLE_SUBSHELL -#include "src/subshell.h" +#include "src/subshell/subshell.h" #endif #include "command.h" diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 05f5ec880..fa9389cf8 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -55,7 +55,7 @@ #include "src/args.h" #ifdef ENABLE_SUBSHELL -#include "src/subshell.h" +#include "src/subshell/subshell.h" #endif #include "src/setup.h" /* variables */ #include "src/learn.h" /* learn_keys() */ diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 4abf29a1d..10a844c7e 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -63,7 +63,7 @@ #endif #include "src/keybind-defaults.h" /* global_keymap_t */ #ifdef ENABLE_SUBSHELL -#include "src/subshell.h" /* do_subshell_chdir() */ +#include "src/subshell/subshell.h" /* do_subshell_chdir() */ #endif #include "dir.h" diff --git a/src/main.c b/src/main.c index 68a45336b..7b2e70caf 100644 --- a/src/main.c +++ b/src/main.c @@ -67,7 +67,7 @@ #include "events_init.h" #include "args.h" #ifdef ENABLE_SUBSHELL -#include "subshell.h" +#include "subshell/subshell.h" #endif #include "setup.h" /* load_setup() */ diff --git a/src/subshell/Makefile.am b/src/subshell/Makefile.am new file mode 100644 index 000000000..e74a0c2e7 --- /dev/null +++ b/src/subshell/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = libsubshell.la + +libsubshell_la_SOURCES = \ + common.c \ + internal.h \ + proxyfunc.c + +AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS) diff --git a/src/subshell.c b/src/subshell/common.c similarity index 96% rename from src/subshell.c rename to src/subshell/common.c index eaab1470e..88e11f4e2 100644 --- a/src/subshell.c +++ b/src/subshell/common.c @@ -5,7 +5,31 @@ Free Software Foundation, Inc. Written by: - Slava Zanko , 2013 + Alexander Kriegisch + Aliaksey Kandratsenka + Andreas Mohr + Andrew Borodin + Andrew Borodin + Andrew V. Samoilov + Chris Owen + Claes Nästén + Egmont Koblinger + Enrico Weigelt, metux IT service + Igor Urazov + Ilia Maslakov + Leonard den Ottolander + Miguel de Icaza + Mikhail S. Pobolovets + Norbert Warmuth + Patrick Winnertz + Pavel Machek + Pavel Roskin + Pavel Tsekov + Roland Illig + Sergei Trofimovich + Slava Zanko , 2013,2015. + Timur Bakeyev + Vit Rosin This file is part of the Midnight Commander. @@ -61,11 +85,8 @@ #include "lib/util.h" #include "lib/widget.h" -#include "filemanager/midnight.h" /* current_panel */ - -#include "consaver/cons.saver.h" /* handle_console() */ -#include "setup.h" #include "subshell.h" +#include "internal.h" /*** global variables ****************************************************************************/ @@ -931,6 +952,83 @@ init_subshell_precmd (char *precmd, size_t buff_size) } } +/* --------------------------------------------------------------------------------------------- */ +/** + * Carefully quote directory name to allow entering any directory safely, + * no matter what weird characters it may contain in its name. + * NOTE: Treat directory name an untrusted data, don't allow it to cause + * executing any commands in the shell. Escape all control characters. + * Use following technique: + * + * printf(1) with format string containing a single conversion specifier, + * "b", and an argument which contains a copy of the string passed to + * subshell_name_quote() with all characters, except digits and letters, + * replaced by the backslash-escape sequence \0nnn, where "nnn" is the + * numeric value of the character converted to octal number. + * + * cd "`printf "%b" 'ABC\0nnnDEF\0nnnXYZ'`" + * + */ + +static GString * +subshell_name_quote (const char *s) +{ + GString *ret; + const char *su, *n; + const char *quote_cmd_start, *quote_cmd_end; + + if (subshell_type == FISH) + { + quote_cmd_start = "(printf \"%b\" '"; + quote_cmd_end = "')"; + } + /* TODO: When BusyBox printf is fixed, get rid of this "else if", see + http://lists.busybox.net/pipermail/busybox/2012-March/077460.html */ + /* else if (subshell_type == ASH_BUSYBOX) + { + quote_cmd_start = "\"`echo -en '"; + quote_cmd_end = "'`\""; + } */ + else + { + quote_cmd_start = "\"`printf \"%b\" '"; + quote_cmd_end = "'`\""; + } + + ret = g_string_sized_new (64); + + /* Prevent interpreting leading '-' as a switch for 'cd' */ + if (s[0] == '-') + g_string_append (ret, "./"); + + /* Copy the beginning of the command to the buffer */ + g_string_append (ret, quote_cmd_start); + + /* + * Print every character except digits and letters as a backslash-escape + * sequence of the form \0nnn, where "nnn" is the numeric value of the + * character converted to octal number. + */ + for (su = s; su[0] != '\0'; su = n) + { + n = str_cget_next_char_safe (su); + + if (str_isalnum (su)) + g_string_append_len (ret, su, n - su); + else + { + int c; + + for (c = 0; c < n - su; c++) + g_string_append_printf (ret, "\\0%03o", (unsigned char) su[c]); + } + } + + g_string_append (ret, quote_cmd_end); + + return ret; +} + /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -1182,7 +1280,7 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath) /* Make the subshell change to MC's working directory */ if (new_dir_vpath != NULL) - do_subshell_chdir (current_panel->cwd_vpath, TRUE); + do_subshell_chdir (subshell_get_cwd_from_current_panel (), TRUE); if (command == NULL) /* The user has done "C-o" from MC */ { @@ -1212,16 +1310,16 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath) { const char *pcwd; - pcwd = vfs_translate_path (vfs_path_as_str (current_panel->cwd_vpath)); + pcwd = vfs_translate_path (vfs_path_as_str (subshell_get_cwd_from_current_panel ())); if (strcmp (subshell_cwd, pcwd) != 0) *new_dir_vpath = vfs_path_from_str (subshell_cwd); /* Make MC change to the subshell's CWD */ } /* Restart the subshell if it has died by SIGHUP, SIGQUIT, etc. */ - while (!subshell_alive && quit == 0 && mc_global.tty.use_subshell) + while (!subshell_alive && subshell_get_mainloop_quit () == 0 && mc_global.tty.use_subshell) init_subshell (); - return quit; + return subshell_get_mainloop_quit (); } @@ -1330,84 +1428,6 @@ exit_subshell (void) return subshell_quit; } -/* --------------------------------------------------------------------------------------------- */ -/** - * Carefully quote directory name to allow entering any directory safely, - * no matter what weird characters it may contain in its name. - * NOTE: Treat directory name an untrusted data, don't allow it to cause - * executing any commands in the shell. Escape all control characters. - * Use following technique: - * - * printf(1) with format string containing a single conversion specifier, - * "b", and an argument which contains a copy of the string passed to - * subshell_name_quote() with all characters, except digits and letters, - * replaced by the backslash-escape sequence \0nnn, where "nnn" is the - * numeric value of the character converted to octal number. - * - * cd "`printf "%b" 'ABC\0nnnDEF\0nnnXYZ'`" - * - */ - -static GString * -subshell_name_quote (const char *s) -{ - GString *ret; - const char *su, *n; - const char *quote_cmd_start, *quote_cmd_end; - - if (subshell_type == FISH) - { - quote_cmd_start = "(printf \"%b\" '"; - quote_cmd_end = "')"; - } - /* TODO: When BusyBox printf is fixed, get rid of this "else if", see - http://lists.busybox.net/pipermail/busybox/2012-March/077460.html */ - /* else if (subshell_type == ASH_BUSYBOX) - { - quote_cmd_start = "\"`echo -en '"; - quote_cmd_end = "'`\""; - } */ - else - { - quote_cmd_start = "\"`printf \"%b\" '"; - quote_cmd_end = "'`\""; - } - - ret = g_string_sized_new (64); - - /* Prevent interpreting leading '-' as a switch for 'cd' */ - if (s[0] == '-') - g_string_append (ret, "./"); - - /* Copy the beginning of the command to the buffer */ - g_string_append (ret, quote_cmd_start); - - /* - * Print every character except digits and letters as a backslash-escape - * sequence of the form \0nnn, where "nnn" is the numeric value of the - * character converted to octal number. - */ - for (su = s; su[0] != '\0'; su = n) - { - n = str_cget_next_char_safe (su); - - if (str_isalnum (su)) - g_string_append_len (ret, su, n - su); - else - { - int c; - - for (c = 0; c < n - su; c++) - g_string_append_printf (ret, "\\0%03o", (unsigned char) su[c]); - } - } - - g_string_append (ret, quote_cmd_end); - - return ret; -} - - /* --------------------------------------------------------------------------------------------- */ /** If it actually changed the directory it returns true */ @@ -1416,7 +1436,7 @@ do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt) { char *pcwd; - pcwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_RECODE); + pcwd = vfs_path_to_str_flags (subshell_get_cwd_from_current_panel (), 0, VPF_RECODE); if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0)) { @@ -1484,7 +1504,9 @@ do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt) { char *cwd; - cwd = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_PASSWORD); + cwd = + vfs_path_to_str_flags (subshell_get_cwd_from_current_panel (), 0, + VPF_STRIP_PASSWORD); vfs_print_message (_("Warning: Cannot change to %s.\n"), cwd); g_free (cwd); } @@ -1560,27 +1582,14 @@ sigchld_handler (int sig) subshell_alive = FALSE; delete_select_channel (mc_global.tty.subshell_pty); if (WIFEXITED (status) && WEXITSTATUS (status) != FORK_FAILURE) - quit |= SUBSHELL_EXIT; /* Exited normally */ + { + int subshell_quit; + subshell_quit = subshell_get_mainloop_quit () | SUBSHELL_EXIT; /* Exited normally */ + subshell_set_mainloop_quit (subshell_quit); + } } } -#ifdef __linux__ - pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG); - - if (pid == cons_saver_pid) - { - - if (WIFSTOPPED (status)) - /* Someone has stopped cons.saver - restart it */ - kill (pid, SIGCONT); - else - { - /* cons.saver has died - disable confole saving */ - handle_console (CONSOLE_DONE); - mc_global.tty.console_flag = '\0'; - } - - } -#endif /* __linux__ */ + subshell_handle_cons_saver (); /* If we got here, some other child exited; ignore it */ } diff --git a/src/subshell/internal.h b/src/subshell/internal.h new file mode 100644 index 000000000..8395320b8 --- /dev/null +++ b/src/subshell/internal.h @@ -0,0 +1,29 @@ +/** \file internal.h + * \brief Header: internal functions and variables + */ + +#ifndef MC__SUBSHELL_INTERNAL_H +#define MC__SUBSHELL_INTERNAL_H + +/* TODO: merge content of layout.h here */ + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +const vfs_path_t *subshell_get_cwd_from_current_panel (void); +void subshell_handle_cons_saver (void); + +int subshell_get_mainloop_quit (void); +void subshell_set_mainloop_quit (const int param_quit); + + +/*** inline functions ****************************************************************************/ + +#endif /* MC__SUBSHELL_INTERNAL_H */ diff --git a/src/subshell/proxyfunc.c b/src/subshell/proxyfunc.c new file mode 100644 index 000000000..8b0cbfb86 --- /dev/null +++ b/src/subshell/proxyfunc.c @@ -0,0 +1,107 @@ +/* + Proxy functions for getting access to public variables into 'filemanager' module. + + Copyright (C) 2015 + Free Software Foundation, Inc. + + Written by: + Slava Zanko , 2015. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include +#include + +#include "lib/global.h" +#include "lib/widget.h" + +#include "src/setup.h" /* quit */ +#include "src/filemanager/midnight.h" /* current_panel */ +#include "src/consaver/cons.saver.h" /* handle_console() */ + +#include "internal.h" + +/*** global variables ****************************************************************************/ + +/* path to X clipboard utility */ + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/* --------------------------------------------------------------------------------------------- */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +const vfs_path_t * +subshell_get_cwd_from_current_panel (void) +{ + return current_panel->cwd_vpath; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +subshell_handle_cons_saver (void) +{ +#ifdef __linux__ + int status; + pid_t pid; + + pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG); + waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG); + + if (pid == cons_saver_pid) + { + + if (WIFSTOPPED (status)) + /* Someone has stopped cons.saver - restart it */ + kill (pid, SIGCONT); + else + { + /* cons.saver has died - disable console saving */ + handle_console (CONSOLE_DONE); + mc_global.tty.console_flag = '\0'; + } + + } +#endif /* __linux__ */ +} + +/* --------------------------------------------------------------------------------------------- */ + +int +subshell_get_mainloop_quit (void) +{ + return quit; +} + +/* --------------------------------------------------------------------------------------------- */ + +void +subshell_set_mainloop_quit (const int param_quit) +{ + quit = param_quit; +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/subshell.h b/src/subshell/subshell.h similarity index 100% rename from src/subshell.h rename to src/subshell/subshell.h