--- bash-4.2.orig/bashhist.c	2010-08-13 18:09:08.000000000 -0700
+++ bash-4.2/bashhist.c	2011-10-31 16:57:31.855274000 -0700
@@ -29,6 +29,8 @@
 #  include <unistd.h>
 #endif
 
+#include <sys/mman.h>
+
 #include "bashtypes.h"
 #include <stdio.h>
 #include <errno.h>
@@ -281,9 +283,6 @@ load_history ()
   set_if_not ("HISTSIZE", "500");
   sv_histsize ("HISTSIZE");
 
-  set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
-  sv_histsize ("HISTFILESIZE");
-
   /* Read the history in HISTFILE into the history list. */
   hf = get_string_value ("HISTFILE");
 
@@ -345,6 +344,69 @@ bash_delete_last_history ()
   return r;
 }
 
+int
+erasedups_history (nelements, filename)
+     int nelements;
+     const char *filename;
+{
+  HIST_ENTRY *temp;
+  int r, fd, rv = 0;
+  size_t cursize, mmap_size;
+  char *buffer, *line, *lineend;
+
+  fd = open (filename, O_RDWR);
+
+  if (fd < 0)
+    return errno;
+
+  cursize = lseek (fd, 0, SEEK_END);
+
+  using_history ();
+
+  mmap_size = cursize +1;	/* for possibly not newline ending */
+  buffer = mmap (0, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+  if ((void *)buffer == MAP_FAILED)
+    {
+      rv = errno;
+      close (fd);
+      return rv;
+    }
+
+  line = buffer;
+  while (line < buffer+cursize) {
+    lineend = strchr (line, '\n');
+
+    if (!lineend) {	/* last line not newline ending? */
+      lineend = line + strlen(line);
+      *lineend = '\n';
+      buffer[++cursize] = '\0';
+    }
+
+    for (r = 0; (temp = previous_history ()) && r < nelements; r++)
+      if (STREQN (line, temp->line, strlen (temp->line))) {
+	memmove (line, lineend+1, (buffer+cursize) - (lineend+1));
+	cursize -= (lineend+1 - line);
+	buffer[cursize] = '\0';
+	lineend = NULL;
+	break;
+      }
+    using_history ();
+
+    if (lineend)
+      line = lineend+1;
+  }
+
+  if (ftruncate (fd, cursize) == -1)
+    rv = errno;
+  if (!rv && msync (buffer, cursize, 0) == -1)
+    rv = errno;
+  if (!rv && munmap (buffer, mmap_size) == -1)
+    rv = errno;
+  close (fd);
+
+  return rv;
+}
+
 #ifdef INCLUDE_UNUSED
 /* Write the existing history out to the history file. */
 void
@@ -389,6 +451,8 @@ maybe_append_history (filename)
 	    }
 	  close (fd);
 	}
+      if (history_control & HC_ERASEDUPS)
+	erasedups_history (history_lines_this_session, filename);
       result = append_history (history_lines_this_session, filename);
       history_lines_in_file += history_lines_this_session;
       history_lines_this_session = 0;
@@ -426,6 +490,8 @@ maybe_save_shell_history ()
 	  using_history ();
 	  if (history_lines_this_session <= where_history () || force_append_history)
 	    {
+	      if (history_control & HC_ERASEDUPS)
+		erasedups_history (history_lines_this_session, hf);
 	      result = append_history (history_lines_this_session, hf);
 	      history_lines_in_file += history_lines_this_session;
 	    }
