--- /dev/null
+/* Standard include files. stdio.h is required. */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+/* Used for select(2) */
+#include <sys/types.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include <signal.h>
+
+#include <locale.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
+
+static void cb_linehandler (char *);
+static void sigint_sighandler (int);
+static int sigint_handler (int);
+
+static int saw_signal = 0;
+
+int running;
+const char *prompt = "rltest$ ";
+char *input_string;
+
+/* 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)
+{
+ if (line && *line)
+ add_history (line);
+ printf ("input line: %s\n", line ? line : "");
+ input_string = line;
+ rl_callback_handler_remove ();
+}
+
+static char *
+cb_readline (void)
+{
+ fd_set fds;
+ int r, err;
+ char *not_done = "";
+
+ /* Install the line handler. */
+ rl_callback_handler_install (prompt, cb_linehandler);
+
+if (RL_ISSTATE (RL_STATE_ISEARCH))
+ fprintf(stderr, "cb_readline: after handler install, state (ISEARCH) = %d", rl_readline_state);
+else if (RL_ISSTATE (RL_STATE_NSEARCH))
+ fprintf(stderr, "cb_readline: after handler install, state (NSEARCH) = %d", rl_readline_state);
+/* MULTIKEY VIMOTION NUMERICARG _rl_callback_func */
+
+ FD_ZERO (&fds);
+ FD_SET (fileno (rl_instream), &fds);
+
+ input_string = not_done;
+
+ while (input_string == not_done)
+ {
+ r = err = 0;
+ /* 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. */
+ while (r == 0)
+ {
+ struct timeval timeout = {0, 100000};
+ struct timeval *timeoutp = NULL;
+
+ timeoutp = &timeout;
+ FD_SET (fileno (rl_instream), &fds);
+ r = select (FD_SETSIZE, &fds, NULL, NULL, timeoutp);
+ err = errno;
+ }
+
+ if (saw_signal)
+ sigint_handler (saw_signal);
+
+ if (r < 0)
+ {
+ perror ("rltest: select");
+ rl_callback_handler_remove ();
+ break;
+ }
+
+ /* if (FD_ISSET (fileno (rl_instream), &fds)) */
+ if (r > 0)
+ rl_callback_read_char ();
+ }
+ return input_string;
+}
+
+void
+sigint_sighandler (int s)
+{
+ saw_signal = s;
+}
+
+int
+sigint_handler (int s)
+{
+ rl_free_line_state ();
+ rl_callback_sigcleanup ();
+ rl_cleanup_after_signal ();
+ rl_callback_handler_remove ();
+ saw_signal = 0;
+fprintf(stderr, "sigint_handler: readline state = %d\r\n", rl_readline_state);
+ return s;
+}
+
+int
+main (int c, char **v)
+{
+ char *p;
+
+ setlocale (LC_ALL, "");
+
+ running = 1;
+ rl_catch_signals = 1;
+
+ rl_bind_key_in_map ('r', rl_history_search_backward, emacs_meta_keymap);
+ rl_bind_key_in_map ('s', rl_history_search_forward, emacs_meta_keymap);
+
+ signal (SIGINT, sigint_sighandler);
+ while (running)
+ {
+ p = cb_readline ();
+ if (p == 0 || strcmp (p, "exit") == 0)
+ break;
+ }
+ printf ("rl-callbacktest2: Event loop has exited\n");
+ return 0;
+}
--- /dev/null
+/* Standard include files. stdio.h is required. */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <locale.h>
+
+/* Used for select(2) */
+#include <sys/types.h>
+#include <sys/select.h>
+
+#include <signal.h>
+
+#include <stdio.h>
+
+/* Standard readline include files. */
+#include "readline.h"
+#include "history.h"
+
+static void cb_linehandler (char *);
+static void sigwinch_handler (int);
+static void sigint_handler (int);
+
+int running;
+int sigwinch_received;
+int sigint_received;
+const char *prompt = "rltest$ ";
+
+/* Handle SIGWINCH and window size changes when readline is not active and
+ reading a character. */
+static void
+sigwinch_handler (int sig)
+{
+ sigwinch_received = 1;
+}
+
+/* Handle SIGWINCH and window size changes when readline is not active and
+ reading a character. */
+static void
+sigint_handler (int sig)
+{
+ sigint_received = 1;
+}
+
+/* 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);
+ }
+}
+
+/* replace with something more complex if desired */
+static int
+my_getc (FILE *stream)
+{
+ int ch = rl_getc (stream);
+
+ return ch;
+}
+
+
+int
+main (int c, char **v)
+{
+ fd_set fds;
+ int r;
+
+ /* Set the default locale values according to environment variables. */
+ setlocale (LC_ALL, "");
+
+ /* Handle window size changes when readline is not active and reading
+ characters. */
+ signal (SIGWINCH, sigwinch_handler);
+ signal (SIGINT, sigint_handler);
+
+ rl_getc_function = my_getc;
+
+ /* Install the line handler. */
+ rl_callback_handler_install (prompt, cb_linehandler);
+
+ /* 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;
+ }
+ if (sigwinch_received)
+ {
+ rl_resize_terminal ();
+ sigwinch_received = 0;
+ }
+ if (sigint_received)
+ {
+ printf ("Quit\n");
+
+ rl_callback_handler_remove ();
+ rl_callback_handler_install (prompt, cb_linehandler);
+
+ sigint_received = 0;
+ continue;
+ }
+ if (r < 0)
+ continue;
+
+ if (FD_ISSET (fileno (rl_instream), &fds))
+ rl_callback_read_char ();
+ }
+
+ printf ("rltest: Event loop has exited\n");
+ return 0;
+}
--- /dev/null
+/* gettimeofday.c - gettimeofday replacement using time() */
+
+/* Copyright (C) 2020, 2022 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash 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.
+
+ Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#if !defined (HAVE_GETTIMEOFDAY)
+
+#include "posixtime.h"
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* A version of gettimeofday that just sets tv_sec from time(3) on Unix-like
+ systems that don't have it, or a version for Win32 systems. */
+int
+gettimeofday (struct timeval *restrict tv, void *restrict tz)
+{
+#if !defined (_WIN32)
+ tv->tv_sec = (time_t) time ((time_t *)0);
+ tv->tv_usec = 0;
+#else
+ /* EPOCH is the number of 100 nanosecond intervals from
+ January 1, 1601 (UTC) to January 1, 1970.
+ (the correct value has 9 trailing zeros) */
+ static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((uint64_t)file_time.dwLowDateTime);
+ time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+#endif
+
+ return 0;
+}
+#endif