2019-01-09  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* bind.c [__MSDOS__, __DJGPP__]:  New macro HAVE_LFN_SUPPORT to
	determinate at run time if LFN support is available or not.  For MSDOS
	it always returns false.
	[__DJGPP__]:  Macro SYS_INPUTRC redifined to "/dev/env/DJDIR/etc/inputrc".
	(rl_read_init_file) [__MSDOS__]:  Use HAVE_LFN_SUPPORT to decide if
	".inputrc" is a valid file name for the file system used.  If not or
	if the file does not exists try "_inputrc" instead.
	(rl_translate_keyseq, rl_function_dumper):  Pacify compiler.
	(rl_parse_and_bind): unused variable `s' fixed.
	(_rl_skip_to_delim):  Pacify compiler.

	* complete.c [__MSDOS__]:  New macro IS_SLASH.  For DOS/DJGPP it checks
	for slash and backslash as directory separotor.
	(printable_part):  Use IS_SLASH instead of hard coded slash as directory
	separator.
	(_rl_find_completion_word) [__MSDOS__]:  Ignore colons.
	Pacify compiler.
	(make_quoted_replacement) [__MSDOS__]:  Do not allow ':' to be quoted
	in DOS-style filenames.
	(rl_username_completion_function):  For DJGPP deactivate MS-DOS specific
	//X/ hack and activate DJGPP specific /dev/X/ hack.
	(rl_completion_matches, rl_username_completion_function):  Pacify
	compiler.
	(rl_menu_complete):  unused variable `cstate' fixed.
	(rl_filename_completion_function):  'dentry' and 'convfn' might be used
	uninitialized fixed.
	(print_filename):  'printed_len' might be used uninitialized fixed.
	(rl_complete_internal):  'tlen' might be used uninitialized fixed.

	* display.c (rl_redisplay) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc
	instead of tputs.
	(update_line) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead of
	tputs.
	(_rl_move_cursor_relative) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc
	instead of tputs.
	(_rl_move_vert) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead
	of tputs.
	(_rl_clear_to_eol) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead
	of tputs.
	(_rl_clear_screen) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead
	of tputs.
	(open_some_spaces) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead
	of tputs.
	(delete_chars) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead of
	tputs.
	(cr) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use putc instead of tputs.
	(_rl_redisplay_after_sigwinch) [HAVE_TERMCAP_API]:  For MSDOS/DJGPP use
	putc instead of tputs.
	(expand_prompt): unused variable `ind' and `pind' fixed.
	(rl_redisplay): unused variable `p' and `z' fixed.
	(_rl_move_cursor_relative): unused variable `adjust' and `in_invisline'
	fixed.
	(update_line):  Unused variable `twidth' fixed.

	* doc/hstech.texi:  DJGPP specific info added.

	* doc/rluser.texi:  DJGPP specific info added.

	* examples/fileman.c (main):  Add int return type to main function.
	(command_generator):  Pacify compiler.
	(main):  Add int return type to main function.
	(initialize_readline):  Add void return type to function.
	(com_list):  Add int return type to function.
	(com_view):  Add int return type to function.
	(com_rename):  Add int return type to function.
	(com_stat):  Add int return type to function.
	(com_delete):  Add int return type to function.
	(com_help):  Add int return type to function.
	(com_cd):  Add int return type to function.
	(com_pwd):  Add int return type to function.
	(com_quit):  Add int return type to function.
	(too_dangerous):  Add void return type to function.

	* examples/fileman.c:  Double implementations removed.

	* examples/histexamp.c (main):  Add int return type to main function.
	[HAVE_STDLIB_H]:  Include stdlib.h for free prototype.

	* examples/hist_erasedups.c:  Implicit declaration of function 'hist_erasedups'
	fixed.
	(hist_erasedups):  Suggest parentheses around assignment used as truth
	value fixed.  'r' may be used uninitialized in this function fixed.

	* examples/rl.c [HAVE_UNISTD_H]:  Include unistd.h for getopt prototype.

	* examples/rlcat.c (main):  Pacify compiler.
	(stdcat):  Unused variable 's' and 'fd' fixed.

	* examples/rlevent.c [HAVE_UNISTD_H]:  Include unistd.h for sleep and
	getopt prototypes.

	* funmap.c [__DJGPP__]:  For DJGPP added entry for rl_paste_from_clipboard
	into default_funma array.

	* histexpand.c (get_history_event):  Pacify compiler.

	* histfile.c [__DJGPP__]:  Open files in binary mode.
	[__MSDOS__, __DJGPP__]:  New macro HAVE_LFN_SUPPORT to determinate at
	run time if LFN support is available or not.  For MSDOS it always
	returns false.  New macro FILE_EXISTS uses access to check if a file
	exists.
	(history_filename) [__MSDOS__]:  Use HAVE_LFN_SUPPORT to decide if
	".history" is a valid file name for the file system used.
	Use FILE_EXISTS to decide if ".history" or "_history" shall be used
	when LFN is available.
	(history_backupfile, history_tempfile):  Unused variable `fs' fixed.

	* history.c (add_history):  Unused variable 'i' fixed.
	 (remove_history):  Unused variable 'i' fixed.

	* input.c (rl_read_key):  Pacify compiler.

	* kill.c [__DJGPP__]:  New function rl_paste_from_clipboard.  A special
	paste command to allow DJGPP users to paste from the Windows clipboard.

	* misc.c (_rl_revert_all_lines):  Pacify compiler.
	(rl_clear_history):  Suggest parentheses around assignment used as truth
	value fixed.

	* readline.c [__DJGPP__]:  Include sys/exceptn.h and provide prototype
	for __libc_termios_enable_function_and_arrow_keys.
	(readline_initialize_everything) [__DJGPP__]:  To bind tty characters
	to readline functions use __libc_termios_enable_function_and_arrow_keys.
	(readline_internal_char): unused variable `eof_found' fixed.

	* readline.h [__DJGPP__]:  rl_paste_from_clipboard only available if it
	is DJGPP.

	* rltty.c (prepare_terminal_settings):  Unused variable 'sc' fixed.

	* search.c (rl_history_search_internal):  Unused variable 't' fixed.

	* signals.c: [SIGWINCH]:  If SIGWINCH is not defined do not define the
	variables sigwinch_set_flag, sigwinch_set, sigwinch_oset, sigwinch_oldmask
	and sigwinch_blocked and do not compile the functions _rl_block_sigwinch
	and _rl_release_sigwinch.

	* tcap.h [__MSDOS__, __DJGPP__]:  New macro HAVE_TERMCAP_API.  For MSDOS
	undefine it.  For DJGPP define it if HAVE_PDCURSES_TERMCAP_API is defined.

	* terminal.c [__MSDOS__]:  For MSDOS/DJGPP do not define nor compile
	reset_default_bindings.
	[__DJGPP__, HAVE_TERMCAP_API]:  If defined include conio.h
	and provide prototype for _djgpp_get_screensize.
	(_rl_set_cursor):  No-op for DJGPP.
	[__MSDOS__]:  Reorder global variable and functions so that they are
	defined and compiled only if required for DJGPP/MSDOS.
	(_rl_init_terminal_io) [__MSDOS__, __DJGPP__]:  For DJGPP use its libc
	functions to get screen width and hight.  For MSDOS use hard coded values.
	Set _rl_term_* to values appropriate for DOS/DJGPP.
	(_rl_init_terminal_io) [__DJGPP__, HAVE_TERMCAP_API]:  For DJGPP use
	_djgpp_get_screensize to get screen width and hight.
	(_rl_backspace) [__MSDOS__]:  For MSDOS/DJGPP use putc instead of tputs.
	(rl_ding) [__MSDOS__]:  Use ScreenVisualBell instead of tputs.
	(rl_get_termcap):  No-op for MSDOS/DJGPP.
	(get_term_capabilities) [HAVE_TERMCAP_API]:  No-op if HAVE_TERMCAP_API
	is undefined.
	(_rl_enable_meta_key) [HAVE_TERMCAP_API]:  No-op if HAVE_TERMCAP_API is
	undefined.
	(_rl_disable_meta_key) [HAVE_TERMCAP_API]:  No-op if HAVE_TERMCAP_API
	is undefined.
	(_rl_control_keypad) [HAVE_TERMCAP_API]:  No-op if HAVE_TERMCAP_API is
	undefined.

	* tilde.c (tilde_expand):  Pacify compiler.
	(tilde_expand): $HOME expansion fixed.

	* tminit.c:  Adjust for use with DJGPP 2.04.

	* vi_mode.c (rl_vi_domove): unused variable `r' fixed.





diff -aprNU5 readline-8.0.orig/bind.c readline-8.0/bind.c
--- readline-8.0.orig/bind.c	2018-09-19 15:07:30 +0000
+++ readline-8.0/bind.c	2019-01-09 13:48:00 +0000
@@ -67,10 +67,24 @@ extern int errno;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strchr (), *strrchr ();
 #endif /* !strchr && !__STDC__ */
 
+/* DJGPP allows to detect at runtime if the used file system provides (LFN)
+   long file name support or not.  If LFN support is available then first look
+   for ".inputrc".  If a file with that file name does not exists try "_inputrc".
+   If only SFN is available then only try "_inputrc" as init file name.  */
+#if defined (__MSDOS__)
+#  if defined (__DJGPP__)
+#    define HAVE_LFN_SUPPORT(name)  ((pathconf((name), _PC_NAME_MAX) > 12) ? 1 : 0)
+#    undef  SYS_INPUTRC
+#    define SYS_INPUTRC             "/dev/env/DJDIR/etc/inputrc"
+#  else  /* !__DJGPP__ */
+#    define HAVE_LFN_SUPPORT(name)  (0)
+#  endif /* !__DJGPP__ */
+#endif /* !__MSDOS__ */
+
 /* Variables exported by this file. */
 Keymap rl_binding_keymap;
 
 static int _rl_skip_to_delim PARAMS((char *, int, int));
 
@@ -492,11 +506,11 @@ rl_generic_bind (int type, const char *k
 int
 rl_translate_keyseq (const char *seq, char *array, int *len)
 {
   register int i, c, l, temp;
 
-  for (i = l = 0; c = seq[i]; i++)
+  for (i = l = 0; (c = seq[i]); i++)
     {
       if (c == '\\')
 	{
 	  c = seq[++i];
 
@@ -943,10 +957,13 @@ rl_read_init_file (const char *filename)
     }
 
 #if defined (__MSDOS__)
   if (_rl_read_init_file (filename, 0) == 0)
     return 0;
+  filename = HAVE_LFN_SUPPORT(".inputrc") ? "~/.inputrc" : "~/_inputrc";
+  if (_rl_read_init_file (filename, 0) == 0)
+    return 0;
   filename = "~/_inputrc";
 #endif
   return (_rl_read_init_file (filename, 0));
 }
 
@@ -1457,11 +1474,11 @@ handle_parser_directive (char *statement
 static int
 _rl_skip_to_delim (char *string, int start, int delim)
 {
   int i, c, passc;
 
-  for (i = start,passc = 0; c = string[i]; i++)
+  for (i = start, passc = 0; (c = string[i]); i++)
     {
       if (passc)
 	{
 	  passc = 0;
 	  if (c == 0)
@@ -1551,11 +1568,10 @@ rl_parse_and_bind (char *string)
 
   /* If this is a command to set a variable, then do that. */
   if (_rl_stricmp (string, "set") == 0)
     {
       char *var, *value, *e;
-      int s;
 
       var = string + i;
       /* Make VAR point to start of variable name. */
       while (*var && whitespace (*var)) var++;
 
@@ -2638,11 +2654,11 @@ rl_function_dumper (int print_readably)
 
   names = rl_funmap_names ();
 
   fprintf (rl_outstream, "\n");
 
-  for (i = 0; name = names[i]; i++)
+  for (i = 0; (name = names[i]); i++)
     {
       rl_command_func_t *function;
       char **invokers;
 
       function = rl_named_function (name);
diff -aprNU5 readline-8.0.orig/complete.c readline-8.0/complete.c
--- readline-8.0.orig/complete.c	2017-07-04 23:43:20 +0000
+++ readline-8.0/complete.c	2019-01-09 13:48:00 +0000
@@ -115,10 +115,16 @@ static int colored_stat_start PARAMS((co
 static void colored_stat_end PARAMS((void));
 static int colored_prefix_start PARAMS((void));
 static void colored_prefix_end PARAMS((void));
 #endif
 
+#if defined (__MSDOS__)
+#  define IS_SLASH(c)  ((c) == '/' || (c) == '\\')
+#else  /* !__MSDOS__ */
+#  define IS_SLASH(c)  ((c) == '/')
+#endif /* !__MSDOS__ */
+
 static int path_isdir PARAMS((const char *));
 
 static char *rl_quote_filename PARAMS((char *, int, char *));
 
 static void _rl_complete_sigcleanup PARAMS((int, void *));
@@ -725,13 +731,13 @@ printable_part (char *pathname)
      following that slash.  If there's no previous slash, just return the
      pathname we were passed. */
   else if (temp[1] == '\0')
     {
       for (x = temp - 1; x > pathname; x--)
-        if (*x == '/')
+        if (IS_SLASH(*x))
           break;
-      return ((*x == '/') ? x + 1 : pathname);
+      return (IS_SLASH(*x) ? x + 1 : pathname);
     }
   else
     return ++temp;
 }
 
@@ -920,11 +926,11 @@ static int
 print_filename (char *to_print, char *full_pathname, int prefix_bytes)
 {
   int printed_len, extension_char, slen, tlen;
   char *s, c, *new_full_pathname, *dn;
 
-  extension_char = 0;
+  extension_char = printed_len = 0;
 #if defined (COLOR_SUPPORT)
   /* Defer printing if we want to prefix with a color indicator */
   if (_rl_colored_stats == 0 || rl_filename_completion_desired == 0)
 #endif
     printed_len = fnprint (to_print, prefix_bytes, to_print);
@@ -1131,17 +1137,23 @@ _rl_find_completion_word (int *fp, int *
   if (rl_point == end && quote_char == '\0')
     {
       /* We didn't find an unclosed quoted substring upon which to do
          completion, so use the word break characters to find the
          substring on which to complete. */
-      while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
+      while ((rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY)))
 	{
 	  scan = rl_line_buffer[rl_point];
 
 	  if (strchr (brkchars, scan) == 0)
 	    continue;
 
+#if defined (__MSDOS__)
+          /* Ignore colons.  */
+          if (scan == ':' && (rl_completion_entry_function == NULL
+	      || (rl_completion_entry_function == rl_filename_completion_function)))
+	    continue;
+#endif
 	  /* Call the application-specific function to tell us whether
 	     this word break character is quoted and should be skipped. */
 	  if (rl_char_is_quoted_p && found_quote &&
 	      (*rl_char_is_quoted_p) (rl_line_buffer, rl_point))
 	    continue;
@@ -1781,13 +1793,25 @@ make_quoted_replacement (char *match, in
   if (should_quote)
     {
       /* If there is a single match, see if we need to quote it.
          This also checks whether the common prefix of several
 	 matches needs to be quoted. */
+#if !defined (__MSDOS__)
       should_quote = rl_filename_quote_characters
 			? (_rl_strpbrk (match, rl_filename_quote_characters) != 0)
 			: 0;
+#else  /* __MSDOS__ */
+      /* To get here, the match must be a filename.
+         Do not allow ':' to be quoted in DOS-style filenames,
+         to avoid confusing people.  */
+      char *token = NULL;
+      should_quote = rl_filename_quote_characters
+                      ? ((token = _rl_strpbrk (match, rl_filename_quote_characters)) != 0)
+                      : 0;
+      if (token && *token == ':')
+        should_quote = 0;
+#endif /* __MSDOS__ */
 
       do_replace = should_quote ? mtype : NO_MATCH;
       /* Quote the replacement, since we found an embedded
 	 word break character in a potential match. */
       if (do_replace != NO_MATCH && rl_filename_quoting_function)
@@ -2014,10 +2038,12 @@ rl_complete_internal (int what_to_do)
   /* nontrivial_lcd is set if the common prefix adds something to the word
      being completed. */
   nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
   if (what_to_do == '!' || what_to_do == '@')
     tlen = strlen (text);
+  else
+    tlen = 0;
   xfree (text);
 
   if (matches == 0)
     {
       rl_ding ();
@@ -2180,11 +2206,11 @@ rl_completion_matches (const char *text,
   matches = 0;
   match_list_size = 10;
   match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
   match_list[1] = (char *)NULL;
 
-  while (string = (*entry_function) (text, matches))
+  while ((string = (*entry_function) (text, matches)))
     {
       if (RL_SIG_RECEIVED ())
 	{
 	  /* Start at 1 because we don't set matches[0] in this function.
 	     Only free the list members if we're building match list from
@@ -2252,11 +2278,11 @@ rl_username_completion_function (const c
       setpwent ();
 #endif
     }
 
 #if defined (HAVE_GETPWENT)
-  while (entry = getpwent ())
+  while ((entry = getpwent ()))
     {
       /* Null usernames should result in all users as possible completions. */
       if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
 	break;
     }
@@ -2424,11 +2450,11 @@ rl_filename_completion_function (const c
   static DIR *directory = (DIR *)NULL;
   static char *filename = (char *)NULL;
   static char *dirname = (char *)NULL;
   static char *users_dirname = (char *)NULL;
   static int filename_len;
-  char *temp, *dentry, *convfn;
+  char *temp, *dentry = NULL, *convfn = NULL;
   int dirlen, dentlen, convlen;
   int tilde_dirname;
   struct dirent *entry;
 
   /* If we don't have any state, then do some initialization. */
@@ -2450,14 +2476,20 @@ rl_filename_completion_function (const c
 	text = ".";
       dirname = savestring (text);
 
       temp = strrchr (dirname, '/');
 
-#if defined (__MSDOS__) || defined (_WIN32)
+#if defined (__MSDOS__) && !defined (__DJGPP__) || defined (_WIN32)
       /* special hack for //X/... */
       if (dirname[0] == '/' && dirname[1] == '/' && ISALPHA ((unsigned char)dirname[2]) && dirname[3] == '/')
         temp = strrchr (dirname + 3, '/');
+#elif defined (__DJGPP__)
+      /* special hack for /dev/X/ */
+      if (dirname[0] == '/'
+          && (dirname[1] == 'd') && (dirname[2] == 'e') && (dirname[3] == 'v')
+          && (dirname[4] == '/') && dirname[5]          && (dirname[6] == '/'))
+        temp = strrchr (dirname + 6, '/'); 
 #endif
 
       if (temp)
 	{
 	  strcpy (filename, ++temp);
@@ -2789,11 +2821,11 @@ rl_menu_complete (int count, int ignore)
   static int match_list_size = 0;
   static int nontrivial_lcd = 0;
   static int full_completion = 0;	/* set to 1 if menu completion should reinitialize on next call */
   static int orig_start, orig_end;
   static char quote_char;
-  static int delimiter, cstate;
+  static int delimiter;
 
   /* The first time through, we generate the list of matches and set things
      up to insert them. */
   if ((rl_last_func != rl_menu_complete && rl_last_func != rl_backward_menu_complete) || full_completion)
     {
diff -aprNU5 readline-8.0.orig/display.c readline-8.0/display.c
--- readline-8.0.orig/display.c	2018-10-01 01:37:48 +0000
+++ readline-8.0/display.c	2019-01-09 23:25:40 +0000
@@ -333,13 +333,16 @@ prompt_modestr (int *lenp)
 
 static char *
 expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
 {
   char *r, *ret, *p, *igstart, *nprompt, *ms;
-  int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
+  int l, rl, last, ignoring, ninvis, invfl, invflset, physchars;
   int mlen, newlines, newlines_guess, bound;
   int mb_cur_max;
+#if defined (HANDLE_MULTIBYTE)
+  int ind, pind;
+#endif
 
   /* We only expand the mode string for the last line of a multiline prompt
      (a prompt with embedded newlines). */
   ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
   if (ms)
@@ -651,14 +654,15 @@ void
 rl_redisplay (void)
 {
   register int in, out, c, linenum, cursor_linenum;
   register char *line;
   int inv_botlin, lb_botlin, lb_linenum, o_cpos;
-  int newlines, lpos, temp, n0, num, prompt_lines_estimate;
+  int newlines, lpos, temp, prompt_lines_estimate;
   char *prompt_this_line;
   int mb_cur_max = MB_CUR_MAX;
 #if defined (HANDLE_MULTIBYTE)
+  int  n0, num;
   wchar_t wc;
   size_t wc_bytes;
   int wc_width;
   mbstate_t ps;
   int _rl_wrapped_multicolumn = 0;
@@ -1261,11 +1265,11 @@ rl_redisplay (void)
 	      _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
 #else
 	      _rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
 #endif
 	    {
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
 	      putc ('\r', rl_outstream);
 #else
 	      if (_rl_term_cr)
 		tputs (_rl_term_cr, 1, _rl_output_character_function);
 #endif
@@ -1458,11 +1462,11 @@ new:	eddie> Oh, my little buggy says to
    Could be made even smarter, but this works well enough */
 static void
 update_line (char *old, char *new, int current_line, int omax, int nmax, int inv_botlin)
 {
   register char *ofd, *ols, *oe, *nfd, *nls, *ne;
-  int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
+  int temp, lendiff, wsatend, od, nd, o_cpos;
   int current_invis_chars;
   int col_lendiff, col_temp;
   int bytes_to_insert;
   int mb_cur_max = MB_CUR_MAX;
 #if defined (HANDLE_MULTIBYTE)
@@ -1850,11 +1854,11 @@ update_line (char *old, char *new, int c
   if (current_line == 0 && !_rl_horizontal_scroll_mode &&
       _rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
       (((od > 0 || nd > 0) && (od <= prompt_last_invisible || nd <= prompt_last_invisible)) ||
 		((od >= lendiff) && _rl_last_c_pos < PROMPT_ENDING_INDEX)))
     {
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       putc ('\r', rl_outstream);
 #else
       tputs (_rl_term_cr, 1, _rl_output_character_function);
 #endif
       if (modmark)
@@ -2361,12 +2365,10 @@ void
 _rl_move_cursor_relative (int new, const char *data)
 {
   register int i;
   int woff;			/* number of invisible chars on current line */
   int cpos, dpos;		/* current and desired cursor positions */
-  int adjust;
-  int in_invisline;
   int mb_cur_max = MB_CUR_MAX;
 
   woff = WRAP_OFFSET (_rl_last_v_pos, wrap_offset);
   cpos = _rl_last_c_pos;
 
@@ -2379,10 +2381,12 @@ _rl_move_cursor_relative (int new, const
      this case, NEW's display position is not obvious and must be
      calculated.  We need to account for invisible characters in this line,
      as long as we are past them and they are counted by _rl_col_width. */
   if (mb_cur_max > 1 && rl_byte_oriented == 0)
     {
+      int adjust, in_invisline;
+
       adjust = 1;
       /* Try to short-circuit common cases and eliminate a bunch of multibyte
 	 character function calls. */
       /* 1.  prompt string */
       if (new == local_prompt_len && memcmp (data, local_prompt, new) == 0)
@@ -2453,15 +2457,15 @@ _rl_move_cursor_relative (int new, const
 #endif
   i = _rl_last_c_pos - woff;
   if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
       (_rl_term_autowrap && i == _rl_screenwidth))
     {
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       putc ('\r', rl_outstream);
 #else
       tputs (_rl_term_cr, 1, _rl_output_character_function);
-#endif /* !__MSDOS__ */
+#endif /* !HAVE_TERMCAP_API */
       cpos = _rl_last_c_pos = 0;
     }
 
   if (cpos < dpos)
     {
@@ -2482,18 +2486,22 @@ _rl_move_cursor_relative (int new, const
 	 in the buffer and we have to go back to the beginning of the screen
 	 line.  In this case, we can use the terminal sequence to move forward
 	 if it's available. */
       if (mb_cur_max > 1 && rl_byte_oriented == 0)
 	{
+#if defined (HAVE_TERMCAP_API)
 	  if (_rl_term_forward_char)
 	    {
 	      for (i = cpos; i < dpos; i++)
 	        tputs (_rl_term_forward_char, 1, _rl_output_character_function);
 	    }
 	  else
+#endif
 	    {
+#if defined (HAVE_TERMCAP_API)
 	      tputs (_rl_term_cr, 1, _rl_output_character_function);
+#endif
 	      for (i = 0; i < new; i++)
 		putc (data[i], rl_outstream);
 	    }
 	}
       else
@@ -2524,31 +2532,31 @@ _rl_move_vert (int to)
 
   if ((delta = to - _rl_last_v_pos) > 0)
     {
       for (i = 0; i < delta; i++)
 	putc ('\n', rl_outstream);
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       putc ('\r', rl_outstream);
 #else
       tputs (_rl_term_cr, 1, _rl_output_character_function);
 #endif
       _rl_last_c_pos = 0;
     }
   else
     {			/* delta < 0 */
-#ifdef __DJGPP__
+#if !defined (HAVE_TERMCAP_API)
       int row, col;
 
       fflush (rl_outstream);
       ScreenGetCursor (&row, &col);
       ScreenSetCursor (row + delta, col);
       i = -delta;
 #else
       if (_rl_term_up && *_rl_term_up)
 	for (i = 0; i < -delta; i++)
 	  tputs (_rl_term_up, 1, _rl_output_character_function);
-#endif /* !__DJGPP__ */
+#endif /* !HAVE_TERMCAP_API */
     }
 
   _rl_last_v_pos = to;		/* Now TO is here */
 }
 
@@ -2846,11 +2854,11 @@ _rl_erase_at_end_of_line (int l)
    number of character spaces to clear, but we use a terminal escape
    sequence if available. */
 void
 _rl_clear_to_eol (int count)
 {
-#ifndef __MSDOS__
+#if defined (HAVE_TERMCAP_API)
   if (_rl_term_clreol)
     tputs (_rl_term_clreol, 1, _rl_output_character_function);
   else
 #endif
     if (count)
@@ -2871,19 +2879,19 @@ space_to_eol (int count)
 }
 
 void
 _rl_clear_screen (void)
 {
-#if defined (__DJGPP__)
-  ScreenClear ();
-  ScreenSetCursor (0, 0);
-#else
+#if defined (HAVE_TERMCAP_API)
   if (_rl_term_clrpag)
     tputs (_rl_term_clrpag, 1, _rl_output_character_function);
   else
     rl_crlf ();
-#endif /* __DJGPP__ */
+#else /* !HAVE_TERMCAP_API */
+  ScreenClear ();
+  ScreenSetCursor (0, 0);
+#endif /* !HAVE_TERMCAP_API */
 }
 
 /* Insert COUNT characters from STRING to the output stream at column COL. */
 static void
 insert_some_chars (char *string, int count, int col)
@@ -2896,11 +2904,11 @@ insert_some_chars (char *string, int cou
    ncurses documentation and use either im/ei with explicit spaces, or IC/ic
    by itself.  We assume there will either be ei or we don't need to use it. */
 static void
 open_some_spaces (int col)
 {
-#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
+#if defined (HAVE_TERMCAP_API) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
   char *buffer;
   register int i;
 
   /* If IC is defined, then we do not have to "enter" insert mode. */
   if (_rl_term_IC)
@@ -2925,21 +2933,21 @@ open_some_spaces (int col)
       /* If there is a special command for inserting characters, then
 	 use that first to open up the space. */
       for (i = col; i--; )
 	tputs (_rl_term_ic, 1, _rl_output_character_function);
     }
-#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
+#endif /* HAVE_TERMCAP_API && (!__MINGW32__ || NCURSES_VERSION)*/
 }
 
 /* Delete COUNT characters from the display line. */
 static void
 delete_chars (int count)
 {
   if (count > _rl_screenwidth)	/* XXX */
     return;
 
-#if !defined (__MSDOS__) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
+#if defined (HAVE_TERMCAP_API) && (!defined (__MINGW32__) || defined (NCURSES_VERSION))
   if (_rl_term_DC && *_rl_term_DC)
     {
       char *buffer;
       buffer = tgoto (_rl_term_DC, count, count);
       tputs (buffer, count, _rl_output_character_function);
@@ -2948,11 +2956,11 @@ delete_chars (int count)
     {
       if (_rl_term_dc && *_rl_term_dc)
 	while (count--)
 	  tputs (_rl_term_dc, 1, _rl_output_character_function);
     }
-#endif /* !__MSDOS__ && (!__MINGW32__ || NCURSES_VERSION)*/
+#endif /* HAVE_TERMCAP_API && (!__MINGW32__ || NCURSES_VERSION)*/
 }
 
 void
 _rl_update_final (void)
 {
@@ -2997,11 +3005,11 @@ _rl_update_final (void)
 static void
 cr (void)
 {
   if (_rl_term_cr)
     {
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       putc ('\r', rl_outstream);
 #else
       tputs (_rl_term_cr, 1, _rl_output_character_function);
 #endif
       _rl_last_c_pos = 0;
@@ -3046,17 +3054,17 @@ _rl_redisplay_after_sigwinch (void)
      screen line. */
   if (_rl_term_cr)
     {
       _rl_move_vert (_rl_vis_botlin);
 
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       putc ('\r', rl_outstream);
 #else
       tputs (_rl_term_cr, 1, _rl_output_character_function);
 #endif
       _rl_last_c_pos = 0;
-#if defined (__MSDOS__)
+#if !defined (HAVE_TERMCAP_API)
       space_to_eol (_rl_screenwidth);
       putc ('\r', rl_outstream);
 #else
       if (_rl_term_clreol)
 	tputs (_rl_term_clreol, 1, _rl_output_character_function);
diff -aprNU5 readline-8.0.orig/doc/hstech.texi readline-8.0/doc/hstech.texi
--- readline-8.0.orig/doc/hstech.texi	2018-07-06 22:24:54 +0000
+++ readline-8.0/doc/hstech.texi	2019-01-09 13:48:00 +0000
@@ -326,10 +326,16 @@ index of the history element where @var{
 @subsection Managing the History File
 
 The History library can read the history from and write it to a file.
 This section documents the functions for managing a history file.
 
+For the @acronym{DJGPP} port of history library the default will be
+@file{~/.history} if the used operating system offers long file name
+support.  If this is not the case @file{~/_history} will be the default.
+If long file name support is available and @file{~/.history} could not
+be found then @file{~/_history} would be tried instead.
+
 @deftypefun int read_history (const char *filename)
 Add the contents of @var{filename} to the history list, a line at a time.
 If @var{filename} is @code{NULL}, then read from @file{~/.history}.
 Returns 0 if successful, or @code{errno} if not.
 @end deftypefun
diff -aprNU5 readline-8.0.orig/doc/rluser.texi readline-8.0/doc/rluser.texi
--- readline-8.0.orig/doc/rluser.texi	2018-10-05 18:57:14 +0000
+++ readline-8.0/doc/rluser.texi	2019-01-09 13:48:00 +0000
@@ -349,10 +349,17 @@ file is taken from the value of the envi
 @end ifclear
 that variable is unset, the default is @file{~/.inputrc}.  If that
 file does not exist or cannot be read, the ultimate default is
 @file{/etc/inputrc}.
 
+For the @acronym{DJGPP} port of the Readline library the default will be
+@file{~/.inputrc} if the used operating system offers long file name
+support.  If this is not the case @file{~/_inputrc} will be the default.
+If long file name support is available and @file{~/.inputrc} could not
+be found then @file{~/_inputrc} would be tried instead.  The ultimate
+default is @file{/dev/env/DJDIR/etc/inputrc}.
+
 When a program which uses the Readline library starts up, the
 init file is read, and the key bindings are set.
 
 In addition, the @code{C-x C-r} command re-reads this init file, thus
 incorporating any changes that you might have made to it.
diff -aprNU5 readline-8.0.orig/examples/fileman.c readline-8.0/examples/fileman.c
--- readline-8.0.orig/examples/fileman.c	2015-08-06 14:55:38 +0000
+++ readline-8.0/examples/fileman.c	2019-01-09 13:48:00 +0000
@@ -123,45 +123,10 @@ dupstr (s)
   r = xmalloc (strlen (s) + 1);
   strcpy (r, s);
   return (r);
 }
 
-int
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  char *line, *s;
-
-  progname = argv[0];
-
-  initialize_readline ();	/* Bind our completer. */
-
-  /* Loop reading and executing lines until the user quits. */
-  for ( ; done == 0; )
-    {
-      line = readline ("FileMan: ");
-
-      if (!line)
-        break;
-
-      /* Remove leading and trailing whitespace from the line.
-         Then, if there is anything left, add it to the history list
-         and execute it. */
-      s = stripwhite (line);
-
-      if (*s)
-        {
-          add_history (s);
-          execute_line (s);
-        }
-
-      free (line);
-    }
-  exit (0);
-}
-
 /* Execute a command line. */
 int
 execute_line (line)
      char *line;
 {
@@ -300,11 +265,11 @@ command_generator (text, state)
       list_index = 0;
       len = strlen (text);
     }
 
   /* Return the next name which partially matches from the command list. */
-  while (name = commands[list_index].name)
+  while ((name = commands[list_index].name))
     {
       list_index++;
 
       if (strncmp (name, text, len) == 0)
         return (dupstr(name));
@@ -502,5 +467,40 @@ valid_argument (caller, arg)
       return (0);
     }
 
   return (1);
 }
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  char *line, *s;
+
+  progname = argv[0];
+
+  initialize_readline ();	/* Bind our completer. */
+
+  /* Loop reading and executing lines until the user quits. */
+  for ( ; done == 0; )
+    {
+      line = readline ("FileMan: ");
+
+      if (!line)
+        break;
+
+      /* Remove leading and trailing whitespace from the line.
+         Then, if there is anything left, add it to the history list
+         and execute it. */
+      s = stripwhite (line);
+
+      if (*s)
+        {
+          add_history (s);
+          execute_line (s);
+        }
+
+      free (line);
+    }
+  exit (0);
+}
diff -aprNU5 readline-8.0.orig/examples/rl.c readline-8.0/examples/rl.c
--- readline-8.0.orig/examples/rl.c	2015-08-06 14:51:22 +0000
+++ readline-8.0/examples/rl.c	2019-01-09 13:48:00 +0000
@@ -36,20 +36,50 @@
 #  include <stdlib.h>
 #else 
 extern void exit();
 #endif
 
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
 #if defined (READLINE_LIBRARY)
 #  include "posixstat.h"
 #  include "readline.h"
 #  include "history.h"
 #else
 #  include <sys/stat.h>
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)      \
+  (__gnuc_extension__                                  \
+    ({                                                 \
+        char *_dst, *_src;                             \
+        _dst = _src = unconst((file_name), char *);    \
+        while (*_src++)                                \
+          ;                                            \
+        while ((_src - _dst) && (*--_src != '.'))      \
+          ;                                            \
+        for (*_src = '\0'; (_src - _dst); _src--)      \
+          if (IS_DIR_SEPARATOR(*_src))                 \
+            break;                                     \
+        if (_src - _dst)                               \
+          while ((*_dst++ = *++_src))                  \
+            ;                                          \
+        (file_name);                                   \
+    })                                                 \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strrchr();
@@ -85,11 +115,11 @@ main (argc, argv)
   char *temp, *prompt;
   struct stat sb;
   int opt, fd, nch;
   FILE *ifp;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
diff -aprNU5 readline-8.0.orig/examples/rlcat.c readline-8.0/examples/rlcat.c
--- readline-8.0.orig/examples/rlcat.c	2017-05-04 14:54:10 +0000
+++ readline-8.0/examples/rlcat.c	2019-01-09 13:48:00 +0000
@@ -55,10 +55,36 @@ extern int errno;
 #else
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)      \
+  (__gnuc_extension__                                  \
+    ({                                                 \
+        char *_dst, *_src;                             \
+        _dst = _src = unconst((file_name), char *);    \
+        while (*_src++)                                \
+          ;                                            \
+        while ((_src - _dst) && (*--_src != '.'))      \
+          ;                                            \
+        for (*_src = '\0'; (_src - _dst); _src--)      \
+          if (IS_DIR_SEPARATOR(*_src))                 \
+            break;                                     \
+        if (_src - _dst)                               \
+          while ((*_dst++ = *++_src))                  \
+            ;                                          \
+        (file_name);                                   \
+    })                                                 \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 static int stdcat();
 
@@ -77,11 +103,11 @@ main (argc, argv)
      char **argv;
 {
   char *temp;
   int opt, Vflag, Nflag;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
@@ -113,11 +139,11 @@ main (argc, argv)
 
   if (isatty(0) == 0 || argc || Nflag)
     return stdcat(argc, argv);
 
   rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
-  while (temp = readline (""))
+  while ((temp = readline ("")))
     {
       if (*temp)
         add_history (temp);
       printf ("%s\n", temp);
     }
@@ -149,12 +175,11 @@ fcopy(fp)
 int
 stdcat (argc, argv)
      int argc;
      char **argv;
 {
-  int  i, fd, r;
-  char *s;
+  int  i, r;
   FILE *fp;
 
   if (argc == 0)
     return (fcopy(stdin));
 
diff -aprNU5 readline-8.0.orig/examples/rlevent.c readline-8.0/examples/rlevent.c
--- readline-8.0.orig/examples/rlevent.c	2018-05-21 15:04:16 +0000
+++ readline-8.0/examples/rlevent.c	2019-01-09 13:48:00 +0000
@@ -42,20 +42,50 @@ extern int sleep();
 #  include <stdlib.h>
 #else 
 extern void exit();
 #endif
 
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
 #if defined (READLINE_LIBRARY)
 #  include "posixstat.h"
 #  include "readline.h"
 #  include "history.h"
 #else
 #  include <sys/stat.h>
 #  include <readline/readline.h>
 #  include <readline/history.h>
 #endif
 
+#if defined (__DJGPP__)
+# undef  IS_DIR_SEPARATOR
+# define IS_DIR_SEPARATOR(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
+# include <libc/unconst.h>
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)      \
+  (__gnuc_extension__                                  \
+    ({                                                 \
+        char *_dst, *_src;                             \
+        _dst = _src = unconst((file_name), char *);    \
+        while (*_src++)                                \
+          ;                                            \
+        while ((_src - _dst) && (*--_src != '.'))      \
+          ;                                            \
+        for (*_src = '\0'; (_src - _dst); _src--)      \
+          if (IS_DIR_SEPARATOR(*_src))                 \
+            break;                                     \
+        if (_src - _dst)                               \
+          while ((*_dst++ = *++_src))                  \
+            ;                                          \
+        (file_name);                                   \
+    })                                                 \
+  )
+#else  /* !__DJGPP__ */
+# define STRIP_FULL_PATH_AND_EXTENSION(file_name)  (file_name)
+#endif /* !__DJGPP__ */
+
 extern int optind;
 extern char *optarg;
 
 #if !defined (strchr) && !defined (__STDC__)
 extern char *strrchr();
@@ -99,11 +129,11 @@ main (argc, argv)
   char *temp, *prompt;
   struct stat sb;
   int opt, fd, nch;
   FILE *ifp;
 
-  progname = strrchr(argv[0], '/');
+  progname = STRIP_FULL_PATH_AND_EXTENSION(argv[0]);
   if (progname == 0)
     progname = argv[0];
   else
     progname++;
 
diff -aprNU5 readline-8.0.orig/funmap.c readline-8.0/funmap.c
--- readline-8.0.orig/funmap.c	2017-02-18 23:10:22 +0000
+++ readline-8.0/funmap.c	2019-01-09 13:48:00 +0000
@@ -115,11 +115,11 @@ static const FUNMAP default_funmap[] = {
   { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
   { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
   { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
   { "old-menu-complete", rl_old_menu_complete },
   { "overwrite-mode", rl_overwrite_mode },
-#if defined (_WIN32)
+#if defined (_WIN32) || defined (__DJGPP__)
   { "paste-from-clipboard", rl_paste_from_clipboard },
 #endif
   { "possible-completions", rl_possible_completions },
   { "previous-history", rl_get_previous_history },
   { "previous-screen-line", rl_previous_screen_line },
diff -aprNU5 readline-8.0.orig/histexpand.c readline-8.0/histexpand.c
--- readline-8.0.orig/histexpand.c	2018-09-15 21:53:40 +0000
+++ readline-8.0/histexpand.c	2019-01-09 13:48:00 +0000
@@ -208,11 +208,11 @@ get_history_event (const char *string, i
       substring_okay++;
       i++;
     }
 
   /* Only a closing `?' or a newline delimit a substring search string. */
-  for (local_index = i; c = string[i]; i++)
+  for (local_index = i; (c = string[i]); i++)
     {
 #if defined (HANDLE_MULTIBYTE)
       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
 	{
 	  int v;
diff -aprNU5 readline-8.0.orig/histfile.c readline-8.0/histfile.c
--- readline-8.0.orig/histfile.c	2018-06-11 13:14:52 +0000
+++ readline-8.0/histfile.c	2019-01-09 13:48:00 +0000
@@ -78,21 +78,35 @@
 #  endif
 
 #endif /* HISTORY_USE_MMAP */
 
 /* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
-   on win 95/98/nt), we want to open files with O_BINARY mode so that there
-   is no \n -> \r\n conversion performed.  On other systems, we don't want to
-   mess around with O_BINARY at all, so we ensure that it's defined to 0. */
-#if defined (__EMX__) || defined (__CYGWIN__)
+   on win 95/98/nt), or DJGPP (DOS), we want to open files with O_BINARY mode
+   so that there is no \n -> \r\n conversion performed.  On other systems,
+   we don't want to mess around with O_BINARY at all, so we ensure that
+   it's defined to 0. */
+#if defined (__EMX__) || defined (__DJGPP__) || defined (__CYGWIN__)
 #  ifndef O_BINARY
 #    define O_BINARY 0
 #  endif
-#else /* !__EMX__ && !__CYGWIN__ */
+#else /* !__EMX__ && !__DJGPP__ && !__CYGWIN__ */
 #  undef O_BINARY
 #  define O_BINARY 0
-#endif /* !__EMX__ && !__CYGWIN__ */
+#endif /* !__EMX__ && !__DJGPP__ && !__CYGWIN__ */
+
+/* DJGPP allows to detect at runtime if the file system used provides (LFN)
+   long file name support or not.  If LFN support is available then look first
+   for ".history".  If a file with that file name does not exists try "_history".
+   If only SFN support is available then only try "_history" as history file name.  */
+#if defined (__MSDOS__)
+#  if defined (__DJGPP__)
+#    define HAVE_LFN_SUPPORT(name)   ((pathconf((name), _PC_NAME_MAX) > 12) ? 1 : 0)
+#    define FILE_EXISTS(name)        (access((name), F_OK) == 0)
+#  else  /* !__DJGPP__ */
+#    define HAVE_LFN_SUPPORT(name)   (0)
+#  endif /* !__DJGPP__ */
+#endif /* !__MSDOS__ */
 
 #include <errno.h>
 #if !defined (errno)
 extern int errno;
 #endif /* !errno */
@@ -167,11 +181,14 @@ history_filename (const char *filename)
 
   return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
   strcpy (return_val, home);
   return_val[home_len] = '/';
 #if defined (__MSDOS__)
-  strcpy (return_val + home_len + 1, "_history");
+  if (HAVE_LFN_SUPPORT(".history"))
+    strcpy (return_val + home_len + 1, FILE_EXISTS(".history") ? ".history" : "_history");
+  else
+    strcpy (return_val + home_len + 1, "_history");
 #else
   strcpy (return_val + home_len + 1, ".history");
 #endif
 
   return (return_val);
@@ -182,11 +199,10 @@ history_backupfile (const char *filename
 {
   const char *fn;
   char *ret, linkbuf[PATH_MAX+1];
   size_t len;
   ssize_t n;
-  struct stat fs;
 
   fn = filename;  
 #if defined (HAVE_READLINK)
   /* Follow symlink to avoid backing up symlink itself; call will fail if
      not a symlink */
@@ -202,19 +218,18 @@ history_backupfile (const char *filename
   strcpy (ret, fn);
   ret[len] = '-';
   ret[len+1] = '\0';
   return ret;
 }
-  
+
 static char *
 history_tempfile (const char *filename)
 {
   const char *fn;
   char *ret, linkbuf[PATH_MAX+1];
   size_t len;
   ssize_t n;
-  struct stat fs;
   int pid;
 
   fn = filename;  
 #if defined (HAVE_READLINK)
   /* Follow symlink so tempfile created in the same directory as any symlinked
diff -aprNU5 readline-8.0.orig/history.c readline-8.0/history.c
--- readline-8.0.orig/history.c	2017-02-27 20:39:24 +0000
+++ readline-8.0/history.c	2019-01-09 13:48:00 +0000
@@ -274,11 +274,13 @@ add_history (const char *string)
   HIST_ENTRY *temp;
   int new_length;
 
   if (history_stifled && (history_length == history_max_entries))
     {
+#if 0
       register int i;
+#endif
 
       /* If the history is stifled, and history_length is zero,
 	 and it equals history_max_entries, we don't save items. */
       if (history_length == 0)
 	return;
@@ -477,14 +479,15 @@ _hs_replace_history_data (int which, his
    and containing structure. */
 HIST_ENTRY *
 remove_history (int which)
 {
   HIST_ENTRY *return_value;
-  register int i;
 #if 1
   int nentries;
   HIST_ENTRY **start, **end;
+#else
+  register int i;
 #endif
 
   if (which < 0 || which >= history_length || history_length ==  0 || the_history == 0)
     return ((HIST_ENTRY *)NULL);
 
diff -aprNU5 readline-8.0.orig/input.c readline-8.0/input.c
--- readline-8.0.orig/input.c	2018-09-30 21:04:20 +0000
+++ readline-8.0/input.c	2019-01-09 13:48:00 +0000
@@ -462,11 +462,11 @@ rl_read_key (void)
       rl_clear_pending_input ();
     }
   else
     {
       /* If input is coming from a macro, then use that. */
-      if (c = _rl_next_macro_key ())
+      if ((c = _rl_next_macro_key ()))
 	return ((unsigned char)c);
 
       /* If the user has an event function, then call it periodically. */
       if (rl_event_hook)
 	{
diff -aprNU5 readline-8.0.orig/kill.c readline-8.0/kill.c
--- readline-8.0.orig/kill.c	2018-10-03 19:26:36 +0000
+++ readline-8.0/kill.c	2019-01-09 13:48:00 +0000
@@ -762,5 +762,78 @@ rl_paste_from_clipboard (int count, int
       CloseClipboard ();
     }
   return (0);
 }
 #endif /* _WIN32 */
+
+/* A special paste command to allow DJGPP users to paste
+   from the Windows clipboard. */
+#if defined (__DJGPP__)
+#include <dpmi.h>
+#include <sys/farptr.h>
+#include <go32.h>
+
+int
+rl_paste_from_clipboard (count, key)
+     int count, key;
+{
+  char *ptr;
+  int len, index;
+  __dpmi_regs r;
+  unsigned long offset;
+  char ch;
+ 
+  /* Open the Windows clipboard.  */
+  r.x.ax = 0x1701;
+  __dpmi_int(0x2f, &r);
+  if (r.x.ax == 0)
+    return 0;
+
+  /* Get the size of the text in the clipboard.  */
+  r.x.ax = 0x1704;
+  r.x.dx = 1; /* Select plain text.  */
+  __dpmi_int(0x2f, &r);
+  len = r.x.ax + 65536 * r.x.dx;
+  if (len == 0)
+    return 0;
+
+  /* Get a pointer to the text.  */
+  r.x.ax = 0x1705;
+  r.x.dx = 1;
+  __dpmi_int(0x2f, &r);
+
+  offset = r.x.bx + 16 * r.x.es;
+  if (offset == 0)
+    return 0;
+
+  _farsetsel(_dos_ds);
+  while ((ch = _farnspeekb(offset++)) != '\0')
+  {
+    if (ch == '\r')
+      break;
+  }
+  len = offset - (r.x.bx + 16 * r.x.es);
+  if (ch == '\r')
+    --len;
+
+  ptr = xmalloc(len + 1);
+  offset = r.x.bx + 16 * r.x.es;
+
+  index = 0;
+  _farsetsel(_dos_ds);
+  while (index < len)
+  {
+    ch = _farnspeekb(offset++);
+    ptr[index++] = ch;
+  }
+  ptr[len] = '\0';
+
+  /* Close the clipboard.  */
+  r.x.ax = 0x1708;
+  __dpmi_int(0x2f, &r);
+
+  rl_insert_text(ptr);
+  free(ptr);
+
+  return 0;
+}
+#endif /* __DJGPP__ */
diff -aprNU5 readline-8.0.orig/misc.c readline-8.0/misc.c
--- readline-8.0.orig/misc.c	2017-07-07 21:30:12 +0000
+++ readline-8.0/misc.c	2019-01-09 13:48:00 +0000
@@ -447,11 +447,11 @@ _rl_revert_all_lines (void)
   hpos = where_history ();
 
   entry = (hpos == history_length) ? previous_history () : current_history ();
   while (entry)
     {
-      if (ul = (UNDO_LIST *)entry->data)
+      if ((ul = (UNDO_LIST *)entry->data))
 	{
 	  if (ul == saved_undo_list)
 	    saved_undo_list = 0;
 	  /* Set up rl_line_buffer and other variables from history entry */
 	  rl_replace_from_history (entry, 0);	/* entry->line is now current */
@@ -494,11 +494,11 @@ rl_clear_history (void)
   hlist = history_list ();		/* direct pointer, not copy */
 
   for (i = 0; i < history_length; i++)
     {
       hent = hlist[i];
-      if (ul = (UNDO_LIST *)hent->data)
+      if ((ul = (UNDO_LIST *)hent->data))
 	{
 	  if (ul == saved_undo_list)
 	    saved_undo_list = 0;
 	  _rl_free_undo_list (ul);
 	  hent->data = 0;
diff -aprNU5 readline-8.0.orig/readline.c readline-8.0/readline.c
--- readline-8.0.orig/readline.c	2018-07-17 18:06:16 +0000
+++ readline-8.0/readline.c	2019-01-09 13:48:00 +0000
@@ -62,10 +62,15 @@ extern int errno;
 #if defined (__EMX__)
 #  define INCL_DOSPROCESS
 #  include <os2.h>
 #endif /* __EMX__ */
 
+#if defined (__DJGPP__)
+#  include <sys/exceptn.h>
+extern int __libc_termios_enable_function_and_arrow_keys (void);
+#endif /* __DJGPP__ */
+
 /* Some standard library routines. */
 #include "readline.h"
 #include "history.h"
 
 #include "rlprivate.h"
@@ -95,11 +100,13 @@ static void bind_arrow_keys_internal PAR
 static void bind_arrow_keys PARAMS((void));
 
 static void bind_bracketed_paste_prefix PARAMS((void));
 
 static void readline_default_bindings PARAMS((void));
+#if !defined (__MSDOS__)
 static void reset_default_bindings PARAMS((void));
+#endif
 
 static int _rl_subseq_result PARAMS((int, Keymap, int, int));
 static int _rl_subseq_getchar PARAMS((int));
 
 /* **************************************************************** */
@@ -530,11 +537,14 @@ STATIC_CALLBACK int
 readline_internal_char (void)
 #else
 readline_internal_charloop (void)
 #endif
 {
-  static int lastc, eof_found;
+#if !defined (READLINE_CALLBACKS)
+  static int eof_found;
+#endif
+  static int lastc;
   int c, code, lk, r;
 
   lastc = EOF;
 
 #if !defined (READLINE_CALLBACKS)
@@ -1198,10 +1208,13 @@ readline_initialize_everything (void)
   if (rl_terminal_name == 0)
     rl_terminal_name = sh_get_env_value ("TERM");
   _rl_init_terminal_io (rl_terminal_name);
 
   /* Bind tty characters to readline functions. */
+#if defined (__DJGPP__)
+  __libc_termios_enable_function_and_arrow_keys ();
+#endif /* __DJGPP__ */
   readline_default_bindings ();
 
   /* Initialize the function names. */
   rl_initialize_funmap ();
 
@@ -1252,10 +1265,11 @@ readline_default_bindings (void)
 {
   if (_rl_bind_stty_chars)
     rl_tty_set_default_bindings (_rl_keymap);
 }
 
+#if !defined (__MSDOS__)
 /* Reset the default bindings for the terminal special characters we're
    interested in back to rl_insert and read the new ones. */
 static void
 reset_default_bindings (void)
 {
@@ -1263,10 +1277,11 @@ reset_default_bindings (void)
     {
       rl_tty_unset_default_bindings (_rl_keymap);
       rl_tty_set_default_bindings (_rl_keymap);
     }
 }
+#endif
 
 /* Bind some common arrow key sequences in MAP. */
 static void
 bind_arrow_keys_internal (Keymap map)
 {
diff -aprNU5 readline-8.0.orig/readline.h readline-8.0/readline.h
--- readline-8.0.orig/readline.h	2018-09-18 16:16:58 +0000
+++ readline-8.0/readline.h	2019-01-09 13:48:00 +0000
@@ -174,12 +174,12 @@ extern int rl_copy_backward_word PARAMS(
 extern int rl_yank PARAMS((int, int));
 extern int rl_yank_pop PARAMS((int, int));
 extern int rl_yank_nth_arg PARAMS((int, int));
 extern int rl_yank_last_arg PARAMS((int, int));
 extern int rl_bracketed_paste_begin PARAMS((int, int));
-/* Not available unless _WIN32 is defined. */
-#if defined (_WIN32)
+/* Not available unless _WIN32 or __DJGPP__ is defined. */
+#if defined (_WIN32) || defined (__DJGPP__)
 extern int rl_paste_from_clipboard PARAMS((int, int));
 #endif
 
 /* Bindable commands for incremental searching. */
 extern int rl_reverse_search_history PARAMS((int, int));
diff -aprNU5 readline-8.0.orig/rltty.c readline-8.0/rltty.c
--- readline-8.0.orig/rltty.c	2018-09-19 15:19:26 +0000
+++ readline-8.0/rltty.c	2019-01-09 13:48:00 +0000
@@ -500,11 +500,13 @@ set_tty_settings (int tty, TIOTYPE *tiop
 }
 
 static void
 prepare_terminal_settings (int meta_flag, TIOTYPE oldtio, TIOTYPE *tiop)
 {
+#if defined (VDISCARD)
   int sc;
+#endif /* VDISCARD */
   Keymap kmap;
 
   _rl_echoing_p = (oldtio.c_lflag & ECHO);
 #if defined (ECHOCTL)
   _rl_echoctl = (oldtio.c_lflag & ECHOCTL);
diff -aprNU5 readline-8.0.orig/search.c readline-8.0/search.c
--- readline-8.0.orig/search.c	2018-10-21 18:10:32 +0000
+++ readline-8.0/search.c	2019-01-09 13:48:00 +0000
@@ -482,11 +482,13 @@ _rl_nsearch_callback (_rl_search_cxt *cx
 static int
 rl_history_search_internal (int count, int dir)
 {
   HIST_ENTRY *temp;
   int ret, oldpos, newcol;
+#if 0
   char *t;
+#endif
 
   rl_maybe_save_line ();
   temp = (HIST_ENTRY *)NULL;
 
   /* Search COUNT times through the history for a line matching
diff -aprNU5 readline-8.0.orig/signals.c readline-8.0/signals.c
--- readline-8.0.orig/signals.c	2018-03-28 20:23:44 +0000
+++ readline-8.0/signals.c	2019-01-09 13:48:00 +0000
@@ -109,11 +109,13 @@ int _rl_echoctl = 0;
 int _rl_intr_char = 0;
 int _rl_quit_char = 0;
 int _rl_susp_char = 0;
 
 static int signals_set_flag;
+#if defined (SIGWINCH)
 static int sigwinch_set_flag;
+#endif /* SIGWINCH */
 
 #if defined (HAVE_POSIX_SIGNALS)
 sigset_t _rl_orig_sigset;
 #endif /* !HAVE_POSIX_SIGNALS */
 
@@ -609,20 +611,26 @@ rl_check_signals (void)
 /*								    */
 /* **************************************************************** */
 
 #if defined (HAVE_POSIX_SIGNALS)
 static sigset_t sigint_set, sigint_oset;
+#  if defined (SIGWINCH)
 static sigset_t sigwinch_set, sigwinch_oset;
+#  endif /* SIGWINCH */
 #else /* !HAVE_POSIX_SIGNALS */
 #  if defined (HAVE_BSD_SIGNALS)
 static int sigint_oldmask;
+#    if defined (SIGWINCH)
 static int sigwinch_oldmask;
+#    endif /* SIGWINCH */
 #  endif /* HAVE_BSD_SIGNALS */
 #endif /* !HAVE_POSIX_SIGNALS */
 
 static int sigint_blocked;
+#if defined (SIGWINCH)
 static int sigwinch_blocked;
+#endif /* SIGWINCH */
 
 /* Cause SIGINT to not be delivered until the corresponding call to
    release_sigint(). */
 void
 _rl_block_sigint (void)
@@ -642,10 +650,11 @@ _rl_release_sigint (void)
 
   sigint_blocked = 0;
   RL_CHECK_SIGNALS ();
 }
 
+#if defined (SIGWINCH)
 /* Cause SIGWINCH to not be delivered until the corresponding call to
    release_sigwinch(). */
 void
 _rl_block_sigwinch (void)
 {
@@ -697,10 +706,11 @@ _rl_release_sigwinch (void)
 
 #endif /* SIGWINCH */
 
   sigwinch_blocked = 0;
 }
+#endif /* !SIGWINCH */
 
 /* **************************************************************** */
 /*								    */
 /*		Echoing special control characters		    */
 /*								    */
diff -aprNU5 readline-8.0.orig/tcap.h readline-8.0/tcap.h
--- readline-8.0.orig/tcap.h	2016-01-25 15:36:14 +0000
+++ readline-8.0/tcap.h	2019-01-09 13:48:00 +0000
@@ -24,18 +24,34 @@
 
 #if defined (HAVE_CONFIG_H)
 #  include "config.h"
 #endif
 
+#if !defined (__MSDOS__)
+#  define HAVE_TERMCAP_API
+#else  /* __MSDOS__ */
+/* On MS-DOS, no termcap is needed/available. */
+#  undef HAVE_TERMCAP_API
+
+#  if defined (__DJGPP__)
+/* When not standalone (as in using Bash),
+   the termcap API is always available.  */
+#    if defined (HAVE_PDCURSES_TERMCAP_API) && !defined (RL_LIBRARY_VERSION)
+#      define HAVE_TERMCAP_API
+#    endif
+#  endif
+#endif
+
 #if defined (HAVE_TERMCAP_H)
 #  if defined (__linux__) && !defined (SPEED_T_IN_SYS_TYPES)
 #    include "rltty.h"
 #  endif
 #  include <termcap.h>
 #elif defined (HAVE_NCURSES_TERMCAP_H)
 #  include <ncurses/termcap.h>
 #else
+#  if defined (HAVE_TERMCAP_API)
 
 /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
    Unfortunately, PC is a global variable used by the termcap library. */
 #ifdef PC
 #  undef PC
@@ -52,9 +68,10 @@ extern int tgetnum ();
 extern char *tgetstr ();
 
 extern int tputs ();
 
 extern char *tgoto ();
+#  endif /* HAVE_TERMCAP_API */
 
 #endif /* HAVE_TERMCAP_H */
 
 #endif /* !_RLTCAP_H_ */
diff -aprNU5 readline-8.0.orig/terminal.c readline-8.0/terminal.c
--- readline-8.0.orig/terminal.c	2018-10-29 14:56:26 +0000
+++ readline-8.0/terminal.c	2019-01-09 13:48:00 +0000
@@ -78,10 +78,16 @@ static void _win_get_screensize PARAMS((
 
 #if defined (__EMX__)
 static void _emx_get_screensize PARAMS((int *, int *));
 #endif
 
+#if defined (__DJGPP__) && defined (HAVE_TERMCAP_API)
+#  include <conio.h>
+
+static void _djgpp_get_screensize PARAMS((int *, int *));
+#endif
+
 /* If the calling application sets this to a non-zero value, readline will
    use the $LINES and $COLUMNS environment variables to set its idea of the
    window size before interrogating the kernel. */
 int rl_prefer_env_winsize = 0;
 
@@ -93,11 +99,11 @@ int rl_change_environment = 1;
 /*								    */
 /*			Terminal and Termcap			    */
 /*								    */
 /* **************************************************************** */
 
-#ifndef __MSDOS__
+#if defined (HAVE_TERMCAP_API)
 static char *term_buffer = (char *)NULL;
 static char *term_string_buffer = (char *)NULL;
 #endif
 
 static int tcap_initialized;
@@ -220,10 +226,23 @@ _win_get_screensize (int *swp, int *shp)
 	}
     }
 }
 #endif
 
+#if defined (__DJGPP__) && defined (HAVE_TERMCAP_API)
+static void
+_djgpp_get_screensize (swp, shp)
+     int *swp, *shp;
+{
+  struct text_info screen_info;
+  gettextinfo (&screen_info);
+  *swp = (int)screen_info.screenwidth;
+  *shp = (int)screen_info.screenheight;
+}
+#undef gettextinfo
+#endif
+
 /* Get readline's idea of the screen size.  TTY is a file descriptor open
    to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
    values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
    non-null serve to check whether or not we have initialized termcap. */
 void
@@ -244,10 +263,14 @@ _rl_get_screen_size (int tty, int ignore
     }
 #endif /* TIOCGWINSZ */
 
 #if defined (__EMX__)
   _emx_get_screensize (&wc, &wr);
+#elif defined (__DJGPP__)
+#  if defined (HAVE_TERMCAP_API)
+  _djgpp_get_screensize (&wc, &wr);
+#  endif
 #elif defined (__MINGW32__)
   _win_get_screensize (&wc, &wr);
 #endif
 
   if (ignore_env || rl_prefer_env_winsize == 0)
@@ -267,11 +290,11 @@ _rl_get_screen_size (int tty, int ignore
 	_rl_screenwidth = atoi (ss);
 
       if (_rl_screenwidth <= 0)
         _rl_screenwidth = wc;
 
-#if defined (__DJGPP__)
+#if !defined (HAVE_TERMCAP_API)
       if (_rl_screenwidth <= 0)
 	_rl_screenwidth = ScreenCols ();
 #else
       if (_rl_screenwidth <= 0 && term_string_buffer)
 	_rl_screenwidth = tgetnum ("co");
@@ -286,11 +309,11 @@ _rl_get_screen_size (int tty, int ignore
 	_rl_screenheight = atoi (ss);
 
       if (_rl_screenheight <= 0)
         _rl_screenheight = wr;
 
-#if defined (__DJGPP__)
+#if !defined (HAVE_TERMCAP_API)
       if (_rl_screenheight <= 0)
 	_rl_screenheight = ScreenRows ();
 #else
       if (_rl_screenheight <= 0 && term_string_buffer)
 	_rl_screenheight = tgetnum ("li");
@@ -421,11 +444,11 @@ static const struct _tc_string tc_string
 /* Read the desired terminal capability strings into BP.  The capabilities
    are described in the TC_STRINGS table. */
 static void
 get_term_capabilities (char **bp)
 {
-#if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
+#if defined (HAVE_TERMCAP_API)
   register int i;
 
   for (i = 0; i < NUM_TC_STRINGS; i++)
     *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
 #endif
@@ -459,11 +482,17 @@ _rl_init_terminal_io (const char *termin
   _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
 #if defined(HACK_TERMCAP_MOTION)
   _rl_term_forward_char = (char *)NULL;
 #endif
 
+#if defined (HAVE_TERMCAP_API)
+  _djgpp_get_screensize (&_rl_screenwidth, &_rl_screenheight);
+  _rl_screenwidth--;
+#else /* !HAVE_TERMCAP_API */
   _rl_get_screen_size (tty, 0);
+#endif /* !HAVE_TERMCAP_API */
+
 #else  /* !__MSDOS__ */
   /* I've separated this out for later work on not calling tgetent at all
      if the calling application has supplied a custom redisplay function,
      (and possibly if the application has supplied a custom input function). */
   if (CUSTOM_REDISPLAY_FUNC())
@@ -601,19 +630,21 @@ bind_termcap_arrow_keys (Keymap map)
 }
 
 char *
 rl_get_termcap (const char *cap)
 {
+#if !defined (__MSDOS__)
   register int i;
 
   if (tcap_initialized == 0)
     return ((char *)NULL);
   for (i = 0; i < NUM_TC_STRINGS; i++)
     {
       if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
         return *(tc_strings[i].tc_value);
     }
+#endif /* !__MSDOS__ */
   return ((char *)NULL);
 }
 
 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
    has changed. */
@@ -717,11 +748,11 @@ rl_ding (void)
 static int enabled_meta = 0;	/* flag indicating we enabled meta mode */
 
 void
 _rl_enable_meta_key (void)
 {
-#if !defined (__DJGPP__)
+#if defined (HAVE_TERMCAP_API)
   if (term_has_meta && _rl_term_mm)
     {
       tputs (_rl_term_mm, 1, _rl_output_character_function);
       enabled_meta = 1;
     }
@@ -729,11 +760,11 @@ _rl_enable_meta_key (void)
 }
 
 void
 _rl_disable_meta_key (void)
 {
-#if !defined (__DJGPP__)
+#if defined (HAVE_TERMCAP_API)
   if (term_has_meta && _rl_term_mo && enabled_meta)
     {
       tputs (_rl_term_mo, 1, _rl_output_character_function);
       enabled_meta = 0;
     }
@@ -741,11 +772,11 @@ _rl_disable_meta_key (void)
 }
 
 void
 _rl_control_keypad (int on)
 {
-#if !defined (__DJGPP__)
+#if defined (HAVE_TERMCAP_API)
   if (on && _rl_term_ks)
     tputs (_rl_term_ks, 1, _rl_output_character_function);
   else if (!on && _rl_term_ke)
     tputs (_rl_term_ke, 1, _rl_output_character_function);
 #endif
diff -aprNU5 readline-8.0.orig/tilde.c readline-8.0/tilde.c
--- readline-8.0.orig/tilde.c	2017-03-08 23:47:16 +0000
+++ readline-8.0/tilde.c	2019-01-09 13:48:00 +0000
@@ -190,11 +190,11 @@ tilde_expand (const char *string)
 {
   char *result;
   int result_size, result_index;
 
   result_index = result_size = 0;
-  if (result = strchr (string, '~'))
+  if ((result = strchr (string, '~')))
     result = (char *)xmalloc (result_size = (strlen (string) + 16));
   else
     result = (char *)xmalloc (result_size = (strlen (string) + 1));
 
   /* Scan through STRING expanding tildes as we come to them. */
@@ -237,11 +237,11 @@ tilde_expand (const char *string)
 	expansion = tilde_word;
       else
 	xfree (tilde_word);	
 
       len = strlen (expansion);
-#ifdef __CYGWIN__
+#if defined (_WIN32) || defined (__MSDOS__)
       /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
 	 $HOME for `user' is /.  On cygwin, // denotes a network drive. */
       if (len > 1 || *expansion != '/' || *string != '/')
 #endif
 	{
diff -aprNU5 readline-8.0.orig/tminit.c readline-8.0/tminit.c
--- readline-8.0.orig/tminit.c	1970-01-01 00:00:00 +0000
+++ readline-8.0/tminit.c	2019-01-09 13:48:00 +0000
@@ -0,0 +1,1532 @@
+/*
+ * tminit.c - initializer and main part of termios emulation.
+ *   designed for DJGPP by Daisuke Aoyama <jack@st.rim.or.jp>
+ *   special thanks to Ryo Shimizu
+ */
+
+#if defined (__DJGPP__)
+
+#include <libc/stubs.h>
+#include <conio.h>
+#include <fcntl.h>
+#include <go32.h>
+#include <io.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/farptr.h>
+#include <sys/fsext.h>
+#include <libc/bss.h>
+#include <libc/file.h>
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+#include <sys/version.h>
+
+#if __DJGPP_MINOR__ < 4
+# define _DEV_STDIN  0x0001
+# define _DEV_STDOUT 0x0002
+# define _DEV_NUL    0x0004
+# define _DEV_CLOCK  0x0008
+# define _DEV_RAW    0x0020
+# define _DEV_CDEV   0x0080
+# define _DEV_IOCTRL 0x4000
+#else
+# include <libc/getdinfo.h>
+#endif
+
+#define CPMEOF 0x1a /* Ctrl+Z */
+
+#define _REG_STATUS_CF 0x01
+#define _REG_STATUS_ZF 0x40
+#define _KEY_INS  0x80
+#define _KEY_CAPS 0x40
+#define _KEY_NUM  0x20
+#define _KEY_SCRL 0x10
+#define _KEY_ALT  0x08
+#define _KEY_CTRL 0x04
+#define _KEY_LSFT 0x02
+#define _KEY_RSFT 0x01
+#define _KEYE_SYSRQ 0x80
+#define _KEYE_CAPS  0x40
+#define _KEYE_NUM   0x20
+#define _KEYE_SCRL  0x10
+#define _KEYE_RALT  0x08
+#define _KEYE_RCTRL 0x04
+#define _KEYE_LALT  0x02
+#define _KEYE_LCTRL 0x01
+
+#define CHECKBYTES 32
+
+/* tty buffers */
+unsigned char __libc_tty_queue_buffer[_TTY_QUEUE_SIZE];
+struct tty __libc_tty_internal = TTYDEFAULT;
+struct tty *__libc_tty_p = &__libc_tty_internal;
+struct tty_editline __libc_tty_editline = { 0, { 0 }, { 0 }, };
+
+/* global only in the termios functions */
+int __libc_termios_hook_common_count = -1;
+
+/* static variables */
+static int __libc_use_function_and_arrow_keys = 0;
+static int __libc_has_enhanced_keyboard = 0;
+static int __libc_has_extended_keystroke = 0;
+static unsigned char __libc_extended_keystroke[16] = { 0, };
+static ssize_t __libc_termios_check_bytes = CHECKBYTES;
+
+/* static functions */
+static void __libc_termios_fflushall (void);
+static void __libc_termios_init_direct_functions (void);
+static ssize_t __libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv);
+static ssize_t __libc_termios_read_cooked_tty (int handle, void *buffer, size_t count);
+static ssize_t __libc_termios_read_raw_tty (int handle, void *buffer, size_t count);
+static ssize_t __libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv);
+static ssize_t __libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count);
+static ssize_t __libc_termios_write_raw_tty (int handle, const void *buffer, size_t count);
+static int __libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap);
+static void __libc_termios_echo_ctrl (unsigned char ch);
+static void __libc_termios_maybe_echo_ctrl (unsigned char ch);
+static void __libc_termios_maybe_echo (unsigned char ch);
+static void __libc_termios_maybe_erase1 (void);
+static void __libc_termios_erase_editline (void);
+static void __libc_termios_kill_editline (void);
+static void __libc_termios_insert_editline (unsigned char ch);
+#if __DJGPP_MINOR__ < 4
+static int __libc_termios_exist_queue (void);
+#endif
+static void __libc_termios_clear_queue (void);
+static int __libc_termios_get_queue (void);
+static int __libc_termios_put_queue (unsigned char ch);
+static void __libc_termios_raise_signal (unsigned char ch, int sig);
+static void __libc_termios_fill_queue (void);
+
+/* direct I/O functions */
+static void __direct_add_keystroke (int c);
+static void __direct_add_keystrokes (char *s);
+static void __direct_check_extened_keystroke_at (int scan);
+/* AT keyboard */
+static int __direct_keysense_at (void);
+static unsigned char __direct_keyinput_at (void);
+static int __direct_ctrlsense_at (void);
+/* AT enhanced keyboard */
+static int __direct_keysense_ate (void);
+static unsigned char __direct_keyinput_ate (void);
+static int __direct_ctrlsense_ate (void);
+/* Output functions */
+static void __direct_output_tab_at (void);
+static void __direct_output_at (unsigned char ch);
+static void __direct_outputns_at (int n, const unsigned char *s);
+static void __direct_outputs_at (const unsigned char *s);
+/* function pointers */
+static int (*__direct_keysense) (void) = __direct_keysense_at;
+static unsigned char (*__direct_keyinput) (void) = __direct_keyinput_at;
+static int (*__direct_ctrlsense) (void) = __direct_ctrlsense_at;
+static void (*__direct_output) (unsigned char ch) = __direct_output_at;
+static void (*__direct_outputns) (int n, const unsigned char *s) = __direct_outputns_at;
+static void (*__direct_outputs) (const unsigned char *s) = __direct_outputs_at;
+
+/******************************************************************************/
+/* initialize function ********************************************************/
+
+static void
+__libc_termios_fflushall (void)
+{
+#if 0 /* don't work on djgpp */
+  fflush (NULL);
+#else
+  _fwalk ((void (*) (FILE*)) fflush);
+#endif
+}
+
+static void
+__libc_termios_init_direct_functions (void)
+{
+  __libc_has_enhanced_keyboard = 0;
+  __libc_has_extended_keystroke = 0;
+
+  if (_farpeekb (_dos_ds, 0x496) & 0x10)
+    __libc_has_enhanced_keyboard = 1;
+
+  if (__libc_has_enhanced_keyboard)
+    {
+      __direct_keysense = __direct_keysense_ate;
+      __direct_keyinput = __direct_keyinput_ate;
+      __direct_ctrlsense = __direct_ctrlsense_ate;
+    }
+  else
+    {
+      __direct_keysense = __direct_keysense_at;
+      __direct_keyinput = __direct_keyinput_at;
+      __direct_ctrlsense = __direct_ctrlsense_at;
+    }
+  __direct_output = __direct_output_at;
+  __direct_outputs = __direct_outputs_at;
+}
+
+void
+__libc_termios_init (void)
+{
+  if (__libc_termios_hook_common_count != __bss_count)
+    {
+      __libc_termios_hook_common_count = __bss_count;
+
+      /* flush all buffered streams */
+      __libc_termios_fflushall ();
+
+      /* check enhanced keyboard, etc */
+      __libc_termios_init_direct_functions ();
+
+      /* set special hooks */
+      __libc_read_termios_hook = __libc_termios_read;
+      __libc_write_termios_hook = __libc_termios_write;
+
+      /* import parameters */
+      /* __libc_tty_p = ...; */
+
+      /* fsext */
+      (void) __FSEXT_set_function (0, __libc_termios_fsext);
+      (void) __FSEXT_set_function (1, __libc_termios_fsext);
+      (void) __FSEXT_set_function (2, __libc_termios_fsext);
+      __libc_termios_check_bytes = CHECKBYTES;
+    }
+}
+
+int
+__libc_termios_disable_function_and_arrow_keys (void)
+{
+  int old_value;
+
+  old_value = __libc_use_function_and_arrow_keys;
+  __libc_use_function_and_arrow_keys = 0;
+
+  return old_value;
+}
+
+int
+__libc_termios_enable_function_and_arrow_keys (void)
+{
+  int old_value;
+
+  old_value = __libc_use_function_and_arrow_keys;
+  __libc_use_function_and_arrow_keys = 1;
+
+  return old_value;
+}
+
+/******************************************************************************/
+/* direct I/O function ********************************************************/
+
+/* function key trans function */
+static void
+__direct_add_keystroke (int c)
+{
+  if (__libc_has_extended_keystroke + 1 > sizeof (__libc_extended_keystroke))
+    return;
+
+  __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) c;
+}
+
+static void
+__direct_add_keystrokes (char *s)
+{
+  int len;
+
+  len = strlen (s);
+  if (__libc_has_extended_keystroke + len > sizeof (__libc_extended_keystroke))
+    return;
+
+  while (--len >= 0)
+    __libc_extended_keystroke[__libc_has_extended_keystroke++] = (unsigned char) s[len];
+}
+
+#define _NDUMMY (0xffU)
+#define _N(c) (0x00U|(c)) /* no shift */
+#define _S(c) (0x40U|(c)) /* w/shift */
+#define _C(c) (0x80U|(c)) /* w/ctrl */
+#define _A(c) (0xc0U|(c)) /* w/alt */
+#define _TRANS_NOSHIFT "\x1b[0"
+#define _TRANS_SHIFT "\x1b[1"
+#define _TRANS_CTRL "\x1b[2"
+#define _TRANS_ALT "\x1b[3"
+
+static unsigned char trans_alphabet_chars[64] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZ123456ABCDEFGHIJKLMNOPQRSTUVWXYZ123456";
+
+static unsigned char trans_mapping_chras_at[] =
+{
+  /* 000-037: A-Z, 040-077: XA-XZ */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 00-07 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 08-0F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 10-17 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 18-1F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 20-27 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 28-2F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 30-37 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _N(040), _N(041), _N(042), _N(043), _N(044), /* 38-3F */
+  _N(045), _N(046), _N(047), _N(050), _N(051), _NDUMMY, _NDUMMY, _N(006), /* 40-47 */
+  _N(000), _N(010), _NDUMMY, _N(001), _NDUMMY, _N(002), _NDUMMY, _N(007), /* 48-4F */
+  _N(003), _N(011), _N(004), _N(005), _S(040), _S(041), _S(042), _S(043), /* 50-57 */
+  _S(044), _S(045), _S(046), _S(047), _S(050), _S(051), _C(040), _C(041), /* 58-5F */
+  _C(042), _C(043), _C(044), _C(045), _C(046), _C(047), _C(050), _C(051), /* 60-67 */
+  _A(040), _A(041), _A(042), _A(043), _A(044), _A(045), _A(046), _A(047), /* 68-6F */
+  _A(050), _A(051), _NDUMMY, _C(001), _C(002), _C(007), _C(011), _C(006), /* 70-77 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* 78-7F */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _C(010), _N(052), _N(053), _S(052), /* 80-87 */
+  _S(053), _C(052), _C(053), _A(052), _A(053), _C(000), _NDUMMY, _NDUMMY, /* 88-8F */
+  _NDUMMY, _C(003), _C(004), _C(005), _NDUMMY, _NDUMMY, _NDUMMY, _A(006), /* 90-97 */
+  _A(000), _A(010), _NDUMMY, _A(001), _NDUMMY, _A(002), _NDUMMY, _A(007), /* 98-9F */
+  _A(003), _A(011), _A(004), _A(005), _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A0-A7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* A8-AF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B0-B7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* B8-BF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C0-C7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* C8-CF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D0-D7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* D8-DF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E0-E7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* E8-EF */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F0-F7 */
+  _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, _NDUMMY, /* F8-FF */
+};
+
+static void
+__direct_check_extened_keystroke_at (int scan)
+{
+  int c, shift;
+
+  if (!__libc_use_function_and_arrow_keys || scan < 0 || scan > 0xff)
+    return;
+
+  c = (int) trans_mapping_chras_at[scan];
+  if (c == (int) _NDUMMY)
+    return;
+
+  shift = c & 0xc0;
+  c &= ~0xc0;
+  __direct_add_keystroke (trans_alphabet_chars[c]);
+  if (c >= 040)
+    __direct_add_keystroke ('X');
+  if (shift == 0x00)
+    __direct_add_keystrokes (_TRANS_NOSHIFT);
+  else if (shift == 0x40)
+    __direct_add_keystrokes (_TRANS_SHIFT);
+  else if (shift == 0x80)
+    __direct_add_keystrokes (_TRANS_CTRL);
+  else if (shift == 0xc0)
+    __direct_add_keystrokes (_TRANS_ALT);
+}
+
+/* Input form AT keyboard */
+static int
+__direct_keysense_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 1;
+
+  r.h.ah = 0x01;
+  __dpmi_int (0x16, &r);
+  if (r.x.flags & _REG_STATUS_ZF)
+    return 0;
+
+  return 1;
+}
+
+static unsigned char
+__direct_keyinput_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  r.h.ah = 0x00;
+  __dpmi_int (0x16, &r);
+  if (r.h.al != 0x00)
+    return r.h.al;
+
+  __direct_check_extened_keystroke_at (r.h.ah);
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  return 0;
+}
+
+static int
+__direct_ctrlsense_at (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 0;
+
+  r.h.ah = 0x02;
+  __dpmi_int (0x16, &r);
+  if (r.h.al & _KEY_CTRL)
+    return 1;
+
+  return 0;
+}
+
+/* Input from AT enhanced keyboard */
+static int
+__direct_keysense_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 1;
+
+  r.h.ah = 0x11;
+  __dpmi_int (0x16, &r);
+  if (r.x.flags & _REG_STATUS_ZF)
+    return 0;
+
+  return 1;
+}
+
+static unsigned char
+__direct_keyinput_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  r.h.ah = 0x10;
+  __dpmi_int (0x16, &r);
+  if (r.h.al != 0x00 && (r.h.al < 0xe0U
+			 || (r.h.al != 0xe0 && r.h.al != 0xf0)))
+    return r.h.al;
+
+  __direct_check_extened_keystroke_at (r.h.ah);
+  if (__libc_has_extended_keystroke)
+    return __libc_extended_keystroke[--__libc_has_extended_keystroke];
+
+  return 0;
+}
+
+static int
+__direct_ctrlsense_ate (void)
+{
+  __dpmi_regs r;
+
+  if (__libc_has_extended_keystroke)
+    return 0;
+
+  r.h.ah = 0x12;
+  __dpmi_int (0x16, &r);
+  if (r.h.al & _KEY_CTRL) /* either CTRL */
+    return 1;
+
+  return 0;
+}
+
+/* output to Screen */
+static void
+__direct_output_tab_at (void)
+{
+  __dpmi_regs r;
+  int page, col;
+  int x, y;
+
+  page = _farpeekb (_dos_ds, 0x462);
+  col = _farpeekw (_dos_ds, 0x44a);
+
+  r.h.ah = 3;
+  r.h.bh = page;
+  __dpmi_int (0x10, &r);
+  x = r.h.dl;
+  y = r.h.dh;
+
+  x += 8;
+  x &= ~7;
+  if (x > col)
+    {
+#if 1
+      r.h.al = '\r';
+      __dpmi_int (0x29, &r);
+      r.h.al = '\n';
+      __dpmi_int (0x29, &r);
+#else
+      (void) putch ('\r');
+      (void) putch ('\n');
+#endif
+    }
+  else
+    {
+      r.h.ah = 2;
+      r.h.bh = page;
+      r.h.dl = x;
+      r.h.dh = y;
+      __dpmi_int (0x10, &r);
+    }
+}
+
+static void
+__direct_output_at (unsigned char ch)
+{
+#if 1
+  __dpmi_regs r;
+#endif
+
+  if (ch == 0x09)
+    {
+      __direct_output_tab_at ();
+      return;
+    }
+  else if (ch == 0xff)
+    return;
+
+#if 1
+  r.h.al = ch;
+  __dpmi_int (0x29, &r);
+#else
+  (void) putch (ch);
+#endif
+}
+
+static void
+__direct_outputns_at (int n, const unsigned char *s)
+{
+#if 1
+  __dpmi_regs r;
+#endif
+  unsigned char ch;
+
+  while (--n >= 0)
+    {
+      ch = *s++;
+      if (ch == 0x09)
+	__direct_output_tab_at ();
+      else if (ch != 0xff)
+	{
+#if 1
+	  r.h.al = ch;
+	  __dpmi_int (0x29, &r);
+#else
+	  (void) putch (ch);
+#endif
+	}
+    }
+}
+
+static void
+__direct_outputs_at (const unsigned char *s)
+{
+  while (*s)
+    __direct_output_at (*s++);
+}
+
+/******************************************************************************/
+/* special read function ******************************************************/
+
+static ssize_t
+__libc_termios_read (int handle, void *buffer, size_t count, ssize_t *rv)
+{
+  short devmod;
+  ssize_t bytes;
+
+  /* check handle whether valid or not */
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    {
+      *rv = -1;
+      return 1;
+    }
+
+  /* special case */
+  if (count == 0)
+    {
+      *rv = 0;
+      return 1;
+    }
+
+  /* console only... */
+  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    {
+      /* character device */
+      if (devmod & _DEV_RAW)
+	*rv = __libc_termios_read_raw_tty (handle, buffer, count);
+      else
+	*rv = __libc_termios_read_cooked_tty (handle, buffer, count);
+      return 1;
+    }
+
+  if (__file_handle_modes[handle] & O_BINARY)
+    {
+      bytes = _read (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+    }
+  else
+    {
+      unsigned char *rp, *wp;
+      ssize_t n;
+
+      bytes = _read (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+
+      rp = wp = buffer;
+      n = bytes;
+      while (--n >= 0)
+	{
+	  unsigned char ch;
+
+	  ch = *rp++;
+	  if (ch == CPMEOF)
+	    {
+	      ++n;
+	      (void) lseek (handle, -n, SEEK_CUR);
+	      break;
+	    }
+	  else if (ch == '\r')
+	    {
+	      if (n > 0)
+		{
+		  /* peek next character */
+		  if (*rp == '\n')
+		    {
+		      /* if found '\n', delete '\r' */
+		      ch = *rp++;
+		      --n;
+		    }
+		}
+	      else
+		{
+		  unsigned char tmpch;
+
+		  /* read a character to peek */
+		  if (_read (handle, &tmpch, 1) == 1)
+		    {
+		      if (tmpch == '\n')
+			ch = tmpch;
+		      else
+			(void) lseek (handle, -1, SEEK_CUR);
+		    }
+		}
+	    }
+	  *wp++ = ch;
+	}
+      bytes = wp - (unsigned char *) buffer;
+    }
+
+  /* result of read() */
+  *rv =  bytes;
+  return 1;
+}
+
+static ssize_t
+__libc_termios_read_cooked_tty (int handle, void *buffer, size_t count)
+{
+  unsigned char *wp;
+  ssize_t n;
+
+  wp = buffer;
+  n = count;
+
+#if 0
+  /* clear cooked queue */
+  if (__libc_termios_exist_queue ())
+    __libc_termios_clear_queue ();
+#endif
+
+  if (__libc_tty_p->t_lflag & ICANON)
+    {
+      /* get inputs (wait for NL or EOT) */
+      if (! __libc_termios_exist_queue ())
+	__libc_termios_fill_queue ();
+
+      while (--n >= 0)
+	{
+	  if (! __libc_termios_exist_queue ())
+	    break;
+
+	  *wp++ = __libc_termios_get_queue ();
+	}
+    }
+  else
+    {
+      /* block until getting inputs */
+      while (! __libc_termios_exist_queue ())
+	{
+	  __dpmi_yield ();
+	  __libc_termios_fill_queue ();
+	}
+
+      while (--n >= 0)
+	{
+	  *wp++ = __libc_termios_get_queue ();
+
+	  if (! __libc_termios_exist_queue ())
+	    {
+	      __libc_termios_fill_queue ();
+	      if (! __libc_termios_exist_queue ())
+		break;
+	    }
+	}
+    }
+
+  return (ssize_t) (wp - (unsigned char *) buffer);
+}
+
+static ssize_t
+__libc_termios_read_raw_tty (int handle, void *buffer, size_t count)
+{
+  unsigned char *wp;
+  unsigned char ch;
+  ssize_t n;
+
+  n = count;
+  wp = buffer;
+
+  /* clear cooked queue */
+  if (__libc_termios_exist_queue ())
+    __libc_termios_clear_queue ();
+
+  /* block until getting inputs */
+  while (! __direct_keysense ())
+    __dpmi_yield ();
+
+  while (--n >= 0)
+    {
+      /* exhaust inputs ? */
+      if (! __direct_keysense ())
+	break;
+
+      /* realy get */
+      ch = __direct_keyinput ();
+
+      /* replace CTRL+SPACE with 0x00 */
+      if (ch == ' ' && __direct_ctrlsense ())
+	ch = '\0';
+
+      /* copy a character into buffer and echo */
+      *wp++ = ch;
+      __libc_termios_maybe_echo (ch);
+    }
+
+  return (ssize_t) (wp - (unsigned char *) buffer);
+}
+
+/******************************************************************************/
+/* special write function *****************************************************/
+
+static unsigned char __libc_termios_write_sbuf_internal[64];
+static unsigned char *__libc_termios_write_sbuf = NULL;
+static size_t __libc_termios_write_sbuflen = 0;
+static int __libc_termios_write_count = -1;
+
+void
+__libc_termios_check_signals (void);
+
+static ssize_t
+__libc_termios_write (int handle, const void *buffer, size_t count, ssize_t *rv)
+{
+  short devmod;
+  ssize_t bytes;
+
+  /* check handle whether valid or not */
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    {
+      *rv = -1;
+      return 1;
+    }
+
+  /* special case */
+  if (count == 0)
+    {
+      *rv = 0;
+      return 1;
+    }
+
+  /* console only... */
+  if ((devmod & _DEV_CDEV) && (devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    {
+      /* character device */
+      if (devmod & _DEV_RAW)
+	*rv = __libc_termios_write_raw_tty (handle, buffer, count);
+      else
+	*rv = __libc_termios_write_cooked_tty (handle, buffer, count);
+      return 1;
+    }
+
+  if (__file_handle_modes[handle] & O_BINARY)
+    {
+      bytes = _write (handle, buffer, count);
+      if (bytes < 0)
+	{
+	  *rv = -1;
+	  return 1;
+	}
+    }
+  else
+    {
+      const unsigned char *rp;
+      unsigned char *tp, *ep;
+      ssize_t n;
+
+      /* initialize local buffer */
+      if (__libc_termios_write_count != __bss_count)
+	{
+	  __libc_termios_write_count = __bss_count;
+	  __libc_termios_write_sbuflen = _go32_info_block.size_of_transfer_buffer;
+	  __libc_termios_write_sbuf = malloc (__libc_termios_write_sbuflen);
+	  if (__libc_termios_write_sbuf == NULL)
+	    {
+	      __libc_termios_write_sbuf = &__libc_termios_write_sbuf_internal[0];
+	      __libc_termios_write_sbuflen = sizeof (__libc_termios_write_sbuf_internal);
+	    }
+	}
+
+      rp = buffer;
+      tp = __libc_termios_write_sbuf;
+      ep = tp + __libc_termios_write_sbuflen;
+      n = count;
+      bytes = 0;
+      while (n >= 0)
+	{
+	  unsigned char *wp;
+	  unsigned char ch;
+	  ssize_t ncr, wbytes;
+
+	  /* fill local buffer */
+	  wp = tp;
+	  ncr = 0;
+	  while ((wp < ep) && (--n >= 0))
+	    {
+	      /* get character */
+	      ch = *rp++;
+
+	      /* LF conversion */
+	      if (ch == '\n')
+		{
+		  if (wp == (ep - 1))
+		    {
+		      n++;
+		      rp--;
+		      break;
+		    }
+		  *wp++ = '\r';
+		  ncr++;
+		}
+
+	      /* put character */
+	      *wp++ = ch;
+	    }
+
+	  /* write on handle */
+	  wbytes = _write (handle, tp, (size_t) (wp - tp));
+	  if (wbytes < 0)
+	    {
+	      *rv = -1;
+	      return 1;
+	    }
+	  if (wbytes < (ssize_t) (wp - tp))
+	    {
+	      /* detected disk full, but the result is not reality */
+	      *rv = bytes + (wbytes > ncr ? wbytes - ncr : 0);
+	      return 1;
+	    }
+
+	  /* don't count CR */
+	  bytes += wbytes - ncr;
+	}
+    }
+
+  __libc_termios_check_bytes -= bytes;
+  if (__libc_termios_check_bytes <= 0)
+    {
+      __libc_termios_check_bytes = CHECKBYTES;
+      __libc_termios_check_signals ();
+    }
+
+  /* result of write() */
+  *rv =  bytes;
+  return 1;
+}
+
+static ssize_t
+__libc_termios_write_cooked_tty (int handle, const void *buffer, size_t count)
+{
+  ssize_t bytes;
+
+  /* output process if need */
+  if (__libc_tty_p->t_oflag & OPOST)
+    {
+      const unsigned char *rp;
+      unsigned char ch;
+      ssize_t n, nn;
+
+      rp = buffer;
+      n = count;
+      while (n > 0)
+	{
+	  nn = (n < __libc_termios_check_bytes) ? n : __libc_termios_check_bytes;
+	  n -= nn;
+	  __libc_termios_check_bytes -= nn;
+
+	  while (--nn >= 0)
+	    {
+	      /* get character */
+	      ch = *rp++;
+
+	      /* NOTE: multibyte character don't contain control character */
+	      /* map NL to CRNL */
+	      if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR))
+		__direct_output ('\r');
+	      /* map CR to NL */
+	      else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL))
+		ch = '\n';
+
+	      __direct_output (ch);
+	    }
+
+	  if (__libc_termios_check_bytes <= 0)
+	    {
+	      __libc_termios_check_bytes = CHECKBYTES;
+	      __libc_termios_check_signals ();
+	    }
+	}
+
+      /* don't count CR */
+      bytes = count;
+    }
+  else
+    {
+      /* output with no effect */
+      bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+    }
+
+  return bytes;
+}
+
+static ssize_t
+__libc_termios_write_raw_tty (int handle, const void *buffer, size_t count)
+{
+  const unsigned char *rp;
+  ssize_t n;
+
+  rp = buffer;
+  n = count;
+  while (n > 0)
+    {
+      if (n < __libc_termios_check_bytes)
+	{
+	  __libc_termios_check_bytes -= n;
+	  __direct_outputns (n, rp);
+	  rp += n;
+	  break;
+	}
+      else
+	{
+	  n -= __libc_termios_check_bytes;
+	  __direct_outputns (__libc_termios_check_bytes, rp);
+	  rp += __libc_termios_check_bytes;
+	  __libc_termios_check_bytes = CHECKBYTES;
+	  __libc_termios_check_signals ();
+	}
+    }
+
+  return count;
+}
+
+/******************************************************************************/
+/* special fsext function *****************************************************/
+
+static int
+__libc_termios_fsext (__FSEXT_Fnumber n, int *rv, va_list ap)
+{
+  short devmod;
+  ssize_t bytes;
+  int handle;
+
+  handle = va_arg (ap, int);
+  devmod = _get_dev_info (handle);
+  if (devmod == -1)
+    return 0;
+  if (!(devmod & _DEV_CDEV) || !(devmod & (_DEV_STDIN|_DEV_STDOUT)))
+    return 0;
+
+  /* console only... */
+  switch (n)
+    {
+#if 0
+    case __FSEXT_read:
+      {
+	void *buffer;
+	size_t count;
+
+	buffer = va_arg (ap, void *);
+	count = va_arg (ap, size_t);
+	if (devmod & _DEV_RAW)
+	  bytes = __libc_termios_read_raw_tty (handle, buffer, count);
+	else
+	  bytes = __libc_termios_read_cooked_tty (handle, buffer, count);
+
+	/* result of read */
+	*rv = bytes;
+	return 1;
+      }
+    case __FSEXT_write:
+      {
+	const void *buffer;
+	size_t count;
+
+	buffer = va_arg (ap, const void *);
+	count = va_arg (ap, size_t);
+	if (devmod & _DEV_RAW)
+	  bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+	else
+	  bytes = __libc_termios_write_cooked_tty (handle, buffer, count);
+
+	/* result of write */
+	*rv = bytes;
+	return 1;
+      }
+#else
+    case __FSEXT_write:
+      {
+	size_t count;
+	const void *buffer;
+
+	buffer = va_arg (ap, const void *);
+	count = va_arg (ap, size_t);
+	bytes = __libc_termios_write_raw_tty (handle, buffer, count);
+
+	/* result of write */
+	*rv = bytes;
+	return 1;
+      }
+#endif
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+/******************************************************************************/
+/* echo routines **************************************************************/
+
+static void
+__libc_termios_echo_ctrl (unsigned char ch)
+{
+  ch ^= 0x40;
+  __direct_output ('^');
+  __direct_output (ch);
+}
+
+static void
+__libc_termios_maybe_echo_ctrl (unsigned char ch)
+{
+  if (__libc_tty_p->t_lflag & ECHOCTL)
+    __libc_termios_echo_ctrl (ch);
+}
+
+static void
+__libc_termios_maybe_echo (unsigned char ch)
+{
+  if (! (__libc_tty_p->t_lflag & ECHO))
+    {
+      /* don't echo but newline is required ? */
+      if (ch == '\n' && (__libc_tty_p->t_lflag & ECHONL))
+	{
+	  if (__libc_tty_p->t_oflag & ONLCR)
+	    __direct_output ('\r');
+	  __direct_output ('\n');
+	}
+      return;
+    }
+
+  /* check literal flag */
+  if ((__libc_tty_p->t_status & _TS_LNCH) && (ch < 0x20))
+    {
+      __libc_termios_echo_ctrl (ch);
+      return;
+    }
+
+  /* output process if need */
+  if (__libc_tty_p->t_oflag & OPOST)
+    {
+      /* map NL to CRNL */
+      if (ch == '\n' && (__libc_tty_p->t_oflag & ONLCR))
+	{
+	  __direct_output ('\r');
+	  __direct_output ('\n');
+	  return;
+	}
+      /* map CR to NL */
+      else if (ch == '\r' && (__libc_tty_p->t_oflag & OCRNL))
+	{
+	  __direct_output ('\n');
+	  return;
+	}
+      /* discard EOT */
+      else if (_CC_EQU (VEOF, ch) && (__libc_tty_p->t_oflag & ONOEOT))
+	{
+	  return;
+	}
+    }
+
+  /* control character except newline */
+  if ((ch < 0x20 || ch == 0x7f) && (__libc_tty_p->t_lflag & ECHOCTL) && ch != '\n')
+    {
+      __libc_termios_echo_ctrl (ch);
+      return;
+    }
+
+  /* no effect */
+  __direct_output (ch);
+}
+
+/******************************************************************************/
+/* edit routines **************************************************************/
+
+static void
+__libc_termios_maybe_erase1 (void)
+{
+  if (__libc_tty_p->t_lflag & ECHO)
+    {
+      /* eat prev. character by BS SPC BS */
+      __direct_output ('\010');
+      if (__libc_tty_p->t_lflag & ECHOE)
+	{
+	  __direct_output (' ');
+	  __direct_output ('\010');
+	}
+    }
+}
+
+/* erase one prev. character of editline */
+static void
+__libc_termios_erase_editline (void)
+{
+  int col;
+  char pf;
+
+  col = __libc_tty_editline.col;
+  if (col == 0) /* no more */
+    return;
+
+  /* get position flag */
+  pf = __libc_tty_editline.flag[col - 1];
+  if (pf == _TTY_EDITLINE_INVALID || pf < 0)
+    {
+      /* erase all invalid character */
+      while (col > 0 && __libc_tty_editline.flag[col - 1] < 0)
+	{
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+    }
+  else if (pf == _TTY_EDITLINE_CTRL)
+    {
+      if (__libc_tty_p->t_lflag & ECHOCTL)
+	{
+	  /* erase one of "^X" */
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+      __libc_termios_maybe_erase1 ();
+      --col;
+    }
+  else
+    {
+      /* erase single or multibyte charcter */
+      while (--pf >= 0)
+	{
+	  __libc_termios_maybe_erase1 ();
+	  --col;
+	}
+    }
+
+  /* set next insert position */
+  __libc_tty_editline.col = col;
+}
+
+/* erase all editline */
+static void
+__libc_termios_kill_editline (void)
+{
+  if (__libc_tty_p->t_lflag & ECHOKE)
+    {
+      while (__libc_tty_editline.col != 0)
+	__libc_termios_erase_editline ();
+    }
+  else
+    __libc_tty_editline.col = 0;
+
+  if (__libc_tty_p->t_lflag & ECHOK)
+    __libc_termios_maybe_echo ('\n');
+}
+
+static void
+__libc_termios_insert_editline (unsigned char ch)
+{
+  int mbsize;
+  int col;
+
+  col = __libc_tty_editline.col;
+  if (col >= _TTY_EDITLINE_SIZE)
+    {
+      /* detected over flow */
+      if (__libc_tty_p->t_iflag & IMAXBEL)
+	__direct_output ('\007');
+      return;
+    }
+
+  __libc_tty_editline.buf[col] = ch;
+  if (col == 0 || ((col > 0)
+		   && __libc_tty_editline.flag[col - 1] != _TTY_EDITLINE_INVALID))
+    {
+      /* check multibyte length */
+      mbsize = mblen (__libc_tty_editline.buf + col, 1);
+      if (mbsize == 1)
+	{
+	  /* single character */
+	  if ((ch < 0x20) || ch == 0x7f)
+	    __libc_tty_editline.flag[col] = _TTY_EDITLINE_CTRL;
+	  else
+	    __libc_tty_editline.flag[col] = _TTY_EDITLINE_SINGLE;
+	  __libc_termios_maybe_echo (ch);
+	}
+      else
+	{
+	  /* first of multibyte or invalid character */
+	  __libc_tty_editline.flag[col] = _TTY_EDITLINE_INVALID;
+	  __libc_tty_p->t_status |= _TS_LNCH;
+	}
+    }
+  else
+    {
+      int pcol;
+
+      /* look for non fixed flag */
+      pcol = col;
+      while (__libc_tty_editline.flag[pcol - 1] == _TTY_EDITLINE_INVALID)
+	if (--pcol <= 0)
+	  break;
+
+      /* check whether it's multibyte sequence */
+      mbsize = mblen (__libc_tty_editline.buf + pcol, (col - pcol + 1));
+      if (mbsize > 1)
+	{
+	  /* multibyte sequence is good */
+	  while (pcol < col)
+	    {
+	      /* set negative size for dividing sequence */
+	      __libc_tty_editline.flag[pcol] = -mbsize;
+	      __libc_termios_maybe_echo (__libc_tty_editline.buf[pcol]);
+	      pcol++;
+	    }
+	  /* last flag is always positive size */
+	  __libc_tty_editline.flag[col] = mbsize;
+	  __libc_termios_maybe_echo (ch);
+	}
+      else
+	{
+	  if ((col - pcol + 1) > MB_CUR_MAX)
+	    {
+	      /* it's terrible... */
+	      while (pcol <= col)
+		{
+		  /* replace all with valid character */
+		  __libc_tty_editline.flag[pcol] = _TTY_EDITLINE_SINGLE;
+		  __libc_tty_editline.buf[pcol] = 'X';
+		  __libc_termios_maybe_echo ('X');
+		  pcol++;
+		}
+	    }
+
+	  /* continuous multibyte character */
+	  __libc_tty_editline.flag[col] = _TTY_EDITLINE_INVALID;
+	  __libc_tty_p->t_status |= _TS_LNCH;
+	}
+    }
+
+  /* set next insert position */
+  col++;
+  __libc_tty_editline.col = col;
+}
+
+/******************************************************************************/
+/* queued input routines ******************************************************/
+
+#if __DJGPP_MINOR__ < 4
+static int
+#else
+int
+#endif
+__libc_termios_exist_queue (void)
+{
+  return __libc_tty_p->t_count;
+}
+
+static void
+__libc_termios_clear_queue (void)
+{
+  __libc_tty_p->t_count = 0;
+  __libc_tty_p->t_rpos = __libc_tty_p->t_top;
+  __libc_tty_p->t_wpos = __libc_tty_p->t_top;
+}
+
+static int
+__libc_termios_get_queue (void)
+{
+  int ch;
+
+  if (__libc_tty_p->t_count == 0)
+    return -1;
+
+  ch = *__libc_tty_p->t_rpos++;
+  __libc_tty_p->t_count--;
+
+  if (__libc_tty_p->t_rpos >= __libc_tty_p->t_bottom)
+    __libc_tty_p->t_rpos = __libc_tty_p->t_top;
+
+  return ch;
+}
+
+static int
+__libc_termios_put_queue (unsigned char ch)
+{
+  if (__libc_tty_p->t_count >= __libc_tty_p->t_size)
+    return -1;
+
+  *__libc_tty_p->t_wpos++ = ch;
+  __libc_tty_p->t_count++;
+
+  if (__libc_tty_p->t_wpos >= __libc_tty_p->t_bottom)
+    __libc_tty_p->t_wpos = __libc_tty_p->t_top;
+
+  return 0;
+}
+
+static void
+__libc_termios_raise_signal (unsigned char ch, int sig)
+{
+#if 0
+  struct sigaction oldact;
+
+  if (sigaction (sig, NULL, &oldact) == 0)
+    if (oldact.sa_handler == SIG_DFL)
+      __libc_termios_maybe_echo_ctrl (ch);
+#else
+  __libc_termios_maybe_echo_ctrl (ch);
+#endif
+  kill (getpid(), sig);
+}
+
+static void
+__libc_termios_fill_queue (void)
+{
+  unsigned char ch;
+
+  while (1)
+    {
+      /* exhaust inputs ? */
+      if (! __direct_keysense ())
+	{
+	  __dpmi_yield ();
+	  /* wait for NL or EOT ? */
+	  if (__libc_tty_p->t_lflag & ICANON)
+	    continue;
+	  return;
+	}
+
+      /* realy get */
+      ch = __direct_keyinput ();
+
+      /* replace CTRL+SPACE with 0x00 */
+      if (ch == ' ' && __direct_ctrlsense ())
+	ch = '\0';
+
+      /* input process if need */
+      if (! (__libc_tty_p->t_status & _TS_LNCH) || ch != (unsigned char) _POSIX_VDISABLE)
+	{
+	  /* software signals */
+	  if (__libc_tty_p->t_lflag & ISIG)
+	    {
+	      if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch))
+		{
+		  if (__libc_tty_p->t_iflag & BRKINT)
+		    {
+		      __libc_termios_raise_signal (ch, SIGINT);
+		      continue;
+		    }
+		  else
+		    {
+		      ch = '\0';
+		      goto proc_skip;
+		    }
+		}
+	      else if (_CC_EQU (VQUIT, ch))
+		{
+		  __libc_termios_raise_signal (ch, SIGQUIT);
+		  continue;
+		}
+	      else if (_CC_EQU (VSUSP, ch))
+		{
+#ifdef SIGTSTP
+		  __libc_termios_raise_signal (ch, SIGTSTP);
+#else /* djgpp don't have ... */
+		  {
+		    char oldcwd[PATH_MAX];
+		    int fds[5] = { -1, -1, -1, -1, -1 };
+		    int i;
+
+		    for (i = 0; i < 5; i++)
+		      if ((fds[i] = fcntl (i, F_DUPFD, 20)) < 0)
+		        __direct_outputs ("Suspend: cannot save fds\r\n");
+
+		    __direct_outputs ("\r\nSuspended\r\n");
+		    /* keep cwd on exec */
+		    getcwd (oldcwd, sizeof (oldcwd));
+		    system (NULL);
+		    chdir (oldcwd);
+
+		    for (i = 0; i < 5; i++)
+		      if (fds[i] >= 0)
+			{
+			  dup2 (fds[i], i);
+			  close (fds[i]);
+			}
+		  }
+#endif /* !SIGTSTP */
+		  continue;
+		}
+	    }
+
+	  /* flow control... */
+	  if (_CC_EQU (VSTART, ch) && (__libc_tty_p->t_iflag & IXOFF))
+	    {
+	      continue;
+	    }
+	  else if (_CC_EQU (VSTOP, ch) && (__libc_tty_p->t_iflag & IXOFF))
+	    {
+	      continue;
+	    }
+
+	  /* CR/LF process */
+	  if (ch == '\r')
+	    {
+	      if (__libc_tty_p->t_iflag & IGNCR)
+		continue;
+	      if (__libc_tty_p->t_iflag & ICRNL)
+		ch = '\n';
+	    }
+	  else if ((ch == '\n') && (__libc_tty_p->t_iflag & INLCR))
+	    ch = '\r';
+
+	  /* strip 8th-bit */
+	  if (__libc_tty_p->t_iflag & ISTRIP)
+	    ch &= 0x7f;
+	}
+
+proc_skip:
+      if (__libc_tty_p->t_lflag & ICANON)
+	{
+	  if (__libc_tty_p->t_status & _TS_LNCH)
+	    {
+	      __libc_tty_p->t_status &= ~_TS_LNCH;
+	      __libc_termios_insert_editline (ch);
+	    }
+	  else
+	    {
+	      if (_CC_EQU (VERASE, ch))
+		__libc_termios_erase_editline ();
+	      else if (_CC_EQU (VKILL, ch))
+		__libc_termios_kill_editline ();
+	      else if (ch == '\n' || _CC_EQU (VEOF, ch) || _CC_EQU (VEOL, ch))
+		{
+		  int col = __libc_tty_editline.col;
+		  unsigned char *p = __libc_tty_editline.buf;
+
+		  /* clear column for next access */
+		  __libc_tty_editline.col = 0;
+
+		  /* copy editline into tty queue */
+		  while (--col >= 0)
+		    __libc_termios_put_queue (*p++);
+
+		  /* echo terminate character and put it */
+		  __libc_termios_maybe_echo (ch);
+		  if (_CC_NEQU (VEOF, ch))
+		    __libc_termios_put_queue (ch);
+
+		  return;
+		}
+	      else
+		__libc_termios_insert_editline (ch);
+	    } /* !_TS_LNCH */
+	}
+      else /* !ICANON */
+	{
+	  __libc_termios_maybe_echo (ch);
+	  __libc_tty_p->t_status &= ~_TS_LNCH;
+	  __libc_termios_put_queue (ch);
+	}
+    } /* end of while (1) */
+}
+
+/******************************************************************************/
+/* software signal checker ****************************************************/
+
+void
+__libc_termios_check_signals (void)
+{
+  unsigned char ch;
+
+  if (! __direct_keysense ())
+    return;
+
+  /* software signals */
+  if (__libc_tty_p->t_lflag & ISIG)
+    {
+      ch = __direct_keyinput ();
+      if (! (__libc_tty_p->t_iflag & IGNBRK) && _CC_EQU (VINTR, ch))
+	{
+	  if (__libc_tty_p->t_iflag & BRKINT)
+	    {
+	      __libc_termios_raise_signal (ch, SIGINT);
+	      return;
+	    }
+	}
+      else if (_CC_EQU (VQUIT, ch))
+	{
+	  __libc_termios_raise_signal (ch, SIGQUIT);
+	  return;
+	}
+
+      /* for compatiblity */
+      if (ch == 0x13 && !(__libc_tty_p->t_iflag & IXOFF))
+	{
+	  /* CTRL+S */
+	  while (! __direct_keysense ())
+	    __dpmi_yield ();
+	  ch = __direct_keyinput ();
+	  return;
+	}
+
+      /* push back */
+      __direct_add_keystroke ((int) ch);
+    }
+}
+
+/******************************************************************************/
+
+#endif	/* __DJGPP__ */
diff -aprNU5 readline-8.0.orig/vi_mode.c readline-8.0/vi_mode.c
--- readline-8.0.orig/vi_mode.c	2018-10-01 18:48:32 +0000
+++ readline-8.0/vi_mode.c	2019-01-09 13:48:00 +0000
@@ -1342,11 +1342,10 @@ _rl_vi_domove_callback (_rl_vimotion_cxt
 
 /* This code path is taken when not in callback mode. */
 int
 rl_vi_domove (int x, int *ignore)
 {
-  int r;
   _rl_vimotion_cxt *m;
 
   m = _rl_vimvcxt;
   *ignore = m->motion = rl_vi_domove_getchar (m);
 
