Mercurial > hg > octave-jordi > gnulib-hg
annotate lib/stat.c @ 18079:4c948fd76734 default tip master
autoupdate
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Mon, 24 Aug 2015 06:09:19 -0700 |
parents | ab58d4870664 |
children |
rev | line source |
---|---|
12036 | 1 /* Work around platform bugs in stat. |
17848 | 2 Copyright (C) 2009-2015 Free Software Foundation, Inc. |
12036 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
16 | |
17 /* written by Eric Blake */ | |
18 | |
15538
9fd857e43955
Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents:
15314
diff
changeset
|
19 /* If the user's config.h happens to include <sys/stat.h>, let it include only |
9fd857e43955
Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents:
15314
diff
changeset
|
20 the system's <sys/stat.h> here, so that orig_stat doesn't recurse to |
9fd857e43955
Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents:
15314
diff
changeset
|
21 rpl_stat. */ |
9fd857e43955
Avoid endless recursions if config.h includes some header files.
Bruno Haible <bruno@clisp.org>
parents:
15314
diff
changeset
|
22 #define __need_system_sys_stat_h |
12036 | 23 #include <config.h> |
24 | |
12037 | 25 /* Get the original definition of stat. It might be defined as a macro. */ |
26 #include <sys/types.h> | |
27 #include <sys/stat.h> | |
28 #undef __need_system_sys_stat_h | |
29 | |
16795
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
30 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
31 # if _GL_WINDOWS_64_BIT_ST_SIZE |
16917
d7028e1986c1
stat, fstat: Avoid warnings on mingw64.
Bruno Haible <bruno@clisp.org>
parents:
16795
diff
changeset
|
32 # undef stat /* avoid warning on mingw64 with _FILE_OFFSET_BITS=64 */ |
16795
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
33 # define stat _stati64 |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
34 # define REPLACE_FUNC_STAT_DIR 1 |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
35 # undef REPLACE_FUNC_STAT_FILE |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
36 # elif REPLACE_FUNC_STAT_FILE |
16781
f3d643af663d
stat: Bypass buggy override in mingw64.
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
37 /* mingw64 has a broken stat() function, based on _stat(), in libmingwex.a. |
f3d643af663d
stat: Bypass buggy override in mingw64.
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
38 Bypass it. */ |
16795
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
39 # define stat _stat |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
40 # define REPLACE_FUNC_STAT_DIR 1 |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
41 # undef REPLACE_FUNC_STAT_FILE |
6a9ea5d7b466
Large File Support for native Windows platforms.
Bruno Haible <bruno@clisp.org>
parents:
16781
diff
changeset
|
42 # endif |
16781
f3d643af663d
stat: Bypass buggy override in mingw64.
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
43 #endif |
f3d643af663d
stat: Bypass buggy override in mingw64.
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
44 |
17187
4cd6b652c293
fflush, stat: no 'static inline'
Paul Eggert <eggert@cs.ucla.edu>
parents:
16917
diff
changeset
|
45 static int |
12037 | 46 orig_stat (const char *filename, struct stat *buf) |
47 { | |
48 return stat (filename, buf); | |
49 } | |
50 | |
51 /* Specification. */ | |
15583
716e67b8d5a9
openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents:
15538
diff
changeset
|
52 /* Write "sys/stat.h" here, not <sys/stat.h>, otherwise OSF/1 5.1 DTK cc |
716e67b8d5a9
openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents:
15538
diff
changeset
|
53 eliminates this include because of the preliminary #include <sys/stat.h> |
716e67b8d5a9
openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents:
15538
diff
changeset
|
54 above. */ |
716e67b8d5a9
openat: Work around compilation error with OSF/1 5.1 DTK cc.
Bruno Haible <bruno@clisp.org>
parents:
15538
diff
changeset
|
55 #include "sys/stat.h" |
12036 | 56 |
57 #include <errno.h> | |
58 #include <limits.h> | |
59 #include <stdbool.h> | |
60 #include <string.h> | |
14393
9f47f8c334f2
dirname: move m4/dos.m4 functionality into lib/dosname.h
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
61 #include "dosname.h" |
15314
517a0b73b86b
stat: be robust to PATH_MAX definition
Eric Blake <eblake@redhat.com>
parents:
14393
diff
changeset
|
62 #include "verify.h" |
12036 | 63 |
15658
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
64 #if REPLACE_FUNC_STAT_DIR |
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
65 # include "pathmax.h" |
15659
bdf397bc4086
* lib/stat.c: Move comment.
Paul Eggert <eggert@cs.ucla.edu>
parents:
15658
diff
changeset
|
66 /* The only known systems where REPLACE_FUNC_STAT_DIR is needed also |
bdf397bc4086
* lib/stat.c: Move comment.
Paul Eggert <eggert@cs.ucla.edu>
parents:
15658
diff
changeset
|
67 have a constant PATH_MAX. */ |
15658
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
68 # ifndef PATH_MAX |
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
69 # error "Please port this replacement to your platform" |
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
70 # endif |
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
71 #endif |
07e1173e4fc9
stat: use pathmax.h only if needed
Paul Eggert <eggert@cs.ucla.edu>
parents:
15612
diff
changeset
|
72 |
12037 | 73 /* Store information about NAME into ST. Work around bugs with |
74 trailing slashes. Mingw has other bugs (such as st_ino always | |
75 being 0 on success) which this wrapper does not work around. But | |
76 at least this implementation provides the ability to emulate fchdir | |
77 correctly. */ | |
12036 | 78 |
79 int | |
80 rpl_stat (char const *name, struct stat *st) | |
81 { | |
12037 | 82 int result = orig_stat (name, st); |
83 #if REPLACE_FUNC_STAT_FILE | |
84 /* Solaris 9 mistakenly succeeds when given a non-directory with a | |
85 trailing slash. */ | |
86 if (result == 0 && !S_ISDIR (st->st_mode)) | |
87 { | |
88 size_t len = strlen (name); | |
89 if (ISSLASH (name[len - 1])) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12037
diff
changeset
|
90 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12037
diff
changeset
|
91 errno = ENOTDIR; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12037
diff
changeset
|
92 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12037
diff
changeset
|
93 } |
12037 | 94 } |
95 #endif /* REPLACE_FUNC_STAT_FILE */ | |
96 #if REPLACE_FUNC_STAT_DIR | |
15314
517a0b73b86b
stat: be robust to PATH_MAX definition
Eric Blake <eblake@redhat.com>
parents:
14393
diff
changeset
|
97 |
12036 | 98 if (result == -1 && errno == ENOENT) |
99 { | |
100 /* Due to mingw's oddities, there are some directories (like | |
101 c:\) where stat() only succeeds with a trailing slash, and | |
102 other directories (like c:\windows) where stat() only | |
103 succeeds without a trailing slash. But we want the two to be | |
104 synonymous, since chdir() manages either style. Likewise, Mingw also | |
105 reports ENOENT for names longer than PATH_MAX, when we want | |
106 ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR. | |
107 Fortunately, mingw PATH_MAX is small enough for stack | |
108 allocation. */ | |
109 char fixed_name[PATH_MAX + 1] = {0}; | |
110 size_t len = strlen (name); | |
111 bool check_dir = false; | |
15314
517a0b73b86b
stat: be robust to PATH_MAX definition
Eric Blake <eblake@redhat.com>
parents:
14393
diff
changeset
|
112 verify (PATH_MAX <= 4096); |
12036 | 113 if (PATH_MAX <= len) |
114 errno = ENAMETOOLONG; | |
115 else if (len) | |
116 { | |
117 strcpy (fixed_name, name); | |
118 if (ISSLASH (fixed_name[len - 1])) | |
119 { | |
120 check_dir = true; | |
121 while (len && ISSLASH (fixed_name[len - 1])) | |
122 fixed_name[--len] = '\0'; | |
123 if (!len) | |
124 fixed_name[0] = '/'; | |
125 } | |
126 else | |
127 fixed_name[len++] = '/'; | |
12037 | 128 result = orig_stat (fixed_name, st); |
12036 | 129 if (result == 0 && check_dir && !S_ISDIR (st->st_mode)) |
130 { | |
131 result = -1; | |
132 errno = ENOTDIR; | |
133 } | |
134 } | |
135 } | |
12037 | 136 #endif /* REPLACE_FUNC_STAT_DIR */ |
12036 | 137 return result; |
138 } |