/* FHE 26 Apr 2016 Readline callback interface example copied from readline documentation and modified. Compile with: gcc -g -Wall test-callback.c -lreadline -o test-callback */ /* Standard include files. stdio.h is required. */ #include #include /* Used for select(2) */ #include #include #include #include #include #include /* Standard readline include files. */ #include #include static void cb_linehandler (char *); int running; const char *prompt = "rltest$ "; /******************************************************************/ /* Copied from rlprivate.h */ #define RL_CHECK_SIGNALS() \ do { \ if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \ } while (0) extern void _rl_signal_handler (int); extern int volatile _rl_caught_signal; void _rl_reset_completion_state (); /******************************************************************/ /* Callback function called for each line when accept-line executed, EOF seen, or EOF character read. This sets a flag and returns; it could also call exit(3). */ static void cb_linehandler (char *line) { /* Can use ^D (stty eof) or `exit' to exit. */ if (line == NULL || strcmp (line, "exit") == 0) { if (line == 0) printf ("\n"); printf ("exit\n"); /* This function needs to be called to reset the terminal settings, and calling it from the line handler keeps one extra prompt from being displayed. */ rl_callback_handler_remove (); running = 0; } else { if (*line) add_history (line); printf ("input line: %s\n", line); free (line); } } sigjmp_buf env; void handle_signal(int sig) { /* rl_reset_line_state(); */ /* rl_reset_after_signal (); */ /* rl_callback_sigcleanup () */ fprintf(stderr,"Got signal: %d\n", sig); siglongjmp(env,1); } int main (int c, char **v) { struct sigaction act; act.sa_handler=handle_signal; int res; res = sigaction(SIGINT, &act, NULL); if(res!=0) { perror("sigaction"); exit(1); } if(sigsetjmp(env, 1)) { rl_free_line_state (); rl_cleanup_after_signal (); rl_callback_handler_remove (); printf("\n"); } fd_set fds; int r; /* Install the line handler. */ rl_callback_handler_install (prompt, cb_linehandler); rl_set_signals(); /* Enter a simple event loop. This waits until something is available to read on readline's input stream (defaults to standard input) and calls the builtin character read callback to read it. It does not have to modify the user's terminal settings. */ running = 1; while (running) { FD_ZERO (&fds); FD_SET (fileno (rl_instream), &fds); r = select (FD_SETSIZE, &fds, NULL, NULL, NULL); if (r < 0 && errno != EINTR) { perror ("rltest: select"); rl_callback_handler_remove (); break; } fprintf(stderr, "r=%d\n",r); /* RL_CHECK_SIGNALS(); */ if (FD_ISSET (fileno (rl_instream), &fds)) rl_callback_read_char (); } printf ("rltest: Event loop has exited\n"); return 0; }