mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-02 01:40:49 +02:00
fixes for glibc time/gettimeofday issue; fix issue with history file containing one line too few if saving timestamps; fix for signal arriving while displaying readline completions
This commit is contained in:
@@ -1630,7 +1630,7 @@ rl_display_match_list (char **matches, int len, int max)
|
||||
if (_rl_page_completions && lines >= (_rl_screenheight - 1) && i < count)
|
||||
{
|
||||
lines = _rl_internal_pager (lines);
|
||||
if (lines < 0)
|
||||
if (lines < 0 || _rl_complete_display_matches_interrupt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1658,7 +1658,7 @@ rl_display_match_list (char **matches, int len, int max)
|
||||
if (_rl_page_completions && lines >= _rl_screenheight - 1)
|
||||
{
|
||||
lines = _rl_internal_pager (lines);
|
||||
if (lines < 0)
|
||||
if (lines < 0 || _rl_complete_display_matches_interrupt)
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1745,7 +1745,9 @@ display_matches (char **matches)
|
||||
}
|
||||
}
|
||||
|
||||
rl_display_match_list (matches, len, max);
|
||||
/* We rely on the caller to set MATCHES to 0 when this returns. */
|
||||
if (_rl_complete_display_matches_interrupt == 0)
|
||||
rl_display_match_list (matches, len, max);
|
||||
|
||||
rl_forced_update_display ();
|
||||
rl_display_fixed = 1;
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char line[1024], *t;
|
||||
int len, done;
|
||||
@@ -91,6 +89,7 @@ main (argc, argv)
|
||||
register HIST_ENTRY **the_list;
|
||||
register int i;
|
||||
time_t tt;
|
||||
struct tm *tm;
|
||||
char timestr[128];
|
||||
|
||||
the_list = history_list ();
|
||||
@@ -98,8 +97,9 @@ main (argc, argv)
|
||||
for (i = 0; the_list[i]; i++)
|
||||
{
|
||||
tt = history_get_time (the_list[i]);
|
||||
if (tt)
|
||||
strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt));
|
||||
tm = tt ? localtime (&tt) : 0;
|
||||
if (tm)
|
||||
strftime (timestr, sizeof (timestr), "%a %R", tm);
|
||||
else
|
||||
strcpy (timestr, "??");
|
||||
printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line);
|
||||
|
||||
+36
-12
@@ -1,6 +1,6 @@
|
||||
/* histfile.c - functions to manipulate the history file. */
|
||||
|
||||
/* Copyright (C) 1989-2019 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2019,2023 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (History), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
@@ -578,6 +578,15 @@ history_truncate_file (const char *fname, int lines)
|
||||
goto truncate_exit;
|
||||
}
|
||||
|
||||
/* Don't bother with any of this if we're truncating to zero length. */
|
||||
if (lines == 0)
|
||||
{
|
||||
close (file);
|
||||
buffer[chars_read = 0] = '\0';
|
||||
bp = buffer;
|
||||
goto truncate_write;
|
||||
}
|
||||
|
||||
chars_read = read (file, buffer, file_size);
|
||||
close (file);
|
||||
|
||||
@@ -586,30 +595,38 @@ history_truncate_file (const char *fname, int lines)
|
||||
rv = (chars_read < 0) ? errno : 0;
|
||||
goto truncate_exit;
|
||||
}
|
||||
buffer[chars_read] = '\0'; /* for the initial check of bp1[1] */
|
||||
|
||||
/* Count backwards from the end of buffer until we have passed
|
||||
LINES lines. bp1 is set funny initially. But since bp[1] can't
|
||||
be a comment character (since it's off the end) and *bp can't be
|
||||
both a newline and the history comment character, it should be OK. */
|
||||
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
|
||||
both a newline and the history comment character, it should be OK.
|
||||
If we are writing history timestamps, we need to add one to LINES
|
||||
because we decrement it one extra time the first time through the loop
|
||||
and we need the final timestamp line. */
|
||||
lines += history_write_timestamps;
|
||||
for (bp1 = bp = buffer + chars_read - 1; lines > 0 && bp > buffer; bp--)
|
||||
{
|
||||
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
|
||||
lines--;
|
||||
bp1 = bp;
|
||||
}
|
||||
|
||||
/* If this is the first line, then the file contains exactly the
|
||||
/* This is the right line, so move to its start. If we're writing history
|
||||
timestamps, we want to go back until *bp == '\n' and bp1 starts a
|
||||
history timestamp. If we're not, just move back to *bp == '\n'.
|
||||
If this is the first line, then the file contains exactly the
|
||||
number of lines we want to truncate to, so we don't need to do
|
||||
anything. It's the first line if we don't find a newline between
|
||||
the current value of i and 0. Otherwise, write from the start of
|
||||
this line until the end of the buffer. */
|
||||
anything, and we'll end up with bp == buffer.
|
||||
Otherwise, write from the start of this line until the end of the
|
||||
buffer. */
|
||||
for ( ; bp > buffer; bp--)
|
||||
{
|
||||
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
|
||||
{
|
||||
if (*bp == '\n' && (history_write_timestamps == 0 || HIST_TIMESTAMP_START(bp1)))
|
||||
{
|
||||
bp++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bp1 = bp;
|
||||
}
|
||||
|
||||
@@ -623,15 +640,22 @@ history_truncate_file (const char *fname, int lines)
|
||||
goto truncate_exit;
|
||||
}
|
||||
|
||||
truncate_write:
|
||||
tempname = history_tempfile (filename);
|
||||
|
||||
if ((file = open (tempname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1)
|
||||
{
|
||||
if (write (file, bp, chars_read - (bp - buffer)) < 0)
|
||||
rv = errno;
|
||||
{
|
||||
rv = errno;
|
||||
close (file);
|
||||
}
|
||||
|
||||
if (rv == 0 && fstat (file, &nfinfo) < 0)
|
||||
rv = errno;
|
||||
{
|
||||
rv = errno;
|
||||
close (file);
|
||||
}
|
||||
|
||||
if (rv == 0 && close (file) < 0)
|
||||
rv = errno;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include "posixtime.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -261,7 +262,7 @@ hist_inittime (void)
|
||||
time_t t;
|
||||
char ts[64], *ret;
|
||||
|
||||
t = (time_t) time ((time_t *)0);
|
||||
t = getnow ();
|
||||
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
|
||||
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
|
||||
#else
|
||||
|
||||
+5
-4
@@ -340,13 +340,14 @@ rl_maybe_replace_line (void)
|
||||
xfree (temp->line);
|
||||
FREE (temp->timestamp);
|
||||
xfree (temp);
|
||||
/* What about _rl_saved_line_for_history? if the saved undo list is
|
||||
rl_undo_list, and we just put that into a history entry, should
|
||||
we set the saved undo list to NULL? */
|
||||
if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == rl_undo_list)
|
||||
_rl_saved_line_for_history->data = 0;
|
||||
/* Do we want to set rl_undo_list = 0 here since we just saved it into
|
||||
a history entry? */
|
||||
rl_undo_list = 0;
|
||||
|
||||
/* XXX - what about _rl_saved_line_for_history? if the saved undo list
|
||||
is rl_undo_list, and we just put that into a history entry, should
|
||||
we set the saved undo list to NULL? */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ rl_free_undo_list (void)
|
||||
_rl_free_undo_list (rl_undo_list);
|
||||
rl_undo_list = (UNDO_LIST *)NULL;
|
||||
_hs_replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
|
||||
if (_rl_saved_line_for_history && (UNDO_LIST *)_rl_saved_line_for_history->data == orig_list)
|
||||
_rl_saved_line_for_history->data = 0;
|
||||
}
|
||||
|
||||
UNDO_LIST *
|
||||
|
||||
+2
-1
@@ -279,10 +279,11 @@ char *
|
||||
sh_mktmpdir (const char *nameroot, int flags)
|
||||
{
|
||||
char *filename;
|
||||
int fd;
|
||||
#ifdef USE_MKDTEMP
|
||||
char *tdir, *dirname;
|
||||
const char *lroot;
|
||||
int fd, tdlen;
|
||||
int tdlen;
|
||||
|
||||
filename = (char *)xmalloc (PATH_MAX + 1);
|
||||
tdir = get_tmpdir (flags);
|
||||
|
||||
Reference in New Issue
Block a user