]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/hash.def
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / builtins / hash.def
CommitLineData
726f6388
JA
1This file is hash.def, from which is created hash.c.
2It implements the builtin "hash" in Bash.
3
4Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
bb70624e 10Software Foundation; either version 2, or (at your option) any later
726f6388
JA
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
bb70624e 20Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
726f6388
JA
21
22$PRODUCES hash.c
23
24$BUILTIN hash
25$FUNCTION hash_builtin
ccc6cda3 26$SHORT_DOC hash [-r] [-p pathname] [name ...]
726f6388 27For each NAME, the full pathname of the command is determined and
ccc6cda3
JA
28remembered. If the -p option is supplied, PATHNAME is used as the
29full pathname of NAME, and no path search is performed. The -r
30option causes the shell to forget all remembered locations. If no
31arguments are given, information about remembered commands is displayed.
726f6388
JA
32$END
33
ccc6cda3
JA
34#include <config.h>
35
726f6388
JA
36#include <stdio.h>
37
cce855bc
JA
38#include "../bashtypes.h"
39
ccc6cda3
JA
40#if defined (HAVE_UNISTD_H)
41# include <unistd.h>
42#endif
43
28ef6c31
JA
44#include <errno.h>
45
ccc6cda3 46#include "../bashansi.h"
726f6388
JA
47
48#include "../shell.h"
49#include "../builtins.h"
d166f048 50#include "../flags.h"
cce855bc 51#include "../findcmd.h"
d166f048 52#include "../hashcmd.h"
726f6388 53#include "common.h"
ccc6cda3 54#include "bashgetopt.h"
726f6388
JA
55
56extern int dot_found_in_search;
ccc6cda3
JA
57extern char *this_command_name;
58
59static int add_hashed_command ();
60static int print_hashed_commands ();
61
726f6388
JA
62/* Print statistics on the current state of hashed commands. If LIST is
63 not empty, then rehash (or hash in the first place) the specified
64 commands. */
ccc6cda3 65int
726f6388
JA
66hash_builtin (list)
67 WORD_LIST *list;
68{
ccc6cda3 69 int expunge_hash_table, opt;
cce855bc 70 char *w, *pathname;
726f6388 71
ccc6cda3 72 if (hashing_enabled == 0)
726f6388
JA
73 {
74 builtin_error ("hashing disabled");
75 return (EXECUTION_FAILURE);
76 }
77
ccc6cda3
JA
78 expunge_hash_table = 0;
79 pathname = (char *)NULL;
80 reset_internal_getopt ();
81 while ((opt = internal_getopt (list, "rp:")) != -1)
726f6388 82 {
ccc6cda3 83 switch (opt)
726f6388 84 {
ccc6cda3 85 case 'r':
726f6388 86 expunge_hash_table = 1;
726f6388 87 break;
ccc6cda3
JA
88 case 'p':
89 pathname = list_optarg;
90 break;
91 default:
92 builtin_usage ();
726f6388
JA
93 return (EX_USAGE);
94 }
726f6388 95 }
ccc6cda3 96 list = loptend;
726f6388
JA
97
98 /* We want hash -r to be silent, but hash -- to print hashing info. That
ccc6cda3
JA
99 is the reason for the test of expunge_hash_table. */
100 if (list == 0 && expunge_hash_table == 0)
726f6388 101 {
ccc6cda3
JA
102 if (print_hashed_commands () == 0)
103 printf ("%s: hash table empty\n", this_command_name);
726f6388
JA
104
105 return (EXECUTION_SUCCESS);
106 }
107
108 if (expunge_hash_table)
ccc6cda3 109 flush_hashed_filenames ();
726f6388 110
bb70624e
JA
111#if defined (RESTRICTED_SHELL)
112 if (restricted && pathname && strchr (pathname, '/'))
113 {
114 builtin_error ("%s: restricted", pathname);
115 return (EXECUTION_FAILURE);
116 }
117#endif
118
ccc6cda3 119 for (opt = EXECUTION_SUCCESS; list; list = list->next)
726f6388
JA
120 {
121 /* Add or rehash the specified commands. */
cce855bc 122 w = list->word->word;
ccc6cda3 123 if (pathname)
28ef6c31
JA
124 {
125 if (is_directory (pathname))
126 {
127#ifdef EISDIR
128 builtin_error ("%s: %s", pathname, strerror (EISDIR));
129#else
130 builtin_error ("%s: is a directory", pathname);
131#endif
132 opt = EXECUTION_FAILURE;
133 }
134 else
135 remember_filename (w, pathname, 0, 0);
136 }
cce855bc 137 else if (absolute_program (w))
d166f048 138 continue;
cce855bc 139 else if (add_hashed_command (w, 0))
d166f048 140 opt = EXECUTION_FAILURE;
726f6388
JA
141 }
142
143 fflush (stdout);
ccc6cda3 144 return (opt);
726f6388
JA
145}
146
ccc6cda3 147static int
cce855bc
JA
148add_hashed_command (w, quiet)
149 char *w;
ccc6cda3
JA
150 int quiet;
151{
152 int rv;
153 char *full_path;
154
155 rv = 0;
cce855bc 156 if (find_function (w) == 0 && find_shell_builtin (w) == 0)
ccc6cda3 157 {
cce855bc 158 full_path = find_user_command (w);
ccc6cda3 159 if (full_path && executable_file (full_path))
cce855bc 160 remember_filename (w, full_path, dot_found_in_search, 0);
ccc6cda3
JA
161 else
162 {
163 if (quiet == 0)
cce855bc 164 builtin_error ("%s: not found", w);
ccc6cda3
JA
165 rv++;
166 }
167 if (full_path)
168 free (full_path);
169 }
170 return (rv);
171}
172
173/* Print information about current hashed info. */
174static int
175print_hashed_commands ()
176{
177 BUCKET_CONTENTS *item_list;
178 int bucket, any_printed;
179
d166f048
JA
180 if (hashed_filenames == 0)
181 return (0);
182
ccc6cda3
JA
183 for (bucket = any_printed = 0; bucket < hashed_filenames->nbuckets; bucket++)
184 {
185 item_list = get_hash_bucket (bucket, hashed_filenames);
186 if (item_list == 0)
187 continue;
188
189 if (any_printed == 0)
190 {
191 printf ("hits\tcommand\n");
192 any_printed++;
193 }
194
195 for ( ; item_list; item_list = item_list->next)
196 printf ("%4d\t%s\n", item_list->times_found, pathdata(item_list)->path);
197
198 }
199 return (any_printed);
200}