Cleanup on CTRL+C


#1

I’m using some ANSI codes in my program and if I don’t undo them the terminal becomes practically unusable. How can I make sure that they get reset, even if the user sends a SIGINT?


#2

Maybe a tangential answer, but doesn’t the program normally run as a sub process, meaning the parent shell doesn’t get affected by the ansi codes?


#3

As far as I can tell, the settings do persist even after the program finishes running.


#4

Can you post a screenshot of what it looks like when it happens, and if possible the code that affects the shell?


#5

There is ctrlc crate that will set up signal handlers for you.


#6

Sorry, I can’t screenshot, but it’s a simple program - something like:

    print!("\u{1B}[?25l"); let _ = io::stdout().flush(); // Hide the cursor.
    // Do some stuff that might panic.
    print!("\u{1B}[?25h"); let _ = io::stdout().flush(); // Show the cursor.

There is ctrlc crate that will set up signal handlers for you.

That would be hard to integrate in a library, considering that it can only be called once. :neutral_face:


#7

As a library it’s not your job - you only need to provide a way for the main program to do the cleanup from the signal handler.


#8

Create an object that will be given to the user on initialization and will be used to perform all the other interaction with your library. In the Drop implementation of this object, reset the terminal.


#9

Create an object that will be given to the user on initialization and will be used to perform all the other interaction with your library. In the Drop implementation of this object, reset the terminal.

That is what I’m currently doing, but Drop does not seem to run on SIGINT; only in normal execution and when panicking.

As a library it’s not your job - you only need to provide a way for the main program to do the cleanup from the signal handler.

That’s a good thought, but it means more pointless boilerplate for the user.


#10

You can even offer a function to register the signal handler from the library (thereby taking over signal handling on request), but the “user” (main program) needs to be in control of these process-global things. (As such, it is very much not pointless.)