Ticket #3547: code cleanup before 4.8.16 release.

Move subshell stuff into subdir.

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2015-11-10 15:54:40 +03:00 committed by Andrew Borodin
parent 24d09babd8
commit 974ab368ec
13 changed files with 277 additions and 118 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

8
src/subshell/Makefile.am Normal file
View File

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

View File

@ -5,7 +5,31 @@
Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2013
Alexander Kriegisch <Alexander@Kriegisch.name>
Aliaksey Kandratsenka <alk@tut.by>
Andreas Mohr <and@gmx.li>
Andrew Borodin <aborodin@vmail.ru>
Andrew Borodin <borodin@borodin.zarya>
Andrew V. Samoilov <sav@bcs.zp.ua>
Chris Owen <chris@candu.co.uk>
Claes Nästén <me@pekdon.net>
Egmont Koblinger <egmont@gmail.com>
Enrico Weigelt, metux IT service <weigelt@metux.de>
Igor Urazov <z0rc3r@gmail.com>
Ilia Maslakov <il.smind@gmail.com>
Leonard den Ottolander <leonard@den.ottolander.nl>
Miguel de Icaza <miguel@novell.com>
Mikhail S. Pobolovets <styx.mp@gmail.com>
Norbert Warmuth <nwarmuth@privat.circular.de>
Patrick Winnertz <winnie@debian.org>
Pavel Machek <pavel@suse.cz>
Pavel Roskin <proski@gnu.org>
Pavel Tsekov <ptsekov@gmx.net>
Roland Illig <roland.illig@gmx.de>
Sergei Trofimovich <slyfox@inbox.ru>
Slava Zanko <slavazanko@gmail.com>, 2013,2015.
Timur Bakeyev <mc@bat.ru>
Vit Rosin <vit_r@list.ru>
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 */
}
}
#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';
int subshell_quit;
subshell_quit = subshell_get_mainloop_quit () | SUBSHELL_EXIT; /* Exited normally */
subshell_set_mainloop_quit (subshell_quit);
}
}
#endif /* __linux__ */
}
subshell_handle_cons_saver ();
/* If we got here, some other child exited; ignore it */
}

29
src/subshell/internal.h Normal file
View File

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

107
src/subshell/proxyfunc.c Normal file
View File

@ -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 <slavazanko@gmail.com>, 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <sys/wait.h>
#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;
}
/* --------------------------------------------------------------------------------------------- */