Exemple #1
0
void
tty_change_screen_size (void)
{
#if defined(TIOCGWINSZ) && NCURSES_VERSION_MAJOR >= 4
    struct winsize winsz;

    winsz.ws_col = winsz.ws_row = 0;

#ifndef NCURSES_VERSION
    tty_noraw_mode ();
    tty_reset_screen ();
#endif

    /* Ioctl on the STDIN_FILENO */
    ioctl (fileno (stdout), TIOCGWINSZ, &winsz);
    if (winsz.ws_col != 0 && winsz.ws_row != 0)
    {
#if defined(NCURSES_VERSION) && defined(HAVE_RESIZETERM)
        resizeterm (winsz.ws_row, winsz.ws_col);
        clearok (stdscr, TRUE); /* sigwinch's should use a semaphore! */
#else
        COLS = winsz.ws_col;
        LINES = winsz.ws_row;
#endif
    }
#endif /* defined(TIOCGWINSZ) || NCURSES_VERSION_MAJOR >= 4 */

#ifdef ENABLE_SUBSHELL
    if (mc_global.tty.use_subshell)
        tty_resize (mc_global.tty.subshell_pty);
#endif
}
Exemple #2
0
void
tty_change_screen_size (void)
{
    SLtt_get_screen_size ();
    SLsmg_reinit_smg ();

#ifdef ENABLE_SUBSHELL
    if (mc_global.tty.use_subshell)
        tty_resize (mc_global.tty.subshell_pty);
#endif
}
Exemple #3
0
static void
init_subshell_child (const char *pty_name)
{
    char *init_file = NULL;
    pid_t mc_sid;

    (void) pty_name;
    setsid ();                  /* Get a fresh terminal session */

    /* Make sure that it has become our controlling terminal */

    /* Redundant on Linux and probably most systems, but just in case: */

#ifdef TIOCSCTTY
    ioctl (subshell_pty_slave, TIOCSCTTY, 0);
#endif

    /* Configure its terminal modes and window size */

    /* Set up the pty with the same termios flags as our own tty */
    if (tcsetattr (subshell_pty_slave, TCSANOW, &shell_mode))
    {
        fprintf (stderr, "Cannot set pty terminal modes: %s\r\n", unix_error_string (errno));
        my_exit (FORK_FAILURE);
    }

    /* Set the pty's size (80x25 by default on Linux) according to the */
    /* size of the real terminal as calculated by ncurses, if possible */
    tty_resize (subshell_pty_slave);

    /* Set up the subshell's environment and init file name */

    /* It simplifies things to change to our home directory here, */
    /* and the user's startup file may do a 'cd' command anyway   */
    {
        int ret;
        ret = chdir (mc_config_get_home_dir ());        /* FIXME? What about when we re-run the subshell? */
        (void) ret;
    }

    /* Set MC_SID to prevent running one mc from another */
    mc_sid = getsid (0);
    if (mc_sid != -1)
    {
        char sid_str[BUF_SMALL];
        g_snprintf (sid_str, sizeof (sid_str), "MC_SID=%ld", (long) mc_sid);
        putenv (g_strdup (sid_str));
    }

    switch (subshell_type)
    {
    case BASH:
        init_file = mc_config_get_full_path ("bashrc");

        if (access (init_file, R_OK) == -1)
        {
            g_free (init_file);
            init_file = g_strdup (".bashrc");
        }

        /* Make MC's special commands not show up in bash's history */
        putenv ((char *) "HISTCONTROL=ignorespace");

        /* Allow alternative readline settings for MC */
        {
            char *input_file = mc_config_get_full_path ("inputrc");
            if (access (input_file, R_OK) == 0)
            {
                char *putenv_str = g_strconcat ("INPUTRC=", input_file, NULL);
                putenv (putenv_str);
                g_free (putenv_str);
            }
            g_free (input_file);
        }

        break;

    /* TODO: Find a way to pass initfile to TCSH and ZSH */
    case TCSH:
    case ZSH:
    case FISH:
        break;

    default:
        fprintf (stderr, __FILE__ ": unimplemented subshell type %d\r\n", subshell_type);
        my_exit (FORK_FAILURE);
    }

    /* Attach all our standard file descriptors to the pty */

    /* This is done just before the fork, because stderr must still      */
    /* be connected to the real tty during the above error messages; */
    /* otherwise the user will never see them.                   */

    dup2 (subshell_pty_slave, STDIN_FILENO);
    dup2 (subshell_pty_slave, STDOUT_FILENO);
    dup2 (subshell_pty_slave, STDERR_FILENO);

    close (subshell_pipe[READ]);
    close (subshell_pty_slave); /* These may be FD_CLOEXEC, but just in case... */
    /* Close master side of pty.  This is important; apart from */
    /* freeing up the descriptor for use in the subshell, it also       */
    /* means that when MC exits, the subshell will get a SIGHUP and     */
    /* exit too, because there will be no more descriptors pointing     */
    /* at the master side of the pty and so it will disappear.  */
    close (mc_global.tty.subshell_pty);

    /* Execute the subshell at last */

    switch (subshell_type)
    {
    case BASH:
        execl (mc_global.tty.shell, "bash", "-rcfile", init_file, (char *) NULL);
        break;

    case TCSH:
        execl (mc_global.tty.shell, "tcsh", (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);

        break;

    case FISH:
        execl (mc_global.tty.shell, "fish", (char *) NULL);
        break;
    }

    /* If we get this far, everything failed miserably */
    g_free (init_file);
    my_exit (FORK_FAILURE);
}