Skip to content

🐛 delta 0.8.3 leaves terminal in an inconsistent state on exit #681

@abbeyj

Description

@abbeyj

This seems similar to #463, but can still be reproduced with delta 0.8.3. Using CentOS 7, less version 458 from package less-458-9.el7.x86_64.

Run delta with no command line arguments. It will print out the message:

The main way to use delta is to configure it as the pager for git: see https://github.com/dandavison/delta#configuration. You can also use delta to diff two files: `delta file_A file_B`.

It will exit and return to the shell, but the shell prompt will not be drawn.

When using delta --paging=never, the problem does not occur.

There seems to be a race condition Sometimes this problem will occur the first time I run delta, but other times it will work correctly. Running delta 3 or 4 times in a row will usually reproduce the problem.

Even more rarely, the terminal will be left with echo turned off (like stty -echo). This can be reproduced by running delta a bunch of times in a row, e.g.

for i in $(seq 1 100); do delta; done; echo Done

This will run delta 100 times, print out "Done" and then return to the shell. But sometimes echo will be turned off and you will not be able to see what you're typing in your shell.

A possibly related problem happens when using Ctrl+C to exit delta. Run yes | delta so that you are assured of having more than a page of output. At the less prompt, press Ctrl+C. Now delta will exit, and the shell prompt will be drawn. But less --RAW-CONTROL-CHARS --no-init --quit-if-one-screen is still running in the background (reparented to pid 1). The next keystroke is processed by less. Trying a newer version of less (581.2, compiled from source), shows similar symptoms. The command left running in the background is instead less --RAW-CONTROL-CHARS --quit-if-one-screen. And now you're left on the terminal's "alternate screen" until less exits. Then you're returned to the "normal screen". Let me know if you'd prefer that I open a separate bug for this issue.

I think the root cause here might be the same. You launch less but there are some situations where you do not wait for it to exit before exiting yourself. I think the invariant needed here is that once the pager is started you cannot exit until it has exited. I'm not sure of the best way to accomplish that. It seems like any place that you use process::exit in the code is a place where this bug may potentially occur. Any fatal signal would seem to have the same issue. You could perhaps at least work around the Ctrl+C issue by ignoring SIGINT.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions