2

I'm working on a problem similar to Readline: Get a new prompt on SIGINT, but the answers given for that question don't completely satisfy the problem given.

I'm using the regular (non-callback) version of GNU readline and am writing a signal handler to handle SIGINT in C. The handler should clear the current readline buffer and display a clean prompt on a new line.

My primary concern at the moment is that I can't find any confirmation if the functions I'm calling in my signalHandler function are safe to use. The only example I've seen of readline signal handling is in the readline docs using the callback alternate interface.

The other option is to use siglongjmp as answered in the question I linked above. The problem with this solution is that it doesn't offer a way to free the memory allocated line buffer after a signal call. Raising an interrupt signal will call readline() again, but will not free the line allocated from the previous call to readline. Free() is not a signal safe function.

Has anybody written a signal safe SIGINT handler in C with the readline library using the regular interface and not the callback interface?

Sample of my current signal handler:

void signalHandler(int sig) {
if (inReadline==1)
{
    rl_reset_line_state();      // Resets the display state to a clean state
    rl_cleanup_after_signal();  // Resets the terminal to the state before readline() was called
    rl_replace_line("",0);      // Clears the current prompt
    rl_crlf();                  // Moves the cursor to the next line
    rl_redisplay();             // Redisplays the prompt
}
}
prions
  • 33
  • 4
  • 4
    If you can't find documentation that the functions are async-signal-safe, it's a pretty safe bet that they aren't. And given that something like "clear the current readline buffer" is state-dependent, it's almost certain that the functions are async-signal-**UNSAFE**. Using `siglongjmp()` won't fix that. – Andrew Henle Jun 26 '17 at 19:41
  • 1
    The current Readline docs describe a variable `rl_signal_event_hook`: "If non-zero, this is the address of a function to call if a read system call is interrupted when Readline is reading terminal input." You should consider defining a function of appropriate type and assigning it to this function instead of writing your own signal handler. It remains unclear whether the function is called in the context of the handler or after the handler returns, but I speculate the latter. You should be able to answer that either by reading code or by experimentation. – John Bollinger Jun 26 '17 at 20:33
  • You should do the minimum possible work in the signal handler. I'd not risk using the `rl_*()` functions; there's just too much likelihood that they'll do something not permitted in a signal handler — even under POSIX's much more generous rules compared to the C standard's rules. – Jonathan Leffler Jun 26 '17 at 20:40
  • I'll definitely have to look into the rl_signal_event_hook. I still need to use a signal handler because readline will pass the signal back to the process after it handles it (I don't want to quit the process on ctrl+c), but I'm thinking that I can create another function in which I can call the appropriate rl_*() functions. – prions Jun 26 '17 at 21:42

0 Answers0