Ikbel
Ikbel

Reputation: 7851

GNU Readline: Is there a function that cancels readline input request?

I'm new to GNU Readline, so I want to know if there exist a function that can cancel readline() request?

Upvotes: 2

Views: 1678

Answers (1)

Hans Lub
Hans Lub

Reputation: 5678

To do this, you'll have to use the alternate (or "callback") interface to readline. There is actually no need to cancel anything, you just (temporarily) step out of the loop around rl_callback_read_char to do whatever needs to be done. This can even happen before the user has sent an ENTER, but only after a keypress.

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

void line_handler(char *line) { /* This function (callback) gets called by readline                    
                                   whenever rl_callback_read_char sees an ENTER */
  printf("%s? Hah!!\n", line);
}

int main() {
  rl_callback_handler_install("Ask a question: ", &line_handler);

  while (1) {
    rl_callback_read_char();
    if (strstr(rl_line_buffer, "you")) { /* They're asking about *me* =:-0 */
      printf("\nNo personal questions please! Goodbye!\n");
      break;
      /* or make a snarky remark and continue */
    }
  }
}

If you want to "cancel" without a keypress, you'll have to interrupt the read() syscall inside the rl_callback_read_char() using a signal (e.g. by setting an alarm()). Be aware, however, that readline installs its own signal handlers.

A slightly more sophisticated method would be to insert into the loop a select() on two file descriptors, stdin and e.g. a pipe (the self-pipe trick), to use this second descriptor (and/or a timeout) to "wake up" the select(), and then step out of the loop just like in the example below..

Upvotes: 5

Related Questions