diff --git a/bashline.c b/bashline.c
index 8f69bc6..6d285c5 100644
--- a/bashline.c
+++ b/bashline.c
@@ -822,7 +822,11 @@ snarf_hosts_from_file (filename)
   char *temp, buffer[256], name[256];
   register int i, start;
 
-  file = fopen (filename, "r");
+#ifdef __MSYS__
+  file = fopen (filename, "rt");
+#else
+   file = fopen (filename, "r");
+#endif
   if (file == 0)
     return;
 
diff --git a/builtins/fc.def b/builtins/fc.def
index 9b8a997..5be93bd 100644
--- a/builtins/fc.def
+++ b/builtins/fc.def
@@ -681,6 +681,10 @@ fc_readline (stream)
      FILE *stream;
 {
   register int c;
+#ifdef __MSYS__
+  register int d;
+#endif
+
   int line_len = 0, lindex = 0;
   char *line = (char *)NULL;
 
@@ -691,12 +695,19 @@ fc_readline (stream)
 
       if (c == '\n')
 	{
+#ifdef __MSYS__
+	  if (d == '\r')
+	    lindex--;
+#endif
 	  line[lindex++] = '\n';
 	  line[lindex++] = '\0';
 	  return (line);
 	}
       else
 	line[lindex++] = c;
+#ifdef __MSYS__
+      d = c;
+#endif
     }
 
   if (!lindex)
diff --git a/general.c b/general.c
index f4c2a2f..0ae74ca 100644
--- a/general.c
+++ b/general.c
@@ -818,7 +818,8 @@ int
 absolute_program (string)
      const char *string;
 {
-  return ((char *)mbschr (string, '/') != (char *)NULL);
+  return ((char *)mbschr (string, '/') != (char *)NULL ||
+          (char *)mbschr (string, '\\') != (char *)NULL);
 }
 
 /* **************************************************************** */
diff --git a/lib/readline/display.c b/lib/readline/display.c
index c1135ec..b388af6 100644
--- a/lib/readline/display.c
+++ b/lib/readline/display.c
@@ -529,7 +529,10 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
   if (lp)
     *lp = rl;
   if (lip)
-    *lip = last;
+    /* Hack: faking that the last character is invisible seems to work around
+       prompt display bugs.  I wish I knew what the real bug was...  */
+    *lip = r - ret;
+/*     *lip = last; */
   if (niflp)
     *niflp = invfl;
   if  (vlp)
diff --git a/parse.y b/parse.y
index 0ae3458..c6e9520 100644
--- a/parse.y
+++ b/parse.y
@@ -1459,7 +1459,13 @@ yy_input_name ()
 static int
 yy_getc ()
 {
-  return (*(bash_input.getter)) ();
+#ifdef __MSYS__
+  int c;
+  while ((c = (*(bash_input.getter)) ()) == '\r');
+  return c;
+#else
+   return (*(bash_input.getter)) ();
+#endif
 }
 
 /* Call this to unget C.  That is, to make C the next character
diff --git a/shell.c b/shell.c
index ee9d445..8f25726 100644
--- a/shell.c
+++ b/shell.c
@@ -1696,7 +1696,11 @@ open_shell_script (script_name)
   default_buffered_input = fd;
   SET_CLOSE_ON_EXEC (default_buffered_input);
 #else /* !BUFFERED_INPUT */
-  default_input = fdopen (fd, "r");
+#ifdef __MSYS__
+  default_input = fdopen (fd, "rt");
+#else
+   default_input = fdopen (fd, "r");
+#endif
 
   if (default_input == 0)
     {
diff --git a/stringlib.c b/stringlib.c
index 7330496..8623fa6 100644
--- a/stringlib.c
+++ b/stringlib.c
@@ -278,7 +278,15 @@ strip_trailing (string, len, newlines_only)
     {
       if ((newlines_only && string[len] == '\n') ||
 	  (!newlines_only && whitespace (string[len])))
+      {
 	len--;
+#ifdef __MSYS__
+	if (newlines_only && string[len + 1] == '\n' && string[len] == '\r')
+	{
+	  len--;
+	}
+#endif
+      }
       else
 	break;
     }
diff --git a/subst.c b/subst.c
index 2001b4e..3ba2029 100644
--- a/subst.c
+++ b/subst.c
@@ -6895,6 +6895,15 @@ read_comsub (fd, quoted, flags, rflag)
 	      /* If the newline was quoted, remove the quoting char. */
 	      if (istring[istring_index - 1] == CTLESC)
 		--istring_index;
+
+	      if (istring_index > 0 && istring[istring_index - 1] == '\r')
+	      {
+		--istring_index;
+
+	        /* If the caret return was quoted, remove the quoting char. */
+	        if (istring[istring_index - 1] == CTLESC)
+		  --istring_index;
+	      }
 	    }
 	  else
 	    break;
diff --git a/variables.c b/variables.c
index 028667c..a10594d 100644
--- a/variables.c
+++ b/variables.c
@@ -2593,6 +2593,20 @@ set_if_not (name, value)
 {
   SHELL_VAR *v;
 
+#if defined (__MSYS__)
+  /* Remove trailing \r from value */
+  {
+    char *tpos;
+    if (value && *value)
+    {
+      tpos = strchr (value, '\0');
+      tpos--;
+      if (*tpos == '\r')
+	*tpos = '\0';
+    }
+  }
+#endif
+
   if (shell_variables == 0)
     create_variable_tables ();
 
diff --git a/y.tab.c b/y.tab.c
index 32b4c7c..ac70820 100644
--- a/y.tab.c
+++ b/y.tab.c
@@ -3770,7 +3770,13 @@ yy_input_name ()
 static int
 yy_getc ()
 {
-  return (*(bash_input.getter)) ();
+#ifdef __MSYS__
+  int c;
+  while ((c = (*(bash_input.getter)) ()) == '\r');
+  return c;
+#else
+   return (*(bash_input.getter)) ();
+#endif
 }
 
 /* Call this to unget C.  That is, to make C the next character
@@ -4746,6 +4752,10 @@ shell_getc (remove_quoted_newline)
 	  else
 	    RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
 
+#ifdef __MSYS__
+	  if (c == '\r')
+	    continue;
+#endif
 	  if (c == EOF)
 	    {
 	      if (bash_input.type == st_stream)
