]> git.ipfire.org Git - thirdparty/bash.git/blob - bashhist.c
Imported from ../bash-4.0-rc1.tar.gz.
[thirdparty/bash.git] / bashhist.c
1 /* bashhist.c -- bash interface to the GNU history library. */
2
3 /* Copyright (C) 1993-2009 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #if defined (HISTORY)
24
25 #if defined (HAVE_UNISTD_H)
26 # ifdef _MINIX
27 # include <sys/types.h>
28 # endif
29 # include <unistd.h>
30 #endif
31
32 #include "bashtypes.h"
33 #include <stdio.h>
34 #include <errno.h>
35 #include "bashansi.h"
36 #include "posixstat.h"
37 #include "filecntl.h"
38
39 #include "bashintl.h"
40
41 #include "shell.h"
42 #include "flags.h"
43 #include "input.h"
44 #include "parser.h" /* for the struct dstack stuff. */
45 #include "pathexp.h" /* for the struct ignorevar stuff */
46 #include "bashhist.h" /* matching prototypes and declarations */
47 #include "builtins/common.h"
48
49 #include <readline/history.h>
50 #include <glob/glob.h>
51 #include <glob/strmatch.h>
52
53 #if defined (READLINE)
54 # include "bashline.h"
55 extern int rl_done, rl_dispatching; /* should really include readline.h */
56 #endif
57
58 #if !defined (errno)
59 extern int errno;
60 #endif
61
62 static int histignore_item_func __P((struct ign *));
63 static int check_history_control __P((char *));
64 static void hc_erasedups __P((char *));
65 static void really_add_history __P((char *));
66
67 static struct ignorevar histignore =
68 {
69 "HISTIGNORE",
70 (struct ign *)0,
71 0,
72 (char *)0,
73 (sh_iv_item_func_t *)histignore_item_func,
74 };
75
76 #define HIGN_EXPAND 0x01
77
78 /* Declarations of bash history variables. */
79 /* Non-zero means to remember lines typed to the shell on the history
80 list. This is different than the user-controlled behaviour; this
81 becomes zero when we read lines from a file, for example. */
82 int remember_on_history = 1;
83 int enable_history_list = 1; /* value for `set -o history' */
84
85 /* The number of lines that Bash has added to this history session. The
86 difference between the number of the top element in the history list
87 (offset from history_base) and the number of lines in the history file.
88 Appending this session's history to the history file resets this to 0. */
89 int history_lines_this_session;
90
91 /* The number of lines that Bash has read from the history file. */
92 int history_lines_in_file;
93
94 #if defined (BANG_HISTORY)
95 /* Non-zero means do no history expansion on this line, regardless
96 of what history_expansion says. */
97 int history_expansion_inhibited;
98 #endif
99
100 /* With the old default, every line was saved in the history individually.
101 I.e., if the user enters:
102 bash$ for i in a b c
103 > do
104 > echo $i
105 > done
106 Each line will be individually saved in the history.
107 bash$ history
108 10 for i in a b c
109 11 do
110 12 echo $i
111 13 done
112 14 history
113 If the variable command_oriented_history is set, multiple lines
114 which form one command will be saved as one history entry.
115 bash$ for i in a b c
116 > do
117 > echo $i
118 > done
119 bash$ history
120 10 for i in a b c
121 do
122 echo $i
123 done
124 11 history
125 The user can then recall the whole command all at once instead
126 of just being able to recall one line at a time.
127
128 This is now enabled by default.
129 */
130 int command_oriented_history = 1;
131
132 /* Set to 1 if the first line of a possibly-multi-line command was saved
133 in the history list. Managed by maybe_add_history(), but global so
134 the history-manipluating builtins can see it. */
135 int current_command_first_line_saved = 0;
136
137 /* Non-zero means to store newlines in the history list when using
138 command_oriented_history rather than trying to use semicolons. */
139 int literal_history;
140
141 /* Non-zero means to append the history to the history file at shell
142 exit, even if the history has been stifled. */
143 int force_append_history;
144
145 /* A nit for picking at history saving. Flags have the following values:
146
147 Value == 0 means save all lines parsed by the shell on the history.
148 Value & HC_IGNSPACE means save all lines that do not start with a space.
149 Value & HC_IGNDUPS means save all lines that do not match the last
150 line saved.
151 Value & HC_ERASEDUPS means to remove all other matching lines from the
152 history list before saving the latest line. */
153 int history_control;
154
155 /* Set to 1 if the last command was added to the history list successfully
156 as a separate history entry; set to 0 if the line was ignored or added
157 to a previous entry as part of command-oriented-history processing. */
158 int hist_last_line_added;
159
160 /* Set to 1 if builtins/history.def:push_history added the last history
161 entry. */
162 int hist_last_line_pushed;
163
164 #if defined (READLINE)
165 /* If non-zero, and readline is being used, the user is offered the
166 chance to re-edit a failed history expansion. */
167 int history_reediting;
168
169 /* If non-zero, and readline is being used, don't directly execute a
170 line with history substitution. Reload it into the editing buffer
171 instead and let the user further edit and confirm with a newline. */
172 int hist_verify;
173
174 #endif /* READLINE */
175
176 /* Non-zero means to not save function definitions in the history list. */
177 int dont_save_function_defs;
178
179 /* Variables declared in other files used here. */
180 extern int current_command_line_count;
181
182 extern struct dstack dstack;
183
184 static int bash_history_inhibit_expansion __P((char *, int));
185 #if defined (READLINE)
186 static void re_edit __P((char *));
187 #endif
188 static int history_expansion_p __P((char *));
189 static int shell_comment __P((char *));
190 static int should_expand __P((char *));
191 static HIST_ENTRY *last_history_entry __P((void));
192 static char *expand_histignore_pattern __P((char *));
193 static int history_should_ignore __P((char *));
194
195 /* Is the history expansion starting at string[i] one that should not
196 be expanded? */
197 static int
198 bash_history_inhibit_expansion (string, i)
199 char *string;
200 int i;
201 {
202 /* The shell uses ! as a pattern negation character in globbing [...]
203 expressions, so let those pass without expansion. */
204 if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
205 return (1);
206 /* The shell uses ! as the indirect expansion character, so let those
207 expansions pass as well. */
208 else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
209 member ('}', string + i + 1))
210 return (1);
211 #if defined (EXTENDED_GLOB)
212 else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
213 return (1);
214 #endif
215 else
216 return (0);
217 }
218
219 void
220 bash_initialize_history ()
221 {
222 history_quotes_inhibit_expansion = 1;
223 history_search_delimiter_chars = ";&()|<>";
224 history_inhibit_expansion_function = bash_history_inhibit_expansion;
225 #if defined (BANG_HISTORY)
226 sv_histchars ("histchars");
227 #endif
228 }
229
230 void
231 bash_history_reinit (interact)
232 int interact;
233 {
234 #if defined (BANG_HISTORY)
235 history_expansion = interact != 0;
236 history_expansion_inhibited = 1;
237 #endif
238 remember_on_history = enable_history_list = interact != 0;
239 history_inhibit_expansion_function = bash_history_inhibit_expansion;
240 }
241
242 void
243 bash_history_disable ()
244 {
245 remember_on_history = 0;
246 #if defined (BANG_HISTORY)
247 history_expansion_inhibited = 1;
248 #endif
249 }
250
251 void
252 bash_history_enable ()
253 {
254 remember_on_history = 1;
255 #if defined (BANG_HISTORY)
256 history_expansion_inhibited = 0;
257 #endif
258 history_inhibit_expansion_function = bash_history_inhibit_expansion;
259 sv_history_control ("HISTCONTROL");
260 sv_histignore ("HISTIGNORE");
261 }
262
263 /* Load the history list from the history file. */
264 void
265 load_history ()
266 {
267 char *hf;
268
269 /* Truncate history file for interactive shells which desire it.
270 Note that the history file is automatically truncated to the
271 size of HISTSIZE if the user does not explicitly set the size
272 differently. */
273 set_if_not ("HISTSIZE", "500");
274 sv_histsize ("HISTSIZE");
275
276 set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
277 sv_histsize ("HISTFILESIZE");
278
279 /* Read the history in HISTFILE into the history list. */
280 hf = get_string_value ("HISTFILE");
281
282 if (hf && *hf && file_exists (hf))
283 {
284 read_history (hf);
285 using_history ();
286 history_lines_in_file = where_history ();
287 }
288 }
289
290 void
291 bash_clear_history ()
292 {
293 clear_history ();
294 history_lines_this_session = 0;
295 }
296
297 /* Delete and free the history list entry at offset I. */
298 int
299 bash_delete_histent (i)
300 int i;
301 {
302 HIST_ENTRY *discard;
303
304 discard = remove_history (i);
305 if (discard)
306 free_history_entry (discard);
307 history_lines_this_session--;
308
309 return 1;
310 }
311
312 int
313 bash_delete_last_history ()
314 {
315 register int i;
316 HIST_ENTRY **hlist, *histent;
317 int r;
318
319 hlist = history_list ();
320 if (hlist == NULL)
321 return 0;
322
323 for (i = 0; hlist[i]; i++)
324 ;
325 i--;
326
327 /* History_get () takes a parameter that must be offset by history_base. */
328 histent = history_get (history_base + i); /* Don't free this */
329 if (histent == NULL)
330 return 0;
331
332 r = bash_delete_histent (i);
333
334 if (where_history () > history_length)
335 history_set_pos (history_length);
336
337 return r;
338 }
339
340 #ifdef INCLUDE_UNUSED
341 /* Write the existing history out to the history file. */
342 void
343 save_history ()
344 {
345 char *hf;
346
347 hf = get_string_value ("HISTFILE");
348 if (hf && *hf && file_exists (hf))
349 {
350 /* Append only the lines that occurred this session to
351 the history file. */
352 using_history ();
353
354 if (history_lines_this_session < where_history () || force_append_history)
355 append_history (history_lines_this_session, hf);
356 else
357 write_history (hf);
358
359 sv_histsize ("HISTFILESIZE");
360 }
361 }
362 #endif
363
364 int
365 maybe_append_history (filename)
366 char *filename;
367 {
368 int fd, result;
369 struct stat buf;
370
371 result = EXECUTION_SUCCESS;
372 if (history_lines_this_session && (history_lines_this_session < where_history ()))
373 {
374 /* If the filename was supplied, then create it if necessary. */
375 if (stat (filename, &buf) == -1 && errno == ENOENT)
376 {
377 fd = open (filename, O_WRONLY|O_CREAT, 0600);
378 if (fd < 0)
379 {
380 builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
381 return (EXECUTION_FAILURE);
382 }
383 close (fd);
384 }
385 result = append_history (history_lines_this_session, filename);
386 history_lines_in_file += history_lines_this_session;
387 history_lines_this_session = 0;
388 }
389 return (result);
390 }
391
392 /* If this is an interactive shell, then append the lines executed
393 this session to the history file. */
394 int
395 maybe_save_shell_history ()
396 {
397 int result;
398 char *hf;
399
400 result = 0;
401 if (history_lines_this_session)
402 {
403 hf = get_string_value ("HISTFILE");
404
405 if (hf && *hf)
406 {
407 /* If the file doesn't exist, then create it. */
408 if (file_exists (hf) == 0)
409 {
410 int file;
411 file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
412 if (file != -1)
413 close (file);
414 }
415
416 /* Now actually append the lines if the history hasn't been
417 stifled. If the history has been stifled, rewrite the
418 history file. */
419 using_history ();
420 if (history_lines_this_session <= where_history () || force_append_history)
421 {
422 result = append_history (history_lines_this_session, hf);
423 history_lines_in_file += history_lines_this_session;
424 }
425 else
426 {
427 result = write_history (hf);
428 history_lines_in_file = history_lines_this_session;
429 }
430 history_lines_this_session = 0;
431
432 sv_histsize ("HISTFILESIZE");
433 }
434 }
435 return (result);
436 }
437
438 #if defined (READLINE)
439 /* Tell readline () that we have some text for it to edit. */
440 static void
441 re_edit (text)
442 char *text;
443 {
444 if (bash_input.type == st_stdin)
445 bash_re_edit (text);
446 }
447 #endif /* READLINE */
448
449 /* Return 1 if this line needs history expansion. */
450 static int
451 history_expansion_p (line)
452 char *line;
453 {
454 register char *s;
455
456 for (s = line; *s; s++)
457 if (*s == history_expansion_char || *s == history_subst_char)
458 return 1;
459 return 0;
460 }
461
462 /* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
463 print the results of expanding the line if there were any changes.
464 If there is an error, return NULL, otherwise the expanded line is
465 returned. If ADDIT is non-zero the line is added to the history
466 list after history expansion. ADDIT is just a suggestion;
467 REMEMBER_ON_HISTORY can veto, and does.
468 Right now this does history expansion. */
469 char *
470 pre_process_line (line, print_changes, addit)
471 char *line;
472 int print_changes, addit;
473 {
474 char *history_value;
475 char *return_value;
476 int expanded;
477
478 return_value = line;
479 expanded = 0;
480
481 # if defined (BANG_HISTORY)
482 /* History expand the line. If this results in no errors, then
483 add that line to the history if ADDIT is non-zero. */
484 if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
485 {
486 expanded = history_expand (line, &history_value);
487
488 if (expanded)
489 {
490 if (print_changes)
491 {
492 if (expanded < 0)
493 internal_error ("%s", history_value);
494 #if defined (READLINE)
495 else if (hist_verify == 0 || expanded == 2)
496 #else
497 else
498 #endif
499 fprintf (stderr, "%s\n", history_value);
500 }
501
502 /* If there was an error, return NULL. */
503 if (expanded < 0 || expanded == 2) /* 2 == print only */
504 {
505 # if defined (READLINE)
506 if (expanded == 2 && rl_dispatching == 0 && *history_value)
507 # else
508 if (expanded == 2 && *history_value)
509 # endif /* !READLINE */
510 maybe_add_history (history_value);
511
512 free (history_value);
513
514 # if defined (READLINE)
515 /* New hack. We can allow the user to edit the
516 failed history expansion. */
517 if (history_reediting && expanded < 0 && rl_done)
518 re_edit (line);
519 # endif /* READLINE */
520 return ((char *)NULL);
521 }
522
523 # if defined (READLINE)
524 if (hist_verify && expanded == 1)
525 {
526 re_edit (history_value);
527 return ((char *)NULL);
528 }
529 # endif
530 }
531
532 /* Let other expansions know that return_value can be free'ed,
533 and that a line has been added to the history list. Note
534 that we only add lines that have something in them. */
535 expanded = 1;
536 return_value = history_value;
537 }
538 # endif /* BANG_HISTORY */
539
540 if (addit && remember_on_history && *return_value)
541 maybe_add_history (return_value);
542
543 #if 0
544 if (expanded == 0)
545 return_value = savestring (line);
546 #endif
547
548 return (return_value);
549 }
550
551 /* Return 1 if the first non-whitespace character in LINE is a `#', indicating
552 * that the line is a shell comment. */
553 static int
554 shell_comment (line)
555 char *line;
556 {
557 char *p;
558
559 for (p = line; p && *p && whitespace (*p); p++)
560 ;
561 return (p && *p == '#');
562 }
563
564 #ifdef INCLUDE_UNUSED
565 /* Remove shell comments from LINE. A `#' and anything after it is a comment.
566 This isn't really useful yet, since it doesn't handle quoting. */
567 static char *
568 filter_comments (line)
569 char *line;
570 {
571 char *p;
572
573 for (p = line; p && *p && *p != '#'; p++)
574 ;
575 if (p && *p == '#')
576 *p = '\0';
577 return (line);
578 }
579 #endif
580
581 /* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
582 should be saved; 0 if it should be discarded. */
583 static int
584 check_history_control (line)
585 char *line;
586 {
587 HIST_ENTRY *temp;
588 int r;
589
590 if (history_control == 0)
591 return 1;
592
593 /* ignorespace or ignoreboth */
594 if ((history_control & HC_IGNSPACE) && *line == ' ')
595 return 0;
596
597 /* ignoredups or ignoreboth */
598 if (history_control & HC_IGNDUPS)
599 {
600 using_history ();
601 temp = previous_history ();
602
603 r = (temp == 0 || STREQ (temp->line, line) == 0);
604
605 using_history ();
606
607 if (r == 0)
608 return r;
609 }
610
611 return 1;
612 }
613
614 /* Remove all entries matching LINE from the history list. Triggered when
615 HISTCONTROL includes `erasedups'. */
616 static void
617 hc_erasedups (line)
618 char *line;
619 {
620 HIST_ENTRY *temp;
621 int r;
622
623 using_history ();
624 while (temp = previous_history ())
625 {
626 if (STREQ (temp->line, line))
627 {
628 r = where_history ();
629 remove_history (r);
630 }
631 }
632 using_history ();
633 }
634
635 /* Add LINE to the history list, handling possibly multi-line compound
636 commands. We note whether or not we save the first line of each command
637 (which is usually the entire command and history entry), and don't add
638 the second and subsequent lines of a multi-line compound command if we
639 didn't save the first line. We don't usually save shell comment lines in
640 compound commands in the history, because they could have the effect of
641 commenting out the rest of the command when the entire command is saved as
642 a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
643 LITERAL_HISTORY is set, we're saving lines in the history with embedded
644 newlines, so it's OK to save comment lines. We also make sure to save
645 multiple-line quoted strings or other constructs. */
646 void
647 maybe_add_history (line)
648 char *line;
649 {
650 hist_last_line_added = 0;
651
652 /* Don't use the value of history_control to affect the second
653 and subsequent lines of a multi-line command (old code did
654 this only when command_oriented_history is enabled). */
655 if (current_command_line_count > 1)
656 {
657 if (current_command_first_line_saved &&
658 (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
659 bash_add_history (line);
660 return;
661 }
662
663 /* This is the first line of a (possible multi-line) command. Note whether
664 or not we should save the first line and remember it. */
665 current_command_first_line_saved = check_add_history (line, 0);
666 }
667
668 /* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
669 history if it's OK. Used by `history -s' as well as maybe_add_history().
670 Returns 1 if the line was saved in the history, 0 otherwise. */
671 int
672 check_add_history (line, force)
673 char *line;
674 int force;
675 {
676 if (check_history_control (line) && history_should_ignore (line) == 0)
677 {
678 /* We're committed to saving the line. If the user has requested it,
679 remove other matching lines from the history. */
680 if (history_control & HC_ERASEDUPS)
681 hc_erasedups (line);
682
683 if (force)
684 {
685 really_add_history (line);
686 using_history ();
687 }
688 else
689 bash_add_history (line);
690 return 1;
691 }
692 return 0;
693 }
694
695 /* Add a line to the history list.
696 The variable COMMAND_ORIENTED_HISTORY controls the style of history
697 remembering; when non-zero, and LINE is not the first line of a
698 complete parser construct, append LINE to the last history line instead
699 of adding it as a new line. */
700 void
701 bash_add_history (line)
702 char *line;
703 {
704 int add_it, offset, curlen;
705 HIST_ENTRY *current, *old;
706 char *chars_to_add, *new_line;
707
708 add_it = 1;
709 if (command_oriented_history && current_command_line_count > 1)
710 {
711 chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
712
713 using_history ();
714 current = previous_history ();
715
716 if (current)
717 {
718 /* If the previous line ended with an escaped newline (escaped
719 with backslash, but otherwise unquoted), then remove the quoted
720 newline, since that is what happens when the line is parsed. */
721 curlen = strlen (current->line);
722
723 if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
724 current->line[curlen - 2] != '\\')
725 {
726 current->line[curlen - 1] = '\0';
727 curlen--;
728 chars_to_add = "";
729 }
730
731 new_line = (char *)xmalloc (1
732 + curlen
733 + strlen (line)
734 + strlen (chars_to_add));
735 sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
736 offset = where_history ();
737 old = replace_history_entry (offset, new_line, current->data);
738 free (new_line);
739
740 if (old)
741 free_history_entry (old);
742
743 add_it = 0;
744 }
745 }
746
747 if (add_it)
748 really_add_history (line);
749
750 using_history ();
751 }
752
753 static void
754 really_add_history (line)
755 char *line;
756 {
757 hist_last_line_added = 1;
758 hist_last_line_pushed = 0;
759 add_history (line);
760 history_lines_this_session++;
761 }
762
763 int
764 history_number ()
765 {
766 using_history ();
767 return (remember_on_history ? history_base + where_history () : 1);
768 }
769
770 static int
771 should_expand (s)
772 char *s;
773 {
774 char *p;
775
776 for (p = s; p && *p; p++)
777 {
778 if (*p == '\\')
779 p++;
780 else if (*p == '&')
781 return 1;
782 }
783 return 0;
784 }
785
786 static int
787 histignore_item_func (ign)
788 struct ign *ign;
789 {
790 if (should_expand (ign->val))
791 ign->flags |= HIGN_EXPAND;
792 return (0);
793 }
794
795 void
796 setup_history_ignore (varname)
797 char *varname;
798 {
799 setup_ignore_patterns (&histignore);
800 }
801
802 static HIST_ENTRY *
803 last_history_entry ()
804 {
805 HIST_ENTRY *he;
806
807 using_history ();
808 he = previous_history ();
809 using_history ();
810 return he;
811 }
812
813 char *
814 last_history_line ()
815 {
816 HIST_ENTRY *he;
817
818 he = last_history_entry ();
819 if (he == 0)
820 return ((char *)NULL);
821 return he->line;
822 }
823
824 static char *
825 expand_histignore_pattern (pat)
826 char *pat;
827 {
828 HIST_ENTRY *phe;
829 char *ret;
830
831 phe = last_history_entry ();
832
833 if (phe == (HIST_ENTRY *)0)
834 return (savestring (pat));
835
836 ret = strcreplace (pat, '&', phe->line, 1);
837
838 return ret;
839 }
840
841 /* Return 1 if we should not put LINE into the history according to the
842 patterns in HISTIGNORE. */
843 static int
844 history_should_ignore (line)
845 char *line;
846 {
847 register int i, match;
848 char *npat;
849
850 if (histignore.num_ignores == 0)
851 return 0;
852
853 for (i = match = 0; i < histignore.num_ignores; i++)
854 {
855 if (histignore.ignores[i].flags & HIGN_EXPAND)
856 npat = expand_histignore_pattern (histignore.ignores[i].val);
857 else
858 npat = histignore.ignores[i].val;
859
860 match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
861
862 if (histignore.ignores[i].flags & HIGN_EXPAND)
863 free (npat);
864
865 if (match)
866 break;
867 }
868
869 return match;
870 }
871 #endif /* HISTORY */