summaryrefslogtreecommitdiffstats
path: root/examples/rl-timeout.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/rl-timeout.c')
-rw-r--r--examples/rl-timeout.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/examples/rl-timeout.c b/examples/rl-timeout.c
new file mode 100644
index 0000000..b8a24ba
--- /dev/null
+++ b/examples/rl-timeout.c
@@ -0,0 +1,245 @@
+/* rl-timeout: test various readline builtin timeouts. */
+
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of the GNU Readline Library (Readline), a library for
+ reading lines of text with interactive input and history editing.
+
+ Readline is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Readline is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with readline. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Standard include files. stdio.h is required. */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+
+/* Used for select(2) */
+#include <sys/types.h>
+#include <sys/select.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+/* Standard readline include files. */
+#if defined (READLINE_LIBRARY)
+# include "readline.h"
+# include "history.h"
+#else
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
+
+extern int errno;
+
+static void cb_linehandler (char *);
+
+int timeout_secs = 1, timeout_usecs = 0;
+int running;
+const char *prompt = "rl-timeout$ ";
+
+/* **************************************************************** */
+/* */
+/* Example 1: readline () with rl_readline_state */
+/* */
+/* **************************************************************** */
+
+void
+rltest_timeout_readline1 ()
+{
+ const char *temp;
+
+ rl_set_timeout (timeout_secs, timeout_usecs);
+ temp = readline (prompt);
+ if (RL_ISSTATE (RL_STATE_TIMEOUT))
+ printf ("timeout\n");
+ else if (temp == NULL)
+ printf ("no input line\n");
+ else
+ printf ("input line: %s\n", temp);
+ free ((void *) temp);
+}
+
+/* **************************************************************** */
+/* */
+/* Example 2: readline () with rl_timeout_event_hook */
+/* */
+/* **************************************************************** */
+
+static int
+timeout_handler ()
+{
+ printf ("timeout\n");
+ return READERR;
+}
+
+void
+rltest_timeout_readline2 ()
+{
+ const char *temp;
+
+ rl_set_timeout (timeout_secs, timeout_usecs);
+ rl_timeout_event_hook = timeout_handler;
+ temp = readline (prompt);
+ if (temp == NULL)
+ printf ("no input line\n");
+ else
+ printf ("input line: %s\n", temp);
+ free ((void *)temp);
+}
+
+/* **************************************************************** */
+/* */
+/* Example 3: rl_callback_* () with rl_timeout_remaining */
+/* */
+/* **************************************************************** */
+
+/* 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);
+ }
+}
+
+void
+rltest_timeout_callback1 ()
+{
+ fd_set fds;
+ int r;
+ unsigned sec, usec;
+
+ rl_set_timeout (timeout_secs, timeout_usecs);
+ rl_callback_handler_install (prompt, cb_linehandler);
+ running = 1;
+ while (running)
+ {
+ FD_ZERO (&fds);
+ FD_SET (fileno (rl_instream), &fds);
+ r = rl_timeout_remaining (&sec, &usec);
+ if (r == 1)
+ {
+ struct timeval timeout = {sec, usec};
+ r = select (FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ }
+ if (r < 0 && errno != EINTR)
+ {
+ perror ("rl-timeout: select");
+ rl_callback_handler_remove ();
+ break;
+ }
+ else if (r == 0)
+ {
+ printf ("rl-timeout: timeout\n");
+ rl_callback_handler_remove ();
+ break;
+ }
+
+ if (FD_ISSET (fileno (rl_instream), &fds))
+ rl_callback_read_char ();
+ }
+
+ printf ("rl-timeout: Event loop has exited\n");
+}
+
+/* **************************************************************** */
+/* */
+/* Example 4: rl_callback_* () with rl_timeout_event_hook */
+/* */
+/* **************************************************************** */
+
+static int
+cb_timeouthandler ()
+{
+ printf ("timeout\n");
+ rl_callback_handler_remove ();
+ running = 0;
+ return READERR;
+}
+
+void
+rltest_timeout_callback2 ()
+{
+ int r;
+
+ rl_set_timeout (timeout_secs, timeout_usecs);
+ rl_timeout_event_hook = cb_timeouthandler;
+ rl_callback_handler_install (prompt, cb_linehandler);
+ running = 1;
+ while (running)
+ rl_callback_read_char ();
+
+ printf ("rl-timeout: Event loop has exited\n");
+}
+
+int
+main (int argc, char **argv)
+{
+ if (argc >= 2)
+ {
+ if (argc >= 3)
+ {
+ double timeout = atof (argv[2]);
+ if (timeout <= 0.0)
+ {
+ fprintf (stderr, "rl-timeout: specify a positive number for timeout.\n");
+ return 2;
+ }
+ else if (timeout > UINT_MAX)
+ {
+ fprintf (stderr, "rl-timeout: timeout too large.\n");
+ return 2;
+ }
+ timeout_secs = (unsigned) timeout;
+ timeout_usecs = (unsigned) ((timeout - timeout_secs) * 1000000 + 0.5);
+ }
+
+ if (strcmp (argv[1], "readline1") == 0)
+ rltest_timeout_readline1 ();
+ else if (strcmp (argv[1], "readline2") == 0)
+ rltest_timeout_readline2 ();
+ else if (strcmp (argv[1], "callback1") == 0)
+ rltest_timeout_callback1 ();
+ else if (strcmp (argv[1], "callback2") == 0)
+ rltest_timeout_callback2 ();
+ else
+ return 2;
+ }
+ else
+ {
+ fprintf (stderr, "usage: rl-timeout [readline1 | readline2 | callback1 | callback2] [timeout]\n");
+ return 2;
+ }
+ return 0;
+}