X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=readline%2Fhistfile.c;h=30a618247f1ec8a7be1c9202ae84224c7e8d5d5e;hb=5836a818eccb180d75c92ce4c861abb6fe8dec23;hp=8749886b6e37e68df38ab1f928a506390339c7e9;hpb=b8cc7b2e9afab37eb9a7cff0d3ae4ebbcf7d494f;p=deliverable%2Fbinutils-gdb.git diff --git a/readline/histfile.c b/readline/histfile.c index 8749886b6e..30a618247f 100644 --- a/readline/histfile.c +++ b/readline/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989-2015 Free Software Foundation, Inc. +/* Copyright (C) 1989-2010 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -35,10 +35,6 @@ #include -#if defined (HAVE_LIMITS_H) -# include -#endif - #include #if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H) # include @@ -103,31 +99,12 @@ extern int errno; #include "rlshell.h" #include "xmalloc.h" -#if !defined (PATH_MAX) -# define PATH_MAX 1024 /* default */ -#endif - /* If non-zero, we write timestamps to the history file in history_do_write() */ int history_write_timestamps = 0; -/* Immediately after a call to read_history() or read_history_range(), this - will return the number of lines just read from the history file in that - call. */ -int history_lines_read_from_file = 0; - -/* Immediately after a call to write_history() or history_do_write(), this - will return the number of lines just written to the history file in that - call. This also works with history_truncate_file. */ -int history_lines_written_to_file = 0; - /* Does S look like the beginning of a history timestamp entry? Placeholder for more extensive tests. */ -#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) ) - -static char *history_backupfile PARAMS((const char *)); -static char *history_tempfile PARAMS((const char *)); -static int histfile_backup PARAMS((const char *, const char *)); -static int histfile_restore PARAMS((const char *, const char *)); +#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) ) /* Return the string that should be used in the place of this filename. This only matters when you don't specify the @@ -146,13 +123,16 @@ history_filename (filename) return (return_val); home = sh_get_env_value ("HOME"); -#if defined (_WIN32) - if (home == 0) - home = sh_get_env_value ("APPDATA"); -#endif if (home == 0) - return (NULL); + { +#if 0 + home = "."; + home_len = 1; +#else + return (NULL); +#endif + } else home_len = strlen (home); @@ -168,75 +148,6 @@ history_filename (filename) return (return_val); } -static char * -history_backupfile (filename) - const char *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 */ - if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) - { - linkbuf[n] = '\0'; - fn = linkbuf; - } -#endif - - len = strlen (fn); - ret = xmalloc (len + 2); - 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 - history file; call will fail if not a symlink */ - if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) - { - linkbuf[n] = '\0'; - fn = linkbuf; - } -#endif - - len = strlen (fn); - ret = xmalloc (len + 11); - strcpy (ret, fn); - - pid = (int)getpid (); - - /* filename-PID.tmp */ - ret[len] = '-'; - ret[len+1] = (pid / 10000 % 10) + '0'; - ret[len+2] = (pid / 1000 % 10) + '0'; - ret[len+3] = (pid / 100 % 10) + '0'; - ret[len+4] = (pid / 10 % 10) + '0'; - ret[len+5] = (pid % 10) + '0'; - strcpy (ret + len + 6, ".tmp"); - - return ret; -} - /* Add the contents of FILENAME to the history list, a line at a time. If FILENAME is NULL, then read from ~/.history. Returns 0 if successful, or errno if not. */ @@ -270,8 +181,6 @@ read_history_range (filename, from, to) int overflow_errno = EIO; #endif - history_lines_read_from_file = 0; - buffer = last_ts = (char *)NULL; input = history_filename (filename); file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1; @@ -384,8 +293,6 @@ read_history_range (filename, from, to) line_start = line_end + 1; } - history_lines_read_from_file = current_line; - FREE (input); #ifndef HISTORY_USE_MMAP FREE (buffer); @@ -396,68 +303,23 @@ read_history_range (filename, from, to) return (0); } -/* Save FILENAME to BACK, handling case where FILENAME is a symlink - (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ -static int -histfile_backup (filename, back) - const char *filename; - const char *back; -{ -#if defined (HAVE_READLINK) - char linkbuf[PATH_MAX+1]; - ssize_t n; - - /* Follow to target of symlink to avoid renaming symlink itself */ - if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0) - { - linkbuf[n] = '\0'; - return (rename (linkbuf, back)); - } -#endif - return (rename (filename, back)); -} - -/* Restore ORIG from BACKUP handling case where ORIG is a symlink - (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */ -static int -histfile_restore (backup, orig) - const char *backup; - const char *orig; -{ -#if defined (HAVE_READLINK) - char linkbuf[PATH_MAX+1]; - ssize_t n; - - /* Follow to target of symlink to avoid renaming symlink itself */ - if ((n = readlink (orig, linkbuf, sizeof (linkbuf) - 1)) > 0) - { - linkbuf[n] = '\0'; - return (rename (backup, linkbuf)); - } -#endif - return (rename (backup, orig)); -} - /* Truncate the history file FNAME, leaving only LINES trailing lines. - If FNAME is NULL, then use ~/.history. Writes a new file and renames - it to the original name. Returns 0 on success, errno on failure. */ + If FNAME is NULL, then use ~/.history. Returns 0 on success, errno + on failure. */ int history_truncate_file (fname, lines) const char *fname; int lines; { - char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */ - int file, chars_read, rv, orig_lines, exists; + char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */ + int file, chars_read, rv; struct stat finfo; size_t file_size; - history_lines_written_to_file = 0; - buffer = (char *)NULL; filename = history_filename (fname); - tempname = 0; file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1; - rv = exists = 0; + rv = 0; /* Don't try to truncate non-regular files. */ if (file == -1 || fstat (file, &finfo) == -1) @@ -467,7 +329,6 @@ history_truncate_file (fname, lines) close (file); goto truncate_exit; } - exists = 1; if (S_ISREG (finfo.st_mode) == 0) { @@ -499,7 +360,6 @@ history_truncate_file (fname, lines) buffer = (char *)malloc (file_size + 1); if (buffer == 0) { - rv = errno; close (file); goto truncate_exit; } @@ -513,7 +373,6 @@ history_truncate_file (fname, lines) goto truncate_exit; } - orig_lines = lines; /* 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 @@ -542,56 +401,27 @@ history_truncate_file (fname, lines) /* Write only if there are more lines in the file than we want to truncate to. */ - if (bp <= buffer) + if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { - rv = 0; - /* No-op if LINES == 0 at this point */ - history_lines_written_to_file = orig_lines - lines; - goto truncate_exit; - } - - tempname = history_tempfile (filename); + write (file, bp, chars_read - (bp - buffer)); - 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; +#if defined (__BEOS__) + /* BeOS ignores O_TRUNC. */ + ftruncate (file, chars_read - (bp - buffer)); +#endif - if (close (file) < 0 && rv == 0) - rv = errno; + close (file); } - else - rv = errno; truncate_exit: - FREE (buffer); - - history_lines_written_to_file = orig_lines - lines; - - if (rv == 0 && filename && tempname) - rv = histfile_restore (tempname, filename); - - if (rv != 0) - { - if (tempname) - unlink (tempname); - history_lines_written_to_file = 0; - } - /* Make sure the new filename is owned by the same user as the old. If one - user is running this, it's a no-op. If the shell is running after sudo - with a shared history file, we don't want to leave the history file - owned by root. */ - if (rv == 0 && exists) - chown (filename, finfo.st_uid, finfo.st_gid); + FREE (buffer); xfree (filename); - FREE (tempname); - return rv; } -/* Workhorse function for writing history. Writes the last NELEMENT entries +/* Workhorse function for writing history. Writes NELEMENT entries from the history list to FILENAME. OVERWRITE is non-zero if you wish to replace FILENAME with the entries. */ static int @@ -600,32 +430,23 @@ history_do_write (filename, nelements, overwrite) int nelements, overwrite; { register int i; - char *output, *tempname, *histname; - int file, mode, rv, exists; - struct stat finfo; + char *output; + int file, mode, rv; #ifdef HISTORY_USE_MMAP size_t cursize; - history_lines_written_to_file = 0; - mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY; #else mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; #endif - histname = history_filename (filename); - tempname = (overwrite && histname) ? history_tempfile (histname) : 0; - output = tempname ? tempname : histname; - exists = histname ? (stat (histname, &finfo) == 0) : 0; - + output = history_filename (filename); file = output ? open (output, mode, 0600) : -1; rv = 0; if (file == -1) { - rv = errno; - FREE (histname); - FREE (tempname); - return (rv); + FREE (output); + return (errno); } #ifdef HISTORY_USE_MMAP @@ -665,11 +486,8 @@ history_do_write (filename, nelements, overwrite) { mmap_error: rv = errno; + FREE (output); close (file); - if (tempname) - unlink (tempname); - FREE (histname); - FREE (tempname); return rv; } #else @@ -677,11 +495,8 @@ mmap_error: if (buffer == 0) { rv = errno; + FREE (output); close (file); - if (tempname) - unlink (tempname); - FREE (histname); - FREE (tempname); return rv; } #endif @@ -700,7 +515,7 @@ mmap_error: } #ifdef HISTORY_USE_MMAP - if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0) + if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0) rv = errno; #else if (write (file, buffer, buffer_size) < 0) @@ -709,30 +524,9 @@ mmap_error: #endif } - history_lines_written_to_file = nelements; - - if (close (file) < 0 && rv == 0) - rv = errno; - - if (rv == 0 && histname && tempname) - rv = histfile_restore (tempname, histname); - - if (rv != 0) - { - if (tempname) - unlink (tempname); - history_lines_written_to_file = 0; - } - - /* Make sure the new filename is owned by the same user as the old. If one - user is running this, it's a no-op. If the shell is running after sudo - with a shared history file, we don't want to leave the history file - owned by root. */ - if (rv == 0 && exists) - chown (histname, finfo.st_uid, finfo.st_gid); + close (file); - FREE (histname); - FREE (tempname); + FREE (output); return (rv); }