The mmap in history_do_write would usually fail when appending because the offset must be a multiple of the page size. --- lib/readline/histfile.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c index a5fb11d2..d5568152 100644 --- a/lib/readline/histfile.c +++ b/lib/readline/histfile.c @@ -742,7 +742,7 @@ history_do_write (const char *filename, int nelements, int overwrite) int file, mode, rv, exists; struct stat finfo; #ifdef HISTORY_USE_MMAP - size_t cursize; + size_t cursize, pa_size; history_lines_written_to_file = 0; @@ -798,7 +798,10 @@ history_do_write (const char *filename, int nelements, int overwrite) #ifdef HISTORY_USE_MMAP if (ftruncate (file, buffer_size+cursize) == -1) goto mmap_error; - buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize); + + /* offset for mmap() must be page aligned */ + pa_size = cursize & ~(getpagesize() - 1); + buffer = (char *)mmap (0, buffer_size + cursize - pa_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, pa_size); if ((void *)buffer == MAP_FAILED) { mmap_error: @@ -812,6 +815,7 @@ mmap_error: FREE (tempname); return rv; } + j = cursize - pa_size; #else buffer = (char *)malloc (buffer_size); if (buffer == 0) @@ -826,9 +830,10 @@ mmap_error: FREE (tempname); return rv; } + j = 0; #endif - for (j = 0, i = history_length - nelements; i < history_length; i++) + for (i = history_length - nelements; i < history_length; i++) { if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0]) { @@ -842,7 +847,9 @@ mmap_error: } #ifdef HISTORY_USE_MMAP - if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0) + if (msync (buffer, buffer_size + cursize - pa_size, MS_ASYNC) != 0) + rv = errno; + if (munmap (buffer, buffer_size + cursize - pa_size) != 0 && rv == 0) rv = errno; #else if (write (file, buffer, buffer_size) < 0) -- 2.47.0