Ticket #3580 (new enhancement)

Opened 23 months ago

Last modified 18 months ago

Slow start because the subshell starts slow

Reported by: aleb Owned by:
Priority: major Milestone: Future Releases
Component: mc-core Version: master
Keywords: subshell Cc: andrey.gursky@…, baltazar.bz@…
Blocked By: Blocking:
Branch state: no branch Votes for changeset:

Description

On my system (Archlinux, zsh with oh-my-zsh) mc starts in 4-5 seconds which is very noticeable. When I remove ~/.zshrc, mc starts instantly.

GNU Midnight Commander 4.8.15
With subshell support as default
With support for background operations

It might worth to start the subshell on a background thread to be able to show the main UI faster. Then a rotating dash would be displayed in the command prompt and in Ctrl-O until the subshell is ready.

How can I help to add this enhancement?

Change History

comment:1 Changed 23 months ago by and

sounds like mc has trouble to detect your shell or zsh precmd_functions are botched or zsh version is too old.

after mc start at subshell

$ echo $SHELL
$ echo $ZSH_VERSION
$ echo $precmd_functions
$ declare -f _mc_precmd
Last edited 23 months ago by and (previous) (diff)

comment:2 Changed 23 months ago by aleb

After I start mc and Ctrl-O:

$ mc

$ echo $SHELL
/bin/zsh

$ echo $ZSH_VERSION
5.2

$ echo $precmd_functions
omz_termsupport_precmd _mc_precmd

$ declare -f _mc_precmd
_mc_precmd () {
        pwd >&8
        kill -STOP $$
}

(BTW, I found out the slow start of the shell was because of the large ~/.zsh_history file)

comment:3 Changed 23 months ago by and

that must be a huge ~/.zsh_history indeed :)

comment:4 Changed 21 months ago by ag

I've been hunting with strace for this bug. And it has been indeed already reported. My .bash_history is 3.5M. After

mv -i ~/.bash_history ~/.bash_history.bak

mc starts promptly. Can be 3.5M considered as huge?.. At least for bash it is so. It starts with a delay.

Using strace I've identified a couple of critical places. The following call takes the most time:

src/subshell.c

// ...cut...

    /* Set up `precmd' or equivalent for reading the subshell's CWD
     *
     * Attention! Never forget that these are *one-liners* even though the concatenated
     * substrings contain line breaks and indentation for better understanding of the
     * shell code. It is vital that each one-liner ends with a line feed character ("\n" ).
     */

    switch (subshell_type)
    {
    case BASH:
        g_snprintf (precmd, sizeof (precmd),
                    " PROMPT_COMMAND=${PROMPT_COMMAND:+$PROMPT_COMMAND\n}'pwd>&%d;kill -STOP $$'\n"
                    "PS1='\\u@\\h:\\w\\$ '\n", subshell_pipe[WRITE]);
        break;

// ...cut...

    write_all (mc_global.tty.subshell_pty, precmd, strlen (precmd)); // <-----------------------

// ...cut...

comment:5 Changed 21 months ago by zaytsev

As you can see, all this does is to send our precmd hook to the shell, which we need in order for the communication with subshell to work, so on the mc side, it doesn't actually need any time at all, but rather it blocks at the shell end.

I think you should be able to simply run it in the terminal and see how much time does it take... (or else extract in a small stand-alone program). I have no idea why shells don't seem to like it if they have huge histories, but you can try to find out.

comment:6 Changed 21 months ago by ag

  • Cc andrey.gursky@… added

comment:7 Changed 18 months ago by balta2ar

  • Cc baltazar.bz@… added
Note: See TracTickets for help on using tickets.