Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/bash/src/hashcmd.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* hashcmd.c - functions for managing a hash table mapping command names to | - | ||||||||||||
2 | full pathnames. */ | - | ||||||||||||
3 | - | |||||||||||||
4 | /* Copyright (C) 1997-2009 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 | - | ||||||||||||
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. | - | ||||||||||||
12 | - | |||||||||||||
13 | Bash 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. | - | ||||||||||||
17 | - | |||||||||||||
18 | You should have received a copy of the GNU General Public License | - | ||||||||||||
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | - | ||||||||||||
20 | */ | - | ||||||||||||
21 | - | |||||||||||||
22 | #include <config.h> | - | ||||||||||||
23 | - | |||||||||||||
24 | #include "bashtypes.h" | - | ||||||||||||
25 | #include "posixstat.h" | - | ||||||||||||
26 | - | |||||||||||||
27 | #if defined (HAVE_UNISTD_H) | - | ||||||||||||
28 | # include <unistd.h> | - | ||||||||||||
29 | #endif | - | ||||||||||||
30 | - | |||||||||||||
31 | #include "bashansi.h" | - | ||||||||||||
32 | - | |||||||||||||
33 | #include "shell.h" | - | ||||||||||||
34 | #include "flags.h" | - | ||||||||||||
35 | #include "findcmd.h" | - | ||||||||||||
36 | #include "hashcmd.h" | - | ||||||||||||
37 | - | |||||||||||||
38 | HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL; | - | ||||||||||||
39 | - | |||||||||||||
40 | static void phash_freedata __P((PTR_T)); | - | ||||||||||||
41 | - | |||||||||||||
42 | void | - | ||||||||||||
43 | phash_create () | - | ||||||||||||
44 | { | - | ||||||||||||
45 | if (hashed_filenames == 0)
| 0-1632 | ||||||||||||
46 | hashed_filenames = hash_create (FILENAME_HASH_BUCKETS); executed 1632 times by 1 test: hashed_filenames = hash_create (64); Executed by:
| 1632 | ||||||||||||
47 | } executed 1632 times by 1 test: end of block Executed by:
| 1632 | ||||||||||||
48 | - | |||||||||||||
49 | static void | - | ||||||||||||
50 | phash_freedata (data) | - | ||||||||||||
51 | PTR_T data; | - | ||||||||||||
52 | { | - | ||||||||||||
53 | free (((PATH_DATA *)data)->path); | - | ||||||||||||
54 | free (data); | - | ||||||||||||
55 | } executed 29 times by 1 test: end of block Executed by:
| 29 | ||||||||||||
56 | - | |||||||||||||
57 | void | - | ||||||||||||
58 | phash_flush () | - | ||||||||||||
59 | { | - | ||||||||||||
60 | if (hashed_filenames)
| 41-51 | ||||||||||||
61 | hash_flush (hashed_filenames, phash_freedata); executed 41 times by 1 test: hash_flush (hashed_filenames, phash_freedata); Executed by:
| 41 | ||||||||||||
62 | } executed 92 times by 1 test: end of block Executed by:
| 92 | ||||||||||||
63 | - | |||||||||||||
64 | /* Remove FILENAME from the table of hashed commands. */ | - | ||||||||||||
65 | int | - | ||||||||||||
66 | phash_remove (filename) | - | ||||||||||||
67 | const char *filename; | - | ||||||||||||
68 | { | - | ||||||||||||
69 | register BUCKET_CONTENTS *item; | - | ||||||||||||
70 | - | |||||||||||||
71 | if (hashing_enabled == 0 || hashed_filenames == 0)
| 0-13 | ||||||||||||
72 | return 0; executed 12 times by 1 test: return 0; Executed by:
| 12 | ||||||||||||
73 | - | |||||||||||||
74 | item = hash_remove (filename, hashed_filenames, 0); | - | ||||||||||||
75 | if (item)
| 0-1 | ||||||||||||
76 | { | - | ||||||||||||
77 | if (item->data)
| 0 | ||||||||||||
78 | phash_freedata (item->data); never executed: phash_freedata (item->data); | 0 | ||||||||||||
79 | free (item->key); | - | ||||||||||||
80 | free (item); | - | ||||||||||||
81 | return 0; never executed: return 0; | 0 | ||||||||||||
82 | } | - | ||||||||||||
83 | return 1; executed 1 time by 1 test: return 1; Executed by:
| 1 | ||||||||||||
84 | } | - | ||||||||||||
85 | - | |||||||||||||
86 | /* Place FILENAME (key) and FULL_PATH (data->path) into the | - | ||||||||||||
87 | hash table. CHECK_DOT if non-null is for future calls to | - | ||||||||||||
88 | phash_search (); it means that this file was found | - | ||||||||||||
89 | in a directory in $PATH that is not an absolute pathname. | - | ||||||||||||
90 | FOUND is the initial value for times_found. */ | - | ||||||||||||
91 | void | - | ||||||||||||
92 | phash_insert (filename, full_path, check_dot, found) | - | ||||||||||||
93 | char *filename, *full_path; | - | ||||||||||||
94 | int check_dot, found; | - | ||||||||||||
95 | { | - | ||||||||||||
96 | register BUCKET_CONTENTS *item; | - | ||||||||||||
97 | - | |||||||||||||
98 | if (hashing_enabled == 0)
| 0-5290 | ||||||||||||
99 | return; never executed: return; | 0 | ||||||||||||
100 | - | |||||||||||||
101 | if (hashed_filenames == 0)
| 1632-3658 | ||||||||||||
102 | phash_create (); executed 1632 times by 1 test: phash_create (); Executed by:
| 1632 | ||||||||||||
103 | - | |||||||||||||
104 | item = hash_insert (filename, hashed_filenames, 0); | - | ||||||||||||
105 | if (item->data)
| 2-5288 | ||||||||||||
106 | free (pathdata(item)->path); executed 2 times by 1 test: sh_xfree((((PATH_DATA *)(item)->data)->path), "hashcmd.c", 106); Executed by:
| 2 | ||||||||||||
107 | else | - | ||||||||||||
108 | { | - | ||||||||||||
109 | item->key = savestring (filename); | - | ||||||||||||
110 | item->data = xmalloc (sizeof (PATH_DATA)); | - | ||||||||||||
111 | } executed 5288 times by 1 test: end of block Executed by:
| 5288 | ||||||||||||
112 | pathdata(item)->path = savestring (full_path); | - | ||||||||||||
113 | pathdata(item)->flags = 0; | - | ||||||||||||
114 | if (check_dot)
| 109-5181 | ||||||||||||
115 | pathdata(item)->flags |= HASH_CHKDOT; executed 5181 times by 1 test: ((PATH_DATA *)(item)->data)->flags |= 0x02; Executed by:
| 5181 | ||||||||||||
116 | if (*full_path != '/')
| 249-5041 | ||||||||||||
117 | pathdata(item)->flags |= HASH_RELPATH; executed 249 times by 1 test: ((PATH_DATA *)(item)->data)->flags |= 0x01; Executed by:
| 249 | ||||||||||||
118 | item->times_found = found; | - | ||||||||||||
119 | } executed 5290 times by 1 test: end of block Executed by:
| 5290 | ||||||||||||
120 | - | |||||||||||||
121 | /* Return the full pathname that FILENAME hashes to. If FILENAME | - | ||||||||||||
122 | is hashed, but (data->flags & HASH_CHKDOT) is non-zero, check | - | ||||||||||||
123 | ./FILENAME and return that if it is executable. This always | - | ||||||||||||
124 | returns a newly-allocated string; the caller is responsible | - | ||||||||||||
125 | for freeing it. */ | - | ||||||||||||
126 | char * | - | ||||||||||||
127 | phash_search (filename) | - | ||||||||||||
128 | const char *filename; | - | ||||||||||||
129 | { | - | ||||||||||||
130 | register BUCKET_CONTENTS *item; | - | ||||||||||||
131 | char *path, *dotted_filename, *tail; | - | ||||||||||||
132 | int same; | - | ||||||||||||
133 | - | |||||||||||||
134 | if (hashing_enabled == 0 || hashed_filenames == 0)
| 0-26869 | ||||||||||||
135 | return ((char *)NULL); executed 1686 times by 1 test: return ((char *) ((void *)0) ); Executed by:
| 1686 | ||||||||||||
136 | - | |||||||||||||
137 | item = hash_search (filename, hashed_filenames, 0); | - | ||||||||||||
138 | - | |||||||||||||
139 | if (item == NULL)
| 3696-21487 | ||||||||||||
140 | return ((char *)NULL); executed 3696 times by 1 test: return ((char *) ((void *)0) ); Executed by:
| 3696 | ||||||||||||
141 | - | |||||||||||||
142 | /* If this filename is hashed, but `.' comes before it in the path, | - | ||||||||||||
143 | see if ./filename is executable. If the hashed value is not an | - | ||||||||||||
144 | absolute pathname, see if ./`hashed-value' exists. */ | - | ||||||||||||
145 | path = pathdata(item)->path; | - | ||||||||||||
146 | if (pathdata(item)->flags & (HASH_CHKDOT|HASH_RELPATH))
| 18-21469 | ||||||||||||
147 | { | - | ||||||||||||
148 | tail = (pathdata(item)->flags & HASH_RELPATH) ? path : (char *)filename; /* XXX - fix const later */
| 4906-16563 | ||||||||||||
149 | /* If the pathname does not start with a `./', add a `./' to it. */ | - | ||||||||||||
150 | if (tail[0] != '.' || tail[1] != '/')
| 0-16563 | ||||||||||||
151 | { | - | ||||||||||||
152 | dotted_filename = (char *)xmalloc (3 + strlen (tail)); | - | ||||||||||||
153 | dotted_filename[0] = '.'; dotted_filename[1] = '/'; | - | ||||||||||||
154 | strcpy (dotted_filename + 2, tail); | - | ||||||||||||
155 | } executed 16563 times by 1 test: end of block Executed by:
| 16563 | ||||||||||||
156 | else | - | ||||||||||||
157 | dotted_filename = savestring (tail); executed 4906 times by 1 test: dotted_filename = (char *)strcpy (sh_xmalloc((1 + strlen (tail)), "hashcmd.c", 157), (tail)); Executed by:
| 4906 | ||||||||||||
158 | - | |||||||||||||
159 | if (executable_file (dotted_filename))
| 4916-16553 | ||||||||||||
160 | return (dotted_filename); executed 4916 times by 1 test: return (dotted_filename); Executed by:
| 4916 | ||||||||||||
161 | - | |||||||||||||
162 | free (dotted_filename); | - | ||||||||||||
163 | - | |||||||||||||
164 | #if 0 | - | ||||||||||||
165 | if (pathdata(item)->flags & HASH_RELPATH) | - | ||||||||||||
166 | return ((char *)NULL); | - | ||||||||||||
167 | #endif | - | ||||||||||||
168 | - | |||||||||||||
169 | /* Watch out. If this file was hashed to "./filename", and | - | ||||||||||||
170 | "./filename" is not executable, then return NULL. */ | - | ||||||||||||
171 | - | |||||||||||||
172 | /* Since we already know "./filename" is not executable, what | - | ||||||||||||
173 | we're really interested in is whether or not the `path' | - | ||||||||||||
174 | portion of the hashed filename is equivalent to the current | - | ||||||||||||
175 | directory, but only if it starts with a `.'. (This catches | - | ||||||||||||
176 | ./. and so on.) same_file () tests general Unix file | - | ||||||||||||
177 | equivalence -- same device and inode. */ | - | ||||||||||||
178 | if (*path == '.')
| 2-16551 | ||||||||||||
179 | { | - | ||||||||||||
180 | same = 0; | - | ||||||||||||
181 | tail = (char *)strrchr (path, '/'); | - | ||||||||||||
182 | - | |||||||||||||
183 | if (tail)
| 0-2 | ||||||||||||
184 | { | - | ||||||||||||
185 | *tail = '\0'; | - | ||||||||||||
186 | same = same_file (".", path, (struct stat *)NULL, (struct stat *)NULL); | - | ||||||||||||
187 | *tail = '/'; | - | ||||||||||||
188 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||
189 | - | |||||||||||||
190 | return same ? (char *)NULL : savestring (path); executed 2 times by 1 test: return same ? (char *) ((void *)0) : (char *)strcpy (sh_xmalloc((1 + strlen (path)), "hashcmd.c", 190), (path)); Executed by:
| 2 | ||||||||||||
191 | } | - | ||||||||||||
192 | } executed 16551 times by 1 test: end of block Executed by:
| 16551 | ||||||||||||
193 | - | |||||||||||||
194 | return (savestring (path)); executed 16569 times by 1 test: return ((char *)strcpy (sh_xmalloc((1 + strlen (path)), "hashcmd.c", 194), (path))); Executed by:
| 16569 | ||||||||||||
195 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |