Ticket #3689: 3689-bash-subshell-V3.patch

File 3689-bash-subshell-V3.patch, 2.8 KB (added by alllexx88, 8 years ago)
  • src/subshell/common.c

    a b  
    355355    switch (mc_global.shell->type) 
    356356    { 
    357357    case SHELL_BASH: 
    358         execl (mc_global.shell->path, "bash", "-rcfile", init_file, (char *) NULL); 
     358        execl (mc_global.shell->path, mc_global.shell->name, "-rcfile", init_file, (char *) NULL); 
    359359        break; 
    360360 
    361361    case SHELL_ZSH: 
  • lib/shell.c

  • lib/shell.c

    old new  
    3333#include <stdarg.h> 
    3434#include <stdio.h> 
    3535#include <stdlib.h> 
     36#include <sys/wait.h> 
     37#include <unistd.h> 
    3638 
    3739#include "global.h" 
    3840#include "util.h" 
     
    191193        mc_shell->type = SHELL_NONE; 
    192194} 
    193195 
     196/* --------------------------------------------------------------------------------------------- 
     197   This function returns TRUE for a shell if it has an internal variable with respective name. 
     198   We unset environmental variable of the same name in the child fork to make sure it's internal. 
     199   --------------------------------------------------------------------------------------------- */ 
     200static gboolean 
     201mc_shell_internal_variable_set (mc_shell_t * mc_shell, const char * name) 
     202{ 
     203    pid_t cpid, w; 
     204    int status; 
     205    char *command; 
     206 
     207    command = g_strdup_printf ("([ -z \"${%s+x}\" ] && exit 1) || exit 0", name); 
     208 
     209    cpid = fork(); 
     210    if (cpid == -1) { 
     211        /* failed to fork */ 
     212        g_free (command); 
     213        return FALSE; 
     214    } 
     215 
     216   if (cpid == 0) {            /* Code executed by child */ 
     217        unsetenv(name); 
     218        execl(mc_shell->path, mc_shell->path, "-c", command, (char *) NULL); 
     219        /* execl failed */ 
     220        exit(1); 
     221   } else {                    /* Code executed by parent */ 
     222        g_free (command); 
     223        do { 
     224            w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); 
     225            if (w == -1) { 
     226                /* witpid error */ 
     227                return FALSE; 
     228            } 
     229        } while (!WIFEXITED(status) && !WIFSIGNALED(status)); 
     230 
     231        return (WIFEXITED(status)) && (WEXITSTATUS(status) == 0); 
     232    } 
     233} 
     234 
    194235/* --------------------------------------------------------------------------------------------- */ 
    195236 
    196237static void 
    197238mc_shell_recognize_path (mc_shell_t * mc_shell) 
    198239{ 
    199     /* If shell is not symlinked to busybox, it is safe to assume it is a real shell */ 
    200     if (strstr (mc_shell->path, "/bash") != NULL || getenv ("BASH") != NULL) 
     240    /* If shell is not symlinked to busybox, it is safe to assume it is a real shell 
     241       Let's assume shell is bash if BASH internal variable is set */ 
     242    if (mc_shell_internal_variable_set (mc_shell, "BASH")) 
    201243    { 
    202244        mc_shell->type = SHELL_BASH; 
    203         mc_shell->name = "bash"; 
     245        mc_shell->name = mc_shell->path; 
    204246    } 
    205247    else if (strstr (mc_shell->path, "/sh") != NULL || getenv ("SH") != NULL) 
    206248    {