blob: 7d049989156c8cbd24164139b7e623c3738cdd72 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001This file is history.def, from which is created history.c.
2It implements the builtin "history" in Bash.
3
Jari Aalto31859422009-01-12 13:36:28 +00004Copyright (C) 1987-2009 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008Bash is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013Bash is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
Jari Aalto726f6381996-08-26 18:22:31 +000020
21$PRODUCES history.c
22
23$BUILTIN history
24$FUNCTION history_builtin
25$DEPENDS_ON HISTORY
Jari Aalto31859422009-01-12 13:36:28 +000026$SHORT_DOC history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
27Display or manipulate the history list.
Jari Aaltob80f6442004-07-27 13:29:18 +000028
Jari Aalto31859422009-01-12 13:36:28 +000029Display the history list with line numbers, prefixing each modified
30entry with a `*'. An argument of N lists only the last N entries.
31
32Options:
33 -c clear the history list by deleting all of the entries
34 -d offset delete the history entry at offset OFFSET.
35
36 -a append history lines from this session to the history file
37 -n read all history lines not already read from the history file
38 -r read the history file and append the contents to the history
39 list
40 -w write the current history to the history file
41 and append them to the history list
42
43 -p perform history expansion on each ARG and display the result
44 without storing it in the history list
45 -s append the ARGs to the history list as a single entry
46
47If FILENAME is given, it is used as the history file. Otherwise,
Jari Aaltoccc6cda1996-12-23 17:02:34 +000048if $HISTFILE has a value, that is used, else ~/.bash_history.
Jari Aaltob80f6442004-07-27 13:29:18 +000049
50If the $HISTTIMEFORMAT variable is set and not null, its value is used
51as a format string for strftime(3) to print the time stamp associated
52with each displayed history entry. No time stamps are printed otherwise.
Jari Aalto31859422009-01-12 13:36:28 +000053
54Exit Status:
55Returns success unless an invalid option is given or an error occurs.
Jari Aalto726f6381996-08-26 18:22:31 +000056$END
57
Jari Aaltoccc6cda1996-12-23 17:02:34 +000058#include <config.h>
59
Jari Aalto726f6381996-08-26 18:22:31 +000060#if defined (HISTORY)
Jari Aaltod166f041997-06-05 14:59:13 +000061#include "../bashtypes.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000062#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000063# include <sys/file.h>
64#endif
Jari Aaltobb706242000-03-17 21:46:59 +000065#include "posixstat.h"
66#include "filecntl.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000067#include <errno.h>
68#include <stdio.h>
69#if defined (HAVE_UNISTD_H)
70# include <unistd.h>
71#endif
72
73#include "../bashansi.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000074#include "../bashintl.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000075
76#include "../shell.h"
Jari Aalto726f6381996-08-26 18:22:31 +000077#include "../bashhist.h"
78#include <readline/history.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000079#include "bashgetopt.h"
80#include "common.h"
Jari Aalto726f6381996-08-26 18:22:31 +000081
Jari Aaltoccc6cda1996-12-23 17:02:34 +000082#if !defined (errno)
Ricardo Cerqueiraa02fbff2013-07-25 22:35:34 +010083#include <errno.h>
Jari Aaltoccc6cda1996-12-23 17:02:34 +000084#endif
Jari Aalto726f6381996-08-26 18:22:31 +000085
Jari Aalto7117c2d2002-07-17 14:10:11 +000086extern int current_command_line_count;
Jari Aalto95732b42005-12-07 14:08:12 +000087extern int force_append_history; /* shopt -s histappend */
88
Jari Aaltob80f6442004-07-27 13:29:18 +000089static char *histtime __P((HIST_ENTRY *, const char *));
Jari Aalto31859422009-01-12 13:36:28 +000090static int display_history __P((WORD_LIST *));
Jari Aaltof73dda02001-11-13 17:56:06 +000091static void push_history __P((WORD_LIST *));
92static int expand_and_print_history __P((WORD_LIST *));
Jari Aaltoccc6cda1996-12-23 17:02:34 +000093
94#define AFLAG 0x01
95#define RFLAG 0x02
96#define WFLAG 0x04
97#define NFLAG 0x08
98#define SFLAG 0x10
99#define PFLAG 0x20
100#define CFLAG 0x40
Jari Aaltobb706242000-03-17 21:46:59 +0000101#define DFLAG 0x80
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000102
103int
Jari Aalto726f6381996-08-26 18:22:31 +0000104history_builtin (list)
105 WORD_LIST *list;
106{
Jari Aaltob80f6442004-07-27 13:29:18 +0000107 int flags, opt, result, old_history_lines, obase;
Jari Aaltobb706242000-03-17 21:46:59 +0000108 char *filename, *delete_arg;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000109 intmax_t delete_offset;
Jari Aalto726f6381996-08-26 18:22:31 +0000110
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000111 flags = 0;
112 reset_internal_getopt ();
Jari Aaltobb706242000-03-17 21:46:59 +0000113 while ((opt = internal_getopt (list, "acd:npsrw")) != -1)
Jari Aalto726f6381996-08-26 18:22:31 +0000114 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000115 switch (opt)
Jari Aalto726f6381996-08-26 18:22:31 +0000116 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000117 case 'a':
118 flags |= AFLAG;
Jari Aalto726f6381996-08-26 18:22:31 +0000119 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000120 case 'c':
121 flags |= CFLAG;
122 break;
123 case 'n':
124 flags |= NFLAG;
125 break;
126 case 'r':
127 flags |= RFLAG;
128 break;
129 case 'w':
130 flags |= WFLAG;
131 break;
132 case 's':
133 flags |= SFLAG;
134 break;
Jari Aaltobb706242000-03-17 21:46:59 +0000135 case 'd':
136 flags |= DFLAG;
137 delete_arg = list_optarg;
138 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000139 case 'p':
140#if defined (BANG_HISTORY)
141 flags |= PFLAG;
142#endif
143 break;
144 default:
145 builtin_usage ();
Jari Aalto726f6381996-08-26 18:22:31 +0000146 return (EX_USAGE);
147 }
Jari Aalto726f6381996-08-26 18:22:31 +0000148 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000149 list = loptend;
150
151 opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
152 if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
153 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000154 builtin_error (_("cannot use more than one of -anrw"));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000155 return (EXECUTION_FAILURE);
156 }
157
158 /* clear the history, but allow other arguments to add to it again. */
159 if (flags & CFLAG)
160 {
Jari Aalto31859422009-01-12 13:36:28 +0000161 bash_clear_history ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000162 if (list == 0)
163 return (EXECUTION_SUCCESS);
164 }
165
166 if (flags & SFLAG)
167 {
168 if (list)
169 push_history (list);
170 return (EXECUTION_SUCCESS);
171 }
172#if defined (BANG_HISTORY)
173 else if (flags & PFLAG)
174 {
175 if (list)
Jari Aalto28ef6c32001-04-06 19:14:31 +0000176 return (expand_and_print_history (list));
Jari Aalto31859422009-01-12 13:36:28 +0000177 return (sh_chkwrite (EXECUTION_SUCCESS));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000178 }
179#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000180 else if (flags & DFLAG)
181 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000182 if ((legal_number (delete_arg, &delete_offset) == 0)
183 || (delete_offset < history_base)
184 || (delete_offset > (history_base + history_length)))
Jari Aaltobb706242000-03-17 21:46:59 +0000185 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000186 sh_erange (delete_arg, _("history position"));
Jari Aaltobb706242000-03-17 21:46:59 +0000187 return (EXECUTION_FAILURE);
188 }
189 opt = delete_offset;
Jari Aalto31859422009-01-12 13:36:28 +0000190 result = bash_delete_histent (opt - history_base);
Jari Aaltobb706242000-03-17 21:46:59 +0000191 /* Since remove_history changes history_length, this can happen if
192 we delete the last history entry. */
193 if (where_history () > history_length)
194 history_set_pos (history_length);
195 return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
196 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000197 else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
198 {
Jari Aalto31859422009-01-12 13:36:28 +0000199 result = display_history (list);
200 return (sh_chkwrite (result));
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000201 }
202
203 filename = list ? list->word->word : get_string_value ("HISTFILE");
204 result = EXECUTION_SUCCESS;
205
206 if (flags & AFLAG) /* Append session's history to file. */
207 result = maybe_append_history (filename);
208 else if (flags & WFLAG) /* Write entire history. */
209 result = write_history (filename);
210 else if (flags & RFLAG) /* Read entire file. */
211 result = read_history (filename);
212 else if (flags & NFLAG) /* Read `new' history from file. */
213 {
214 /* Read all of the lines in the file that we haven't already read. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000215 old_history_lines = history_lines_in_file;
Jari Aaltob80f6442004-07-27 13:29:18 +0000216 obase = history_base;
217
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000218 using_history ();
219 result = read_history_range (filename, history_lines_in_file, -1);
220 using_history ();
Jari Aaltob80f6442004-07-27 13:29:18 +0000221
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000222 history_lines_in_file = where_history ();
Jari Aalto95732b42005-12-07 14:08:12 +0000223
224 /* If we're rewriting the history file at shell exit rather than just
225 appending the lines from this session to it, the question is whether
226 we reset history_lines_this_session to 0, losing any history entries
227 we had before we read the new entries from the history file, or
228 whether we count the new entries we just read from the file as
229 history lines added during this session.
Jari Aaltob80f6442004-07-27 13:29:18 +0000230 Right now, we do the latter. This will cause these history entries
231 to be written to the history file along with any intermediate entries
232 we add when we do a `history -a', but the alternative is losing
233 them altogether. */
Jari Aalto95732b42005-12-07 14:08:12 +0000234 if (force_append_history == 0)
235 history_lines_this_session += history_lines_in_file - old_history_lines +
Jari Aaltob80f6442004-07-27 13:29:18 +0000236 history_base - obase;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000237 }
238
239 return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
240}
241
242/* Accessors for HIST_ENTRY lists that are called HLIST. */
243#define histline(i) (hlist[(i)]->line)
244#define histdata(i) (hlist[(i)]->data)
245
Jari Aaltob80f6442004-07-27 13:29:18 +0000246static char *
247histtime (hlist, histtimefmt)
248 HIST_ENTRY *hlist;
249 const char *histtimefmt;
250{
251 static char timestr[128];
252 time_t t;
253
254 t = history_get_time (hlist);
255 if (t)
256 strftime (timestr, sizeof (timestr), histtimefmt, localtime (&t));
257 else
258 strcpy (timestr, "??");
259 return timestr;
260}
261
Jari Aalto31859422009-01-12 13:36:28 +0000262static int
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000263display_history (list)
264 WORD_LIST *list;
265{
266 register int i;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000267 intmax_t limit;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000268 HIST_ENTRY **hlist;
Jari Aaltob80f6442004-07-27 13:29:18 +0000269 char *histtimefmt, *timestr;
Jari Aalto726f6381996-08-26 18:22:31 +0000270
271 if (list)
272 {
Jari Aalto31859422009-01-12 13:36:28 +0000273 if (get_numeric_arg (list, 0, &limit) == 0)
274 return (EXECUTION_FAILURE);
275
Jari Aaltof73dda02001-11-13 17:56:06 +0000276 if (limit < 0)
277 limit = -limit;
Jari Aalto726f6381996-08-26 18:22:31 +0000278 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000279 else
Jari Aaltof73dda02001-11-13 17:56:06 +0000280 limit = -1;
Jari Aalto726f6381996-08-26 18:22:31 +0000281
282 hlist = history_list ();
283
284 if (hlist)
285 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000286 for (i = 0; hlist[i]; i++)
287 ;
Jari Aalto726f6381996-08-26 18:22:31 +0000288
Jari Aaltof73dda02001-11-13 17:56:06 +0000289 if (0 <= limit && limit < i)
290 i -= limit;
291 else
Jari Aalto726f6381996-08-26 18:22:31 +0000292 i = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000293
Jari Aaltob80f6442004-07-27 13:29:18 +0000294 histtimefmt = get_string_value ("HISTTIMEFORMAT");
295
Jari Aalto726f6381996-08-26 18:22:31 +0000296 while (hlist[i])
297 {
298 QUIT;
Jari Aaltob80f6442004-07-27 13:29:18 +0000299
300 timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL;
301 printf ("%5d%c %s%s\n", i + history_base,
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000302 histdata(i) ? '*' : ' ',
Jari Aaltob80f6442004-07-27 13:29:18 +0000303 ((timestr && *timestr) ? timestr : ""),
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000304 histline(i));
Jari Aalto726f6381996-08-26 18:22:31 +0000305 i++;
306 }
307 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000308
Jari Aalto31859422009-01-12 13:36:28 +0000309 return (EXECUTION_SUCCESS);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000310}
311
312/* Remove the last entry in the history list and add each argument in
313 LIST to the history. */
314static void
315push_history (list)
316 WORD_LIST *list;
317{
318 char *s;
319
Jari Aalto7117c2d2002-07-17 14:10:11 +0000320 /* Delete the last history entry if it was a single entry added to the
321 history list (generally the `history -s' itself), or if `history -s'
322 is being used in a compound command and the compound command was
323 added to the history as a single element (command-oriented history).
324 If you don't want history -s to remove the compound command from the
325 history, change #if 0 to #if 1 below. */
326#if 0
Chet Rameyac50fba2014-02-26 09:36:43 -0500327 if (remember_on_history && hist_last_line_pushed == 0 &&
328 hist_last_line_added && bash_delete_last_history () == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000329#else
Chet Rameyac50fba2014-02-26 09:36:43 -0500330 if (remember_on_history && hist_last_line_pushed == 0 &&
Jari Aalto95732b42005-12-07 14:08:12 +0000331 (hist_last_line_added ||
332 (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
Jari Aalto31859422009-01-12 13:36:28 +0000333 && bash_delete_last_history () == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000334#endif
335 return;
336
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000337 s = string_list (list);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000338 /* Call check_add_history with FORCE set to 1 to skip the check against
339 current_command_line_count. If history -s is used in a compound
340 command, the above code will delete the compound command's history
341 entry and this call will add the line to the history as a separate
342 entry. Without FORCE=1, if current_command_line_count were > 1, the
343 line would be appended to the entry before the just-deleted entry. */
344 check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */
Jari Aalto95732b42005-12-07 14:08:12 +0000345
346 hist_last_line_pushed = 1; /* XXX */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000347 free (s);
348}
349
350#if defined (BANG_HISTORY)
351static int
352expand_and_print_history (list)
353 WORD_LIST *list;
354{
355 char *s;
356 int r, result;
357
Jari Aalto31859422009-01-12 13:36:28 +0000358 if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000359 return EXECUTION_FAILURE;
360 result = EXECUTION_SUCCESS;
361 while (list)
362 {
363 r = history_expand (list->word->word, &s);
364 if (r < 0)
365 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000366 builtin_error (_("%s: history expansion failed"), list->word->word);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000367 result = EXECUTION_FAILURE;
368 }
369 else
Jari Aalto28ef6c32001-04-06 19:14:31 +0000370 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000371 fputs (s, stdout);
372 putchar ('\n');
Jari Aalto28ef6c32001-04-06 19:14:31 +0000373 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000374 FREE (s);
375 list = list->next;
376 }
377 fflush (stdout);
378 return result;
379}
380#endif /* BANG_HISTORY */
Jari Aalto726f6381996-08-26 18:22:31 +0000381#endif /* HISTORY */