1 /* histfile.c - functions to manipulate the history file. */
3 /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
5 This file contains the GNU History Library (History), a set of
6 routines for managing the text of previously typed lines.
8 History is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 History is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with History. If not, see <http://www.gnu.org/licenses/>.
22 /* The goal is to make the implementation transparent, so that you
23 don't have to know what data types are used, just what functions
24 you can call. I think I have done that. */
26 #define READLINE_LIBRARY
28 #if defined (__TANDEM)
32 #if defined (HAVE_CONFIG_H)
38 #if defined (HAVE_LIMITS_H)
42 #include <sys/types.h>
43 #if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
44 # include <sys/file.h>
46 #include "posixstat.h"
49 #if defined (HAVE_STDLIB_H)
52 # include "ansi_stdlib.h"
53 #endif /* HAVE_STDLIB_H */
55 #if defined (HAVE_UNISTD_H)
65 #ifdef HISTORY_USE_MMAP
66 # include <sys/mman.h>
69 # define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
70 # define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
72 # define MAP_RFLAGS MAP_PRIVATE
73 # define MAP_WFLAGS MAP_SHARED
77 # define MAP_FAILED ((void *)-1)
80 #endif /* HISTORY_USE_MMAP */
82 /* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
83 on win 95/98/nt), we want to open files with O_BINARY mode so that there
84 is no \n -> \r\n conversion performed. On other systems, we don't want to
85 mess around with O_BINARY at all, so we ensure that it's defined to 0. */
86 #if defined (__EMX__) || defined (__CYGWIN__)
90 #else /* !__EMX__ && !__CYGWIN__ */
93 #endif /* !__EMX__ && !__CYGWIN__ */
106 #if !defined (PATH_MAX)
107 # define PATH_MAX 1024 /* default */
110 extern void _hs_append_history_line
PARAMS((int, const char *));
112 /* history file version; currently unused */
113 int history_file_version
= 1;
115 /* If non-zero, we write timestamps to the history file in history_do_write() */
116 int history_write_timestamps
= 0;
118 /* If non-zero, we assume that a history file that starts with a timestamp
119 uses timestamp-delimited entries and can include multi-line history
120 entries. Used by read_history_range */
121 int history_multiline_entries
= 0;
123 /* Immediately after a call to read_history() or read_history_range(), this
124 will return the number of lines just read from the history file in that
126 int history_lines_read_from_file
= 0;
128 /* Immediately after a call to write_history() or history_do_write(), this
129 will return the number of lines just written to the history file in that
130 call. This also works with history_truncate_file. */
131 int history_lines_written_to_file
= 0;
133 /* Does S look like the beginning of a history timestamp entry? Placeholder
134 for more extensive tests. */
135 #define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) )
137 static char *history_backupfile
PARAMS((const char *));
138 static char *history_tempfile
PARAMS((const char *));
139 static int histfile_backup
PARAMS((const char *, const char *));
140 static int histfile_restore
PARAMS((const char *, const char *));
142 /* Return the string that should be used in the place of this
143 filename. This only matters when you don't specify the
144 filename to read_history (), or write_history (). */
146 history_filename (const char *filename
)
152 return_val
= filename
? savestring (filename
) : (char *)NULL
;
157 home
= sh_get_env_value ("HOME");
160 home
= sh_get_env_value ("APPDATA");
166 home_len
= strlen (home
);
168 return_val
= (char *)xmalloc (2 + home_len
+ 8); /* strlen(".history") == 8 */
169 strcpy (return_val
, home
);
170 return_val
[home_len
] = '/';
171 #if defined (__MSDOS__)
172 strcpy (return_val
+ home_len
+ 1, "_history");
174 strcpy (return_val
+ home_len
+ 1, ".history");
181 history_backupfile (const char *filename
)
184 char *ret
, linkbuf
[PATH_MAX
+1];
190 #if defined (HAVE_READLINK)
191 /* Follow symlink to avoid backing up symlink itself; call will fail if
193 if ((n
= readlink (filename
, linkbuf
, sizeof (linkbuf
) - 1)) > 0)
201 ret
= xmalloc (len
+ 2);
209 history_tempfile (const char *filename
)
212 char *ret
, linkbuf
[PATH_MAX
+1];
219 #if defined (HAVE_READLINK)
220 /* Follow symlink so tempfile created in the same directory as any symlinked
221 history file; call will fail if not a symlink */
222 if ((n
= readlink (filename
, linkbuf
, sizeof (linkbuf
) - 1)) > 0)
230 ret
= xmalloc (len
+ 11);
233 pid
= (int)getpid ();
235 /* filename-PID.tmp */
237 ret
[len
+1] = (pid
/ 10000 % 10) + '0';
238 ret
[len
+2] = (pid
/ 1000 % 10) + '0';
239 ret
[len
+3] = (pid
/ 100 % 10) + '0';
240 ret
[len
+4] = (pid
/ 10 % 10) + '0';
241 ret
[len
+5] = (pid
% 10) + '0';
242 strcpy (ret
+ len
+ 6, ".tmp");
247 /* Add the contents of FILENAME to the history list, a line at a time.
248 If FILENAME is NULL, then read from ~/.history. Returns 0 if
249 successful, or errno if not. */
251 read_history (const char *filename
)
253 return (read_history_range (filename
, 0, -1));
256 /* Read a range of lines from FILENAME, adding them to the history list.
257 Start reading at the FROM'th line and end at the TO'th. If FROM
258 is zero, start at the beginning. If TO is less than FROM, read
259 until the end of the file. If FILENAME is NULL, then read from
260 ~/.history. Returns 0 if successful, or errno if not. */
262 read_history_range (const char *filename
, int from
, int to
)
264 register char *line_start
, *line_end
, *p
;
265 char *input
, *buffer
, *bufend
, *last_ts
;
266 int file
, current_line
, chars_read
, has_timestamps
, reset_comment_char
;
270 int overflow_errno
= EFBIG
;
271 #elif defined (EOVERFLOW)
272 int overflow_errno
= EOVERFLOW
;
274 int overflow_errno
= EIO
;
277 history_lines_read_from_file
= 0;
279 buffer
= last_ts
= (char *)NULL
;
280 input
= history_filename (filename
);
281 file
= input
? open (input
, O_RDONLY
|O_BINARY
, 0666) : -1;
283 if ((file
< 0) || (fstat (file
, &finfo
) == -1))
286 if (S_ISREG (finfo
.st_mode
) == 0)
296 file_size
= (size_t)finfo
.st_size
;
298 /* check for overflow on very large files */
299 if (file_size
!= finfo
.st_size
|| file_size
+ 1 < file_size
)
301 errno
= overflow_errno
;
309 return 0; /* don't waste time if we don't have to */
312 #ifdef HISTORY_USE_MMAP
313 /* We map read/write and private so we can change newlines to NULs without
314 affecting the underlying object. */
315 buffer
= (char *)mmap (0, file_size
, PROT_READ
|PROT_WRITE
, MAP_RFLAGS
, file
, 0);
316 if ((void *)buffer
== MAP_FAILED
)
318 errno
= overflow_errno
;
321 chars_read
= file_size
;
323 buffer
= (char *)malloc (file_size
+ 1);
326 errno
= overflow_errno
;
330 chars_read
= read (file
, buffer
, file_size
);
343 #ifndef HISTORY_USE_MMAP
352 /* Set TO to larger than end of file if negative. */
356 /* Start at beginning of file, work to end. */
357 bufend
= buffer
+ chars_read
;
358 *bufend
= '\0'; /* null-terminate buffer for timestamp checks */
361 /* Heuristic: the history comment character rarely changes, so assume we
362 have timestamps if the buffer starts with `#[:digit:]' and temporarily
363 set history_comment_char so timestamp parsing works right */
364 reset_comment_char
= 0;
365 if (history_comment_char
== '\0' && buffer
[0] == '#' && isdigit ((unsigned char)buffer
[1]))
367 history_comment_char
= '#';
368 reset_comment_char
= 1;
371 has_timestamps
= HIST_TIMESTAMP_START (buffer
);
372 history_multiline_entries
+= has_timestamps
&& history_write_timestamps
;
374 /* Skip lines until we are at FROM. */
377 for (line_start
= line_end
= buffer
; line_end
< bufend
&& current_line
< from
; line_end
++)
378 if (*line_end
== '\n')
381 /* If we see something we think is a timestamp, continue with this
382 line. We should check more extensively here... */
383 if (HIST_TIMESTAMP_START(p
) == 0)
388 /* If we are at the last line (current_line == from) but we have
389 timestamps (has_timestamps), then line_start points to the
390 text of the last command, and we need to skip to its end. */
391 if (current_line
>= from
&& has_timestamps
)
393 for (line_end
= p
; line_end
< bufend
&& *line_end
!= '\n'; line_end
++)
395 line_start
= (*line_end
== '\n') ? line_end
+ 1 : line_end
;
399 /* If there are lines left to gobble, then gobble them now. */
400 for (line_end
= line_start
; line_end
< bufend
; line_end
++)
401 if (*line_end
== '\n')
403 /* Change to allow Windows-like \r\n end of line delimiter. */
404 if (line_end
> line_start
&& line_end
[-1] == '\r')
411 if (HIST_TIMESTAMP_START(line_start
) == 0)
413 if (last_ts
== NULL
&& history_length
> 0 && history_multiline_entries
)
414 _hs_append_history_line (history_length
- 1, line_start
);
416 add_history (line_start
);
419 add_history_time (last_ts
);
425 last_ts
= line_start
;
432 if (current_line
>= to
)
435 line_start
= line_end
+ 1;
438 history_lines_read_from_file
= current_line
;
439 if (reset_comment_char
)
440 history_comment_char
= '\0';
443 #ifndef HISTORY_USE_MMAP
446 munmap (buffer
, file_size
);
452 /* Save FILENAME to BACK, handling case where FILENAME is a symlink
453 (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
455 histfile_backup (const char *filename
, const char *back
)
457 #if defined (HAVE_READLINK)
458 char linkbuf
[PATH_MAX
+1];
461 /* Follow to target of symlink to avoid renaming symlink itself */
462 if ((n
= readlink (filename
, linkbuf
, sizeof (linkbuf
) - 1)) > 0)
465 return (rename (linkbuf
, back
));
468 return (rename (filename
, back
));
471 /* Restore ORIG from BACKUP handling case where ORIG is a symlink
472 (e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
474 histfile_restore (const char *backup
, const char *orig
)
476 #if defined (HAVE_READLINK)
477 char linkbuf
[PATH_MAX
+1];
480 /* Follow to target of symlink to avoid renaming symlink itself */
481 if ((n
= readlink (orig
, linkbuf
, sizeof (linkbuf
) - 1)) > 0)
484 return (rename (backup
, linkbuf
));
487 return (rename (backup
, orig
));
490 /* Truncate the history file FNAME, leaving only LINES trailing lines.
491 If FNAME is NULL, then use ~/.history. Writes a new file and renames
492 it to the original name. Returns 0 on success, errno on failure. */
494 history_truncate_file (const char *fname
, int lines
)
496 char *buffer
, *filename
, *tempname
, *bp
, *bp1
; /* bp1 == bp+1 */
497 int file
, chars_read
, rv
, orig_lines
, exists
, r
;
501 history_lines_written_to_file
= 0;
503 buffer
= (char *)NULL
;
504 filename
= history_filename (fname
);
506 file
= filename
? open (filename
, O_RDONLY
|O_BINARY
, 0666) : -1;
509 /* Don't try to truncate non-regular files. */
510 if (file
== -1 || fstat (file
, &finfo
) == -1)
519 if (S_ISREG (finfo
.st_mode
) == 0)
530 file_size
= (size_t)finfo
.st_size
;
532 /* check for overflow on very large files */
533 if (file_size
!= finfo
.st_size
|| file_size
+ 1 < file_size
)
538 #elif defined (EOVERFLOW)
539 rv
= errno
= EOVERFLOW
;
546 buffer
= (char *)malloc (file_size
+ 1);
554 chars_read
= read (file
, buffer
, file_size
);
559 rv
= (chars_read
< 0) ? errno
: 0;
564 /* Count backwards from the end of buffer until we have passed
565 LINES lines. bp1 is set funny initially. But since bp[1] can't
566 be a comment character (since it's off the end) and *bp can't be
567 both a newline and the history comment character, it should be OK. */
568 for (bp1
= bp
= buffer
+ chars_read
- 1; lines
&& bp
> buffer
; bp
--)
570 if (*bp
== '\n' && HIST_TIMESTAMP_START(bp1
) == 0)
575 /* If this is the first line, then the file contains exactly the
576 number of lines we want to truncate to, so we don't need to do
577 anything. It's the first line if we don't find a newline between
578 the current value of i and 0. Otherwise, write from the start of
579 this line until the end of the buffer. */
580 for ( ; bp
> buffer
; bp
--)
582 if (*bp
== '\n' && HIST_TIMESTAMP_START(bp1
) == 0)
590 /* Write only if there are more lines in the file than we want to
595 /* No-op if LINES == 0 at this point */
596 history_lines_written_to_file
= orig_lines
- lines
;
600 tempname
= history_tempfile (filename
);
602 if ((file
= open (tempname
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_BINARY
, 0600)) != -1)
604 if (write (file
, bp
, chars_read
- (bp
- buffer
)) < 0)
607 if (close (file
) < 0 && rv
== 0)
616 history_lines_written_to_file
= orig_lines
- lines
;
618 if (rv
== 0 && filename
&& tempname
)
619 rv
= histfile_restore (tempname
, filename
);
625 history_lines_written_to_file
= 0;
628 #if defined (HAVE_CHOWN)
629 /* Make sure the new filename is owned by the same user as the old. If one
630 user is running this, it's a no-op. If the shell is running after sudo
631 with a shared history file, we don't want to leave the history file
633 if (rv
== 0 && exists
)
634 r
= chown (filename
, finfo
.st_uid
, finfo
.st_gid
);
643 /* Workhorse function for writing history. Writes the last NELEMENT entries
644 from the history list to FILENAME. OVERWRITE is non-zero if you
645 wish to replace FILENAME with the entries. */
647 history_do_write (const char *filename
, int nelements
, int overwrite
)
650 char *output
, *tempname
, *histname
;
651 int file
, mode
, rv
, exists
;
653 #ifdef HISTORY_USE_MMAP
656 history_lines_written_to_file
= 0;
658 mode
= overwrite
? O_RDWR
|O_CREAT
|O_TRUNC
|O_BINARY
: O_RDWR
|O_APPEND
|O_BINARY
;
660 mode
= overwrite
? O_WRONLY
|O_CREAT
|O_TRUNC
|O_BINARY
: O_WRONLY
|O_APPEND
|O_BINARY
;
662 histname
= history_filename (filename
);
663 exists
= histname
? (stat (histname
, &finfo
) == 0) : 0;
665 tempname
= (overwrite
&& exists
&& S_ISREG (finfo
.st_mode
)) ? history_tempfile (histname
) : 0;
666 output
= tempname
? tempname
: histname
;
668 file
= output
? open (output
, mode
, 0600) : -1;
679 #ifdef HISTORY_USE_MMAP
680 cursize
= overwrite
? 0 : lseek (file
, 0, SEEK_END
);
683 if (nelements
> history_length
)
684 nelements
= history_length
;
686 /* Build a buffer of all the lines to write, and write them in one syscall.
687 Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
689 HIST_ENTRY
**the_history
; /* local */
694 the_history
= history_list ();
695 /* Calculate the total number of bytes to write. */
696 for (buffer_size
= 0, i
= history_length
- nelements
; i
< history_length
; i
++)
698 buffer_size
+= 2 + HISTENT_BYTES (the_history
[i
]);
701 if (history_write_timestamps
&& the_history
[i
]->timestamp
&& the_history
[i
]->timestamp
[0])
702 buffer_size
+= strlen (the_history
[i
]->timestamp
) + 1;
703 buffer_size
+= strlen (the_history
[i
]->line
) + 1;
707 /* Allocate the buffer, and fill it. */
708 #ifdef HISTORY_USE_MMAP
709 if (ftruncate (file
, buffer_size
+cursize
) == -1)
711 buffer
= (char *)mmap (0, buffer_size
, PROT_READ
|PROT_WRITE
, MAP_WFLAGS
, file
, cursize
);
712 if ((void *)buffer
== MAP_FAILED
)
724 buffer
= (char *)malloc (buffer_size
);
737 for (j
= 0, i
= history_length
- nelements
; i
< history_length
; i
++)
739 if (history_write_timestamps
&& the_history
[i
]->timestamp
&& the_history
[i
]->timestamp
[0])
741 strcpy (buffer
+ j
, the_history
[i
]->timestamp
);
742 j
+= strlen (the_history
[i
]->timestamp
);
745 strcpy (buffer
+ j
, the_history
[i
]->line
);
746 j
+= strlen (the_history
[i
]->line
);
750 #ifdef HISTORY_USE_MMAP
751 if (msync (buffer
, buffer_size
, MS_ASYNC
) != 0 || munmap (buffer
, buffer_size
) != 0)
754 if (write (file
, buffer
, buffer_size
) < 0)
760 history_lines_written_to_file
= nelements
;
762 if (close (file
) < 0 && rv
== 0)
765 if (rv
== 0 && histname
&& tempname
)
766 rv
= histfile_restore (tempname
, histname
);
772 history_lines_written_to_file
= 0;
775 #if defined (HAVE_CHOWN)
776 /* Make sure the new filename is owned by the same user as the old. If one
777 user is running this, it's a no-op. If the shell is running after sudo
778 with a shared history file, we don't want to leave the history file
780 if (rv
== 0 && exists
)
781 mode
= chown (histname
, finfo
.st_uid
, finfo
.st_gid
);
790 /* Append NELEMENT entries to FILENAME. The entries appended are from
791 the end of the list minus NELEMENTs up to the end of the list. */
793 append_history (int nelements
, const char *filename
)
795 return (history_do_write (filename
, nelements
, HISTORY_APPEND
));
798 /* Overwrite FILENAME with the current history. If FILENAME is NULL,
799 then write the history list to ~/.history. Values returned
800 are as in read_history ().*/
802 write_history (const char *filename
)
804 return (history_do_write (filename
, history_length
, HISTORY_OVERWRITE
));