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