2017-07-16  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	These are the patches from /readline/readline-7.0-patches/ of the
	GNU repository.  These must be applied to sources before the DJGPP
	specific ones are applied.


			   READLINE PATCH REPORT
			   =====================

Readline-Release: 7.0
Patch-ID: readline70-001

Bug-Reported-by:        Sean Zha <freeman_cha@hotmail.com>
Bug-Reference-ID:       <BN3PR01MB13657D9303EB94BF6E54216E8CCA0@BN3PR01MB1365.prod.exchangelabs.com>
Bug-Reference-URL:      http://lists.gnu.org/archive/html/bug-bash/2016-09/msg00107.html

Bug-Description:

Readline-7.0 changed the way the history list is initially allocated to reduce
the number of reallocations and copies.  Users who set the readline
history-size variable to a very large number to essentially unlimit the size
of the history list will get memory allocation errors 


			   READLINE PATCH REPORT
			   =====================

Readline-Release: 7.0
Patch-ID: readline70-002

Bug-Reported-by:	Hong Cho <hong.cho@citrix.com>
Bug-Reference-ID:	<c30b5fe62b2543af8297e47ca487c29c@SJCPEX02CL02.citrite.net>
Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-readline/2016-12/msg00002.html

Bug-Description:

There is a race condition in add_history() that can be triggered by a fatal
signal arriving between the time the history length is updated and the time
the history list update is completed. A later attempt to reference an
invalid history entry can cause a crash.



			   READLINE PATCH REPORT
			   =====================

Readline-Release: 7.0
Patch-ID: readline70-003

Bug-Reported-by:	Frédéric Brière <fbriere@fbriere.net>
Bug-Reference-ID:	<20170120180724.7ydq7fb2hsp366dj@fabul.fbriere.net>
Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-readline/2017-01/msg00002.html

Bug-Description:

Readline-7.0 uses pselect(2) to allow readline to handle signals that do not
interrupt read(2), such as SIGALRM, before reading another character.  The
signal mask used in the pselect call did not take into account signals the
calling application blocked before calling readline().












diff -aprNU5 readline-7.0.orig/history.c readline-7.0/history.c
--- readline-7.0.orig/history.c	2015-12-28 18:50:30 +0000
+++ readline-7.0/history.c	2017-07-16 10:05:50 +0000
@@ -55,10 +55,12 @@ extern int errno;
 #endif
 
 /* How big to make the_history when we first allocate it. */
 #define DEFAULT_HISTORY_INITIAL_SIZE	502
 
+#define MAX_HISTORY_INITIAL_SIZE	8192
+
 /* The number of slots to increase the_history by. */
 #define DEFAULT_HISTORY_GROW_SIZE 50
 
 static char *hist_inittime PARAMS((void));
 
@@ -275,10 +277,11 @@ hist_inittime ()
 void
 add_history (string)
      const char *string;
 {
   HIST_ENTRY *temp;
+  int new_length;
 
   if (history_stifled && (history_length == history_max_entries))
     {
       register int i;
 
@@ -291,46 +294,45 @@ add_history (string)
       if (the_history[0])
 	(void) free_history_entry (the_history[0]);
 
       /* Copy the rest of the entries, moving down one slot.  Copy includes
 	 trailing NULL.  */
-#if 0
-      for (i = 0; i < history_length; i++)
-	the_history[i] = the_history[i + 1];
-#else
       memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
-#endif
 
+      new_length = history_length;
       history_base++;
     }
   else
     {
       if (history_size == 0)
 	{
 	  if (history_stifled && history_max_entries > 0)
-	    history_size = history_max_entries + 2;
+	    history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
+				? MAX_HISTORY_INITIAL_SIZE
+				: history_max_entries + 2;
 	  else
 	    history_size = DEFAULT_HISTORY_INITIAL_SIZE;
 	  the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
-	  history_length = 1;
+	  new_length = 1;
 	}
       else
 	{
 	  if (history_length == (history_size - 1))
 	    {
 	      history_size += DEFAULT_HISTORY_GROW_SIZE;
 	      the_history = (HIST_ENTRY **)
 		xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
 	    }
-	  history_length++;
+	  new_length = history_length + 1;
 	}
     }
 
   temp = alloc_history_entry ((char *)string, hist_inittime ());
 
-  the_history[history_length] = (HIST_ENTRY *)NULL;
-  the_history[history_length - 1] = temp;
+  the_history[new_length] = (HIST_ENTRY *)NULL;
+  the_history[new_length - 1] = temp;
+  history_length = new_length;
 }
 
 /* Change the time stamp of the most recent history entry to STRING. */
 void
 add_history_time (string)
diff -aprNU5 readline-7.0.orig/input.c readline-7.0/input.c
--- readline-7.0.orig/input.c	2016-08-30 14:21:46 +0000
+++ readline-7.0/input.c	2017-07-16 10:05:50 +0000
@@ -511,10 +511,11 @@ rl_getc (stream)
 	return (_getch ());	/* "There is no error return." */
 #endif
       result = 0;
 #if defined (HAVE_PSELECT)
       sigemptyset (&empty_set);
+      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &empty_set);
       FD_ZERO (&readfds);
       FD_SET (fileno (stream), &readfds);
       result = pselect (fileno (stream) + 1, &readfds, NULL, NULL, NULL, &empty_set);
 #endif
       if (result >= 0)
diff -aprNU5 readline-7.0.orig/patchlevel readline-7.0/patchlevel
--- readline-7.0.orig/patchlevel	2015-10-02 11:25:02 +0000
+++ readline-7.0/patchlevel	2017-07-16 10:05:50 +0000
@@ -1,3 +1,3 @@
 # Do not edit -- exists only for use by patch
 
-0
+3




##############################################################################




2017-07-02  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* 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.

	* 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.

	* readline.c [__DJGPP__]:  Include sys/exceptn.h and provide prototype
	for __libc_termios_enable_function_and_arrow_keys.
	(readline_internal_charloop):  Define eof to -1.
	(readline_initialize_everything) [__DJGPP__]:  To bind tty characters
	to readline functions use __libc_termios_enable_function_and_arrow_keys.

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

	* 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.


2017-06-27  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.

	* colors.c (_rl_print_color_indicator):  Check if S_ISLNK and S_ISSOCK
	is available.

	* 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.

	* 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.

	* 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/histexamp.c (main):  Add int return type to main function.
	[HAVE_STDLIB_H]:  Include stdlib.h for free prototype.

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

	* examples/rlcat.c (main):  Pacify compiler.

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

	* examples/rltest.c:  Add int return type to main function.

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

	* histexpand.c (get_history_event):  Pacify compiler.

	* tilde.c (tilde_expand):  Pacify compiler.

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







diff -aprNU5 readline-7.0.orig/bind.c readline-7.0/bind.c
--- readline-7.0.orig/bind.c	2016-07-27 15:15:26 +0000
+++ readline-7.0/bind.c	2017-06-27 21:36:14 +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));
 
@@ -474,11 +488,11 @@ rl_translate_keyseq (seq, array, len)
      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];
 
@@ -918,10 +932,13 @@ rl_read_init_file (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));
 }
 
@@ -2364,11 +2381,11 @@ rl_function_dumper (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-7.0.orig/colors.c readline-7.0/colors.c
--- readline-7.0.orig/colors.c	2016-01-25 15:37:56 +0000
+++ readline-7.0/colors.c	2017-06-27 21:36:14 +0000
@@ -209,16 +209,20 @@ _rl_print_color_indicator (const char *f
 #if defined (S_ISVTX)
           else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
             colored_filetype = C_STICKY;
 #endif
         }
+#if defined (S_ISLNK)
       else if (S_ISLNK (mode))
         colored_filetype = C_LINK;
+#endif
       else if (S_ISFIFO (mode))
         colored_filetype = C_FIFO;
+#if defined (S_ISSOCK)
       else if (S_ISSOCK (mode))
         colored_filetype = C_SOCK;
+#endif
       else if (S_ISBLK (mode))
         colored_filetype = C_BLK;
       else if (S_ISCHR (mode))
         colored_filetype = C_CHR;
       else
diff -aprNU5 readline-7.0.orig/complete.c readline-7.0/complete.c
--- readline-7.0.orig/complete.c	2016-04-24 23:39:28 +0000
+++ readline-7.0/complete.c	2017-06-27 21:36:14 +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 *));
@@ -735,13 +741,13 @@ printable_part (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;
 }
 
@@ -1150,17 +1156,23 @@ _rl_find_completion_word (fp, dp)
   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;
@@ -1814,13 +1826,25 @@ make_quoted_replacement (match, mtype, q
   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)
@@ -2227,11 +2251,11 @@ rl_completion_matches (text, entry_funct
   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
@@ -2301,11 +2325,11 @@ rl_username_completion_function (text, s
       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;
     }
@@ -2505,14 +2529,20 @@ rl_filename_completion_function (text, s
 	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);
diff -aprNU5 readline-7.0.orig/display.c readline-7.0/display.c
--- readline-7.0.orig/display.c	2016-07-28 18:49:28 +0000
+++ readline-7.0/display.c	2017-06-27 21:57:02 +0000
@@ -1187,11 +1187,11 @@ rl_redisplay ()
 	      _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
@@ -1680,11 +1680,11 @@ update_line (old, new, current_line, oma
   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)
@@ -2252,15 +2252,15 @@ _rl_move_cursor_relative (new, data)
 #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
       cpos = _rl_last_c_pos = 0;
     }
 
   if (cpos < dpos)
     {
@@ -2281,18 +2281,22 @@ _rl_move_cursor_relative (new, data)
 	 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
@@ -2324,31 +2328,31 @@ _rl_move_vert (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
     }
 
   _rl_last_v_pos = to;		/* Now TO is here */
 }
 
@@ -2639,11 +2643,11 @@ _rl_erase_at_end_of_line (l)
    number of character spaces to clear, */
 void
 _rl_clear_to_eol (count)
      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)
@@ -2665,19 +2669,19 @@ space_to_eol (count)
 }
 
 void
 _rl_clear_screen ()
 {
-#ifndef __DJGPP__
+#if defined (HAVE_TERMCAP_API)
   if (_rl_term_clrpag)
     tputs (_rl_term_clrpag, 1, _rl_output_character_function);
   else
     rl_crlf ();
 #else
   ScreenClear ();
   ScreenSetCursor (0, 0);
-#endif /* __DJGPP__ */
+#endif
 }
 
 /* Insert COUNT characters from STRING to the output stream at column COL. */
 static void
 insert_some_chars (string, count, col)
@@ -2693,11 +2697,11 @@ insert_some_chars (string, count, col)
    by itself.  We assume there will either be ei or we don't need to use it. */
 static void
 open_some_spaces (col)
      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)
@@ -2722,22 +2726,22 @@ open_some_spaces (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 (count)
      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);
@@ -2746,11 +2750,11 @@ delete_chars (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 ()
 {
@@ -2787,11 +2791,11 @@ _rl_update_final ()
 static void
 cr ()
 {
   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;
@@ -2837,17 +2841,17 @@ _rl_redisplay_after_sigwinch ()
      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-7.0.orig/doc/hstech.texi readline-7.0/doc/hstech.texi
--- readline-7.0.orig/doc/hstech.texi	2016-01-25 15:10:06 +0000
+++ readline-7.0/doc/hstech.texi	2017-06-27 22:00:00 +0000
@@ -320,10 +320,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-7.0.orig/doc/rluser.texi readline-7.0/doc/rluser.texi
--- readline-7.0.orig/doc/rluser.texi	2016-02-28 21:55:10 +0000
+++ readline-7.0/doc/rluser.texi	2017-06-27 22:00: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-7.0.orig/examples/fileman.c readline-7.0/examples/fileman.c
--- readline-7.0.orig/examples/fileman.c	2015-08-06 14:55:34 +0000
+++ readline-7.0/examples/fileman.c	2017-06-27 22:04:56 +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;
 {
@@ -234,10 +199,35 @@ stripwhite (string)
   *++t = '\0';
 
   return s;
 }
 
+/* Function which tells you that you can't do this. */
+void
+too_dangerous (caller)
+     char *caller;
+{
+  fprintf (stderr,
+           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
+           caller);
+}
+
+/* Return non-zero if ARG is a valid argument for CALLER, else print
+   an error message and return zero. */
+int
+valid_argument (caller, arg)
+     char *caller, *arg;
+{
+  if (!arg || !*arg)
+    {
+      fprintf (stderr, "%s: Argument required.\n", caller);
+      return (0);
+    }
+
+  return (1);
+}
+
 /* **************************************************************** */
 /*                                                                  */
 /*                  Interface to Readline Completion                */
 /*                                                                  */
 /* **************************************************************** */
@@ -300,11 +290,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));
@@ -478,20 +468,10 @@ com_quit (arg)
 {
   done = 1;
   return (0);
 }
 
-/* Function which tells you that you can't do this. */
-void
-too_dangerous (caller)
-     char *caller;
-{
-  fprintf (stderr,
-           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
-           caller);
-}
-
 /* Return non-zero if ARG is a valid argument for CALLER, else print
    an error message and return zero. */
 int
 valid_argument (caller, arg)
      char *caller, *arg;
@@ -502,5 +482,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-7.0.orig/examples/histexamp.c readline-7.0/examples/histexamp.c
--- readline-7.0.orig/examples/histexamp.c	2009-01-04 19:32:28 +0000
+++ readline-7.0/examples/histexamp.c	2017-06-27 22:33:08 +0000
@@ -19,18 +19,25 @@
    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include <stdio.h>
 
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#else 
+extern void free ();
+#endif
+
 #ifdef READLINE_LIBRARY
 #  include "history.h"
 #else
 #  include <readline/history.h>
 #endif
 
 #include <string.h>
 
+int
 main (argc, argv)
      int argc;
      char **argv;
 {
   char line[1024], *t;
@@ -120,6 +127,7 @@ main (argc, argv)
 	    {
 	      fprintf (stderr, "non-numeric arg given to `delete'\n");
 	    }
 	}
     }
+  return 0;
 }
diff -aprNU5 readline-7.0.orig/examples/rl.c readline-7.0/examples/rl.c
--- readline-7.0.orig/examples/rl.c	2015-08-06 14:51:18 +0000
+++ readline-7.0/examples/rl.c	2017-06-27 22:34:44 +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-7.0.orig/examples/rlcat.c readline-7.0/examples/rlcat.c
--- readline-7.0.orig/examples/rlcat.c	2009-01-04 19:32:28 +0000
+++ readline-7.0/examples/rlcat.c	2017-06-27 22:36:06 +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);
     }
diff -aprNU5 readline-7.0.orig/examples/rlevent.c readline-7.0/examples/rlevent.c
--- readline-7.0.orig/examples/rlevent.c	2009-01-06 17:04:22 +0000
+++ readline-7.0/examples/rlevent.c	2017-06-27 22:36:36 +0000
@@ -35,20 +35,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();
@@ -92,11 +122,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-7.0.orig/examples/rltest.c readline-7.0/examples/rltest.c
--- readline-7.0.orig/examples/rltest.c	2009-01-04 19:32:28 +0000
+++ readline-7.0/examples/rltest.c	2017-06-27 22:37:28 +0000
@@ -44,10 +44,11 @@ extern void exit();
 #  include <readline/history.h>
 #endif
 
 extern HIST_ENTRY **history_list ();
 
+int
 main ()
 {
   char *temp, *prompt;
   int done;
 
diff -aprNU5 readline-7.0.orig/funmap.c readline-7.0/funmap.c
--- readline-7.0.orig/funmap.c	2016-02-27 22:14:14 +0000
+++ readline-7.0/funmap.c	2017-06-27 22:47:28 +0000
@@ -114,11 +114,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 },
   { "print-last-kbd-macro", rl_print_last_kbd_macro },
diff -aprNU5 readline-7.0.orig/histexpand.c readline-7.0/histexpand.c
--- readline-7.0.orig/histexpand.c	2016-08-11 11:55:48 +0000
+++ readline-7.0/histexpand.c	2017-06-27 22:46:42 +0000
@@ -207,11 +207,11 @@ get_history_event (string, caller_index,
       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-7.0.orig/histfile.c readline-7.0/histfile.c
--- readline-7.0.orig/histfile.c	2016-01-25 15:33:58 +0000
+++ readline-7.0/histfile.c	2017-07-02 11:44:44 +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 */
@@ -168,11 +182,14 @@ history_filename (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);
diff -aprNU5 readline-7.0.orig/input.c readline-7.0/input.c
--- readline-7.0.orig/input.c	2016-08-30 14:21:42 +0000
+++ readline-7.0/input.c	2017-07-02 11:42:20 +0000
@@ -450,11 +450,11 @@ rl_read_key ()
       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 (c);
 
       /* If the user has an event function, then call it periodically. */
       if (rl_event_hook)
 	{
diff -aprNU5 readline-7.0.orig/kill.c readline-7.0/kill.c
--- readline-7.0.orig/kill.c	2016-01-25 15:38:40 +0000
+++ readline-7.0/kill.c	2017-07-02 12:15:16 +0000
@@ -774,5 +774,78 @@ rl_paste_from_clipboard (count, key)
       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-7.0.orig/misc.c readline-7.0/misc.c
--- readline-7.0.orig/misc.c	2016-04-22 15:03:32 +0000
+++ readline-7.0/misc.c	2017-07-02 11:47:54 +0000
@@ -453,11 +453,11 @@ _rl_revert_all_lines ()
   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 */
diff -aprNU5 readline-7.0.orig/readline.c readline-7.0/readline.c
--- readline-7.0.orig/readline.c	2016-04-20 19:53:48 +0000
+++ readline-7.0/readline.c	2017-07-02 12:37:02 +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));
 
 /* **************************************************************** */
@@ -648,11 +655,11 @@ readline_internal_charloop ()
 
 #if defined (READLINE_CALLBACKS)
 static int
 readline_internal_charloop ()
 {
-  int eof = 1;
+  int eof = -1;
 
   while (rl_done == 0)
     eof = readline_internal_char ();
   return (eof);
 }
@@ -1197,10 +1204,13 @@ readline_initialize_everything ()
   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 ();
 
@@ -1251,10 +1261,11 @@ readline_default_bindings ()
 {
   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 ()
 {
@@ -1262,10 +1273,11 @@ reset_default_bindings ()
     {
       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 (map)
      Keymap map;
diff -aprNU5 readline-7.0.orig/readline.h readline-7.0/readline.h
--- readline-7.0.orig/readline.h	2016-07-17 20:17:10 +0000
+++ readline-7.0/readline.h	2017-07-02 12:20:18 +0000
@@ -171,12 +171,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-7.0.orig/signals.c readline-7.0/signals.c
--- readline-7.0.orig/signals.c	2016-08-26 12:28:46 +0000
+++ readline-7.0/signals.c	2017-07-02 12:47:08 +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;
+#ifdef SIGWINCH
 static int sigwinch_set_flag;
+#endif
 
 /* **************************************************************** */
 /*					        		    */
 /*			   Signal Handling                          */
 /*								    */
@@ -606,20 +608,26 @@ rl_pending_signal ()
 /*								    */
 /* **************************************************************** */
 
 #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 ()
@@ -639,10 +647,11 @@ _rl_release_sigint ()
 
   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 ()
 {
@@ -694,10 +703,11 @@ _rl_release_sigwinch ()
 
 #endif /* SIGWINCH */
 
   sigwinch_blocked = 0;
 }
+#endif /* !SIGWINCH */
 
 /* **************************************************************** */
 /*								    */
 /*		Echoing special control characters		    */
 /*								    */
diff -aprNU5 readline-7.0.orig/tcap.h readline-7.0/tcap.h
--- readline-7.0.orig/tcap.h	2016-01-25 15:36:10 +0000
+++ readline-7.0/tcap.h	2017-07-02 15:21:18 +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-7.0.orig/terminal.c readline-7.0/terminal.c
--- readline-7.0.orig/terminal.c	2016-01-25 15:36:16 +0000
+++ readline-7.0/terminal.c	2017-07-02 15:41:56 +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 (swp, 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
@@ -245,10 +264,14 @@ _rl_get_screen_size (tty, ignore_env)
     }
 #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)
@@ -268,11 +291,11 @@ _rl_get_screen_size (tty, ignore_env)
 	_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");
@@ -287,11 +310,11 @@ _rl_get_screen_size (tty, ignore_env)
 	_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");
@@ -425,11 +448,12 @@ static const struct _tc_string tc_string
    are described in the TC_STRINGS table. */
 static void
 get_term_capabilities (bp)
      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
@@ -464,11 +488,17 @@ _rl_init_terminal_io (terminal_name)
   _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())
@@ -607,19 +637,21 @@ bind_termcap_arrow_keys (map)
 
 char *
 rl_get_termcap (cap)
      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. */
@@ -729,11 +761,11 @@ rl_ding ()
 static int enabled_meta = 0;	/* flag indicating we enabled meta mode */
 
 void
 _rl_enable_meta_key ()
 {
-#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;
     }
@@ -741,11 +773,11 @@ _rl_enable_meta_key ()
 }
 
 void
 _rl_disable_meta_key ()
 {
-#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;
     }
@@ -754,11 +786,11 @@ _rl_disable_meta_key ()
 
 void
 _rl_control_keypad (on)
      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-7.0.orig/tilde.c readline-7.0/tilde.c
--- readline-7.0.orig/tilde.c	2016-04-28 12:17:46 +0000
+++ readline-7.0/tilde.c	2017-06-27 22:22:00 +0000
@@ -194,11 +194,11 @@ tilde_expand (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. */
diff -aprNU5 readline-7.0.orig/tminit.c readline-7.0/tminit.c
--- readline-7.0.orig/tminit.c	1970-01-01 00:00:00 +0000
+++ readline-7.0/tminit.c	2017-06-27 22:21:18 +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__ */




bug-readline@gnu.org:  Bug in complete.c if HANDLE_MULTIBYTE is undefined.


I have tried to build readline-7.0 for MSDOS/FreeDOS using DJGPP.  The only
important issue here is that the used system does not provide multi-byte
support at all thus NO_MULTIBYTE_SUPPORT is defined to 1 and HANDLE_MULTIBYTE
is undefined.  This triggers at least one bug.

In function fnprint of file complete.c the variable print_len is initialized
with the return value of strlen, but that happens only iff HANDLE_MULTIBYTE
is defined.  Else this variable is never initialized but later used in line 834:

  if (_rl_completion_prefix_display_length > 0 && prefix_bytes >= print_len)
    prefix_bytes = 0;

Either this "if" clause must also be guarded by #if defined (HANDLE_MULTIBYTE)
or the variable must be initialized as shown in the patch.  There are also
some superfluous variables and some other variables that are only used if
HANDLE_MULTIBYTE is defined.  They are used inside of "if" clauses of loops
and could be defined there instead at the beginning of the function so that
the compiler does not warn if compiling with the pedantic and -Wall flag.
But that is of course only a design question.  It is purely a matter of taste.
I send you a small patch made against main branch of the readline repository
in the hope that it may be helpfull.


Regards,
Juan M. Guerrero




	* bind.c (rl_parse_and_bind): unused variable `s' fixed.

	* complete.c (fnprint): 'print_len' might be used uninitialized in this
	function fixed.
	(rl_menu_complete): unused variable `cstate' fixed.

	* display.c (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.

	* readline.c (readline_internal_char): unused variable `eof_found'
	fixed.

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







diff -aprNU5 readline-7.0.orig/bind.c readline-7.0/bind.c
--- readline-7.0.orig/bind.c	2017-07-02 19:36:32 +0000
+++ readline-7.0/bind.c	2017-07-03 21:26:30 +0000
@@ -1359,11 +1359,10 @@ rl_parse_and_bind (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++;
 
diff -aprNU5 readline-7.0.orig/complete.c readline-7.0/complete.c
--- readline-7.0.orig/complete.c	2017-07-02 19:36:32 +0000
+++ readline-7.0/complete.c	2017-07-02 20:09:56 +0000
@@ -811,19 +811,18 @@ fnprint (to_print, prefix_bytes, real_pa
      int prefix_bytes;
      const char *real_pathname;
 {
   int printed_len, w;
   const char *s;
-  int common_prefix_len, print_len;
+  int common_prefix_len, print_len = strlen (to_print);
 #if defined (HANDLE_MULTIBYTE)
   mbstate_t ps;
   const char *end;
   size_t tlen;
   int width;
   wchar_t wc;
 
-  print_len = strlen (to_print);
   end = to_print + print_len + 1;
   memset (&ps, 0, sizeof (mbstate_t));
 #endif
 
   printed_len = common_prefix_len = 0;
@@ -2867,11 +2866,11 @@ rl_menu_complete (count, 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-7.0.orig/display.c readline-7.0/display.c
--- readline-7.0.orig/display.c	2017-07-02 19:36:32 +0000
+++ readline-7.0/display.c	2017-07-03 22:10:26 +0000
@@ -309,12 +309,15 @@ expand_prompt (pmt, flags, lp, lip, nifl
      char *pmt;
      int flags;
      int *lp, *lip, *niflp, *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;
+#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)
@@ -580,14 +583,15 @@ void
 rl_redisplay ()
 {
   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;
@@ -760,11 +764,10 @@ rl_redisplay ()
 
   /* what if lpos is already >= _rl_screenwidth before we start drawing the
      contents of the command line? */
   while (lpos >= _rl_screenwidth)
     {
-      int z, p;
       int nocorrect, wadjust;
 
       nocorrect = 0;
       /* Adjust depending on the invisible characters in the line.  We use a
 	 heuristic based on experience: invisible characters nearly always
@@ -788,11 +791,11 @@ rl_redisplay ()
           temp = local_prompt_len;
           while (num < temp)
 	    {
 	      /* This has to take invisible characters in the prompt into
 		 account. */
-	      z = _rl_col_width  (local_prompt, n0, num, 1) - wadjust;
+	      int z = _rl_col_width  (local_prompt, n0, num, 1) - wadjust;
 	      if (z > _rl_screenwidth)
 		{
 	          num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
 	          break;
 		}
@@ -800,11 +803,11 @@ rl_redisplay ()
 		{
 		  /* If we are in the middle or at the end of a multibyte
 		     character, we want to move to the start, then find out
 		     where it ends so we know where to insert the newline.
 		     If this isn't a multibyte character, its the same as num++ */
-		  p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
+		  int p = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
 		  num = _rl_find_next_mbchar (local_prompt, p, 1, MB_FIND_ANY);
 		  break;
 		}
 	      num++;
 	    }
@@ -2160,12 +2163,10 @@ _rl_move_cursor_relative (new, data)
      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;
 
@@ -2178,10 +2179,12 @@ _rl_move_cursor_relative (new, data)
      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)
diff -aprNU5 readline-7.0.orig/readline.c readline-7.0/readline.c
--- readline-7.0.orig/readline.c	2017-07-02 19:36:34 +0000
+++ readline-7.0/readline.c	2017-07-02 19:45:48 +0000
@@ -534,11 +534,14 @@ STATIC_CALLBACK int
 readline_internal_char ()
 #else
 readline_internal_charloop ()
 #endif
 {
-  static int lastc, eof_found;
+#if !defined (READLINE_CALLBACKS)
+  static int eof_found;
+#endif
+  static int lastc;
   int c, code, lk;
 
   lastc = EOF;
 
 #if !defined (READLINE_CALLBACKS)
diff -aprNU5 readline-7.0.orig/vi_mode.c readline-7.0/vi_mode.c
--- readline-7.0.orig/vi_mode.c	2016-02-28 19:36:10 +0000
+++ readline-7.0/vi_mode.c	2017-07-02 19:50:00 +0000
@@ -1291,11 +1291,10 @@ _rl_vi_domove_callback (m)
 /* This code path taken when not in callback mode. */
 int
 rl_vi_domove (x, ignore)
      int x, *ignore;
 {
-  int r;
   _rl_vimotion_cxt *m;
 
   m = _rl_vimvcxt;
   *ignore = m->motion = rl_vi_domove_getchar (m);
 




2017-07-05  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* bind.c (_rl_skip_to_delim):  Pacify compiler.

	* complete.c (rl_filename_completion_function):  'dentry' and 'convfn'
	might be used uninitialized fixed.

	* display.c (update_line):  Unused variable `twidth' fixed.







diff -aprNU5 readline-7.0.orig/bind.c readline-7.0/bind.c
--- readline-7.0.orig/bind.c	2017-07-05 20:07:52 +0000
+++ readline-7.0/bind.c	2017-07-05 21:35:58 +0000
@@ -1270,11 +1270,11 @@ _rl_skip_to_delim (string, start, delim)
      char *string;
      int start, 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)
diff -aprNU5 readline-7.0.orig/complete.c readline-7.0/complete.c
--- readline-7.0.orig/complete.c	2017-07-05 20:07:52 +0000
+++ readline-7.0/complete.c	2017-07-05 20:39:06 +0000
@@ -2502,11 +2502,11 @@ rl_filename_completion_function (text, s
   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. */
diff -aprNU5 readline-7.0.orig/display.c readline-7.0/display.c
--- readline-7.0.orig/display.c	2017-07-07 22:05:48 +0000
+++ readline-7.0/display.c	2017-07-05 21:17:24 +0000
@@ -1388,11 +1388,11 @@ static void
 update_line (old, new, current_line, omax, nmax, inv_botlin)
      register char *old, *new;
      int current_line, omax, nmax, 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)




bug-readline@gnu.org:  Bug in signls.c if SIGTSTP and friends are not defined.


I am still trying to port readline to FreeDOS using DJGPP and I have found the
following signal issue.  The used system does not provide SIGTSTP and similars.
Thus it does not compile.  The interesting issue is that in function _rl_handle_signal
it is explicitly checked that SIGTSTP is defined, see line 224:


[snipped start]
#if defined (SIGTSTP)
    case SIGTSTP:
    case SIGTTIN:
#  if defined (HAVE_POSIX_SIGNALS)
      /* Block SIGTTOU so we can restore the terminal settings to something
	 sane without stopping on SIGTTOU if we have been placed into the
	 background.  Even trying to get the current terminal pgrp with
	 tcgetpgrp() will generate SIGTTOU, so we don't bother.  Don't bother
	 doing this if we've been stopped on SIGTTOU; it's aready too late. */
      sigemptyset (&set);
      sigaddset (&set, SIGTTOU);
      sigprocmask (SIG_BLOCK, &set, (sigset_t *)NULL);
#  endif
    case SIGTTOU:
#endif /* SIGTSTP */
[snipped end]


but later at line 255 no precaution is taken:


[snipped start]
#if defined (SIGQUIT)
    case SIGQUIT:
#endif
      rl_echo_signal_char (sig);
      rl_cleanup_after_signal ();

#if defined (HAVE_POSIX_SIGNALS)
      /* Unblock SIGTTOU blocked above */
      if (sig == SIGTTIN || sig == SIGTSTP)  <-- offending line!
	sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL);

      sigemptyset (&set);
      sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
      sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
#  if defined (HAVE_BSD_SIGNALS)
      omask = sigblock (0);
#  endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
[snipped end]



It is not enough to check for HAVE_POSIX_SIGNALS.  It must also be checked
for SIGTSTP and friends as it has been done the lines before.  I have fixed
it as shown in the patch but I am not sure if it is the right form to do it.
After that fix I was able to compile to compile the readline and history
libraries with DJGPP.  Now I am checking how well the sample code performs.
Patch is against readline repository.  Hope that the hint is usefull.


Kind regards,
Juan M. Guerrero



2017-07-08  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* signals.c (_rl_handle_signal):  Check that SIGTSTP is defined.







diff -aprNU5 readline-7.0.orig/signals.c readline-7.0/signals.c
--- readline-7.0.orig/signals.c	2017-11-18 18:06:22 +0000
+++ readline-7.0/signals.c	2017-11-18 18:16:34 +0000
@@ -248,13 +248,15 @@ _rl_handle_signal (sig)
 #endif
       rl_echo_signal_char (sig);
       rl_cleanup_after_signal ();
 
 #if defined (HAVE_POSIX_SIGNALS)
+#  if defined (SIGTSTP)
       /* Unblock SIGTTOU blocked above */
       if (sig == SIGTTIN || sig == SIGTSTP)
 	sigprocmask (SIG_UNBLOCK, &set, (sigset_t *)NULL);
+#  endif
 
       sigemptyset (&set);
       sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
       sigdelset (&set, sig);
 #else /* !HAVE_POSIX_SIGNALS */




2017-07-08  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* histfile.c (history_backupfile, history_tempfile):  Unused variable
	`fs' fixed.

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

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







diff -aprNU5 readline-7.0.orig/histfile.c readline-7.0/histfile.c
--- readline-7.0.orig/histfile.c	2017-11-18 18:06:20 +0000
+++ readline-7.0/histfile.c	2017-11-18 18:21:04 +0000
@@ -201,11 +201,10 @@ history_backupfile (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 */
@@ -221,20 +220,19 @@ history_backupfile (filename)
   strcpy (ret, fn);
   ret[len] = '-';
   ret[len+1] = '\0';
   return ret;
 }
-  
+
 static char *
 history_tempfile (filename)
      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-7.0.orig/history.c readline-7.0/history.c
--- readline-7.0.orig/history.c	2017-11-18 18:05:34 +0000
+++ readline-7.0/history.c	2017-11-18 18:21:04 +0000
@@ -281,11 +281,13 @@ add_history (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;
diff -aprNU5 readline-7.0.orig/misc.c readline-7.0/misc.c
--- readline-7.0.orig/misc.c	2017-11-18 18:06:22 +0000
+++ readline-7.0/misc.c	2017-11-18 18:21:04 +0000
@@ -500,11 +500,11 @@ rl_clear_history ()
   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;




2017-07-09  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* examples/fileman.c:  Double implementations removed.

	* 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/hist_purgecmd.c:  Implicit declaration of function 'hist_purgecmd'
	fixed.

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







diff -aprNU5 readline-7.0.orig/examples/fileman.c readline-7.0/examples/fileman.c
--- readline-7.0.orig/examples/fileman.c	2017-07-09 14:11:00 +0000
+++ readline-7.0/examples/fileman.c	2017-07-09 14:16:36 +0000
@@ -199,35 +199,10 @@ stripwhite (string)
   *++t = '\0';
 
   return s;
 }
 
-/* Function which tells you that you can't do this. */
-void
-too_dangerous (caller)
-     char *caller;
-{
-  fprintf (stderr,
-           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
-           caller);
-}
-
-/* Return non-zero if ARG is a valid argument for CALLER, else print
-   an error message and return zero. */
-int
-valid_argument (caller, arg)
-     char *caller, *arg;
-{
-  if (!arg || !*arg)
-    {
-      fprintf (stderr, "%s: Argument required.\n", caller);
-      return (0);
-    }
-
-  return (1);
-}
-
 /* **************************************************************** */
 /*                                                                  */
 /*                  Interface to Readline Completion                */
 /*                                                                  */
 /* **************************************************************** */
@@ -468,10 +443,20 @@ com_quit (arg)
 {
   done = 1;
   return (0);
 }
 
+/* Function which tells you that you can't do this. */
+void
+too_dangerous (caller)
+     char *caller;
+{
+  fprintf (stderr,
+           "%s: Too dangerous for me to distribute.  Write it yourself.\n",
+           caller);
+}
+
 /* Return non-zero if ARG is a valid argument for CALLER, else print
    an error message and return zero. */
 int
 valid_argument (caller, arg)
      char *caller, *arg;
diff -aprNU5 readline-7.0.orig/examples/hist_erasedups.c readline-7.0/examples/hist_erasedups.c
--- readline-7.0.orig/examples/hist_erasedups.c	2016-04-22 15:04:42 +0000
+++ readline-7.0/examples/hist_erasedups.c	2017-07-09 15:07:34 +0000
@@ -36,10 +36,12 @@
 
 #define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
 #define STREQN(a, b, n) ((n == 0) ? (1) \
                                   : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
 
+int hist_erasedups(void);
+
 static void
 usage()
 {
   fprintf (stderr, "hist_erasedups: usage: hist_erasedups [-t] [filename]\n");
   exit (2);
@@ -92,15 +94,15 @@ main (argc, argv)
 }
 
 int
 hist_erasedups ()
 {
-  int r, n;
+  int r = 0, n;
   HIST_ENTRY *h, *temp;
 
   using_history ();
-  while (h = previous_history ())
+  while ((h = previous_history ()))
     {
       r = where_history ();
       for (n = 0; n < r; n++)
 	{
 	  temp = history_get (n+history_base);
diff -aprNU5 readline-7.0.orig/examples/hist_purgecmd.c readline-7.0/examples/hist_purgecmd.c
--- readline-7.0.orig/examples/hist_purgecmd.c	2016-04-22 15:04:18 +0000
+++ readline-7.0/examples/hist_purgecmd.c	2017-07-09 14:48:14 +0000
@@ -41,10 +41,12 @@
 #define STREQN(a, b, n) ((n == 0) ? (1) \
                                   : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
 
 #define PURGE_REGEXP	0x01
 
+int hist_purgecmd(char *cmd, int flags);
+
 static void
 usage()
 {
   fprintf (stderr, "hist_purgecmd: usage: hist_purgecmd [-r] [-t] [-f filename] command-spec\n");
   exit (2);
diff -aprNU5 readline-7.0.orig/examples/rlcat.c readline-7.0/examples/rlcat.c
--- readline-7.0.orig/examples/rlcat.c	2017-07-09 14:11:00 +0000
+++ readline-7.0/examples/rlcat.c	2017-07-09 14:32:56 +0000
@@ -175,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));
 




2018-01-13  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* readline/tilde.c (tilde_expand): $HOME expansion fixed.









diff -aprNU5 readline-7.0//tilde.c readline-7.0//tilde.c
--- readline-7.0//tilde.c	2018-01-13 23:55:40 +0000
+++ readline-7.0//tilde.c	2018-01-13 23:57:20 +0000
@@ -241,11 +241,11 @@ tilde_expand (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
 	{
