2999
|
1 /* dir.c: directory operations. |
|
2 |
|
3 Copyright (C) 1992, 93, 94, 95 Free Software Foundation, Inc. |
|
4 |
|
5 This library is free software; you can redistribute it and/or |
|
6 modify it under the terms of the GNU Library General Public |
|
7 License as published by the Free Software Foundation; either |
|
8 version 2 of the License, or (at your option) any later version. |
|
9 |
|
10 This library is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 Library General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU Library General Public |
|
16 License along with this library; if not, write to the Free Software |
|
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|
18 |
|
19 #include <kpathsea/config.h> |
|
20 |
|
21 #include <kpathsea/c-dir.h> |
|
22 #include <kpathsea/c-stat.h> |
|
23 #include <kpathsea/hash.h> |
|
24 |
|
25 |
|
26 /* Return true if FN is a directory or a symlink to a directory, |
|
27 false if not. */ |
|
28 |
|
29 boolean |
|
30 dir_p P1C(const_string, fn) |
|
31 { |
|
32 struct stat stats; |
|
33 return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode); |
|
34 } |
|
35 |
|
36 |
|
37 /* Return -1 if FN isn't a directory, else its number of links. |
|
38 Duplicate the call to stat; no need to incur overhead of a function |
|
39 call for that little bit of cleanliness. */ |
|
40 |
|
41 int |
|
42 dir_links P1C(const_string, fn) |
|
43 { |
|
44 static hash_table_type link_table; |
|
45 string *hash_ret; |
|
46 long ret; |
|
47 |
|
48 if (link_table.size == 0) |
|
49 link_table = hash_create (457); |
|
50 |
|
51 #ifdef KPSE_DEBUG |
|
52 /* This is annoying, but since we're storing integers as pointers, we |
|
53 can't print them as strings. */ |
|
54 if (KPSE_DEBUG_P (KPSE_DEBUG_HASH)) |
|
55 kpse_debug_hash_lookup_int = true; |
|
56 #endif |
|
57 |
|
58 hash_ret = hash_lookup (link_table, fn); |
|
59 |
|
60 #ifdef KPSE_DEBUG |
|
61 if (KPSE_DEBUG_P (KPSE_DEBUG_HASH)) |
|
62 kpse_debug_hash_lookup_int = false; |
|
63 #endif |
|
64 |
|
65 /* Have to cast the int we need to/from the const_string that the hash |
|
66 table stores for values. Let's hope an int fits in a pointer. */ |
|
67 if (hash_ret) |
|
68 ret = (long) *hash_ret; |
|
69 else |
|
70 { |
|
71 struct stat stats; |
|
72 ret = stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode) |
|
73 ? stats.st_nlink : -1; |
|
74 |
|
75 /* It's up to us to copy the value. */ |
|
76 hash_insert (&link_table, xstrdup (fn), (const_string) ret); |
|
77 |
|
78 #ifdef KPSE_DEBUG |
|
79 if (KPSE_DEBUG_P (KPSE_DEBUG_STAT)) |
|
80 DEBUGF2 ("dir_links(%s) => %ld\n", fn, ret); |
|
81 #endif |
|
82 } |
|
83 |
|
84 return ret; |
|
85 } |