Mercurial > hg > octave-lyh
annotate liboctave/file-stat.cc @ 7705:e9b9f74e0289
Fix stat'ing root pathnames ('\' or '/') under Win32.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Wed, 09 Apr 2008 13:12:27 -0400 |
parents | a1dbe9d80eee |
children | 424ba638d8f1 7cc783e52ddb |
rev | line source |
---|---|
2926 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2005, 2006, 2007 |
4 John W. Eaton | |
2926 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2926 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY 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 | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2926 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <cerrno> | |
29 #include <cstring> | |
30 | |
31 #ifdef HAVE_UNISTD_H | |
32 #ifdef HAVE_SYS_TYPES_H | |
33 #include <sys/types.h> | |
34 #endif | |
35 #include <unistd.h> | |
36 #endif | |
37 | |
5871 | 38 #include "file-ops.h" |
2926 | 39 #include "file-stat.h" |
40 #include "statdefs.h" | |
41 | |
3141 | 42 #if !defined (HAVE_LSTAT) |
43 static inline int | |
44 lstat (const char *name, struct stat *buf) | |
45 { | |
46 return stat (name, buf); | |
47 } | |
48 #endif | |
2926 | 49 |
5775 | 50 // FIXME -- the is_* and mode_as_string functions are only valid |
2926 | 51 // for initialized objects. If called for an object that is not |
52 // initialized, they should throw an exception. | |
53 | |
54 bool | |
55 file_stat::is_blk (void) const | |
56 { | |
5476 | 57 return is_blk (fs_mode); |
2926 | 58 } |
59 | |
60 bool | |
61 file_stat::is_chr (void) const | |
62 { | |
5476 | 63 return is_chr (fs_mode); |
2926 | 64 } |
65 | |
66 bool | |
67 file_stat::is_dir (void) const | |
68 { | |
5476 | 69 return is_dir (fs_mode); |
70 } | |
71 | |
72 bool | |
73 file_stat::is_fifo (void) const | |
74 { | |
75 return is_fifo (fs_mode); | |
76 } | |
77 | |
78 bool | |
79 file_stat::is_lnk (void) const | |
80 { | |
81 return is_lnk (fs_mode); | |
82 } | |
83 | |
84 bool | |
85 file_stat::is_reg (void) const | |
86 { | |
87 return is_reg (fs_mode); | |
88 } | |
89 | |
90 bool | |
91 file_stat::is_sock (void) const | |
92 { | |
93 return is_sock (fs_mode); | |
94 } | |
95 | |
96 bool | |
97 file_stat::is_blk (mode_t mode) | |
98 { | |
99 #ifdef S_ISBLK | |
100 return S_ISBLK (mode); | |
2926 | 101 #else |
102 return false; | |
103 #endif | |
104 } | |
105 | |
106 bool | |
5476 | 107 file_stat::is_chr (mode_t mode) |
108 { | |
109 #ifdef S_ISCHR | |
110 return S_ISCHR (mode); | |
111 #else | |
112 return false; | |
113 #endif | |
114 } | |
115 | |
116 bool | |
117 file_stat::is_dir (mode_t mode) | |
2926 | 118 { |
5476 | 119 #ifdef S_ISDIR |
120 return S_ISDIR (mode); | |
2926 | 121 #else |
122 return false; | |
123 #endif | |
124 } | |
125 | |
126 bool | |
5476 | 127 file_stat::is_fifo (mode_t mode) |
2926 | 128 { |
5476 | 129 #ifdef S_ISFIFO |
130 return S_ISFIFO (mode); | |
2926 | 131 #else |
132 return false; | |
133 #endif | |
134 } | |
135 | |
136 bool | |
5476 | 137 file_stat::is_lnk (mode_t mode) |
2926 | 138 { |
5476 | 139 #ifdef S_ISLNK |
140 return S_ISLNK (mode); | |
2926 | 141 #else |
142 return false; | |
143 #endif | |
144 } | |
145 | |
146 bool | |
5476 | 147 file_stat::is_reg (mode_t mode) |
148 { | |
149 #ifdef S_ISREG | |
150 return S_ISREG (mode); | |
151 #else | |
152 return false; | |
153 #endif | |
154 } | |
155 | |
156 bool | |
157 file_stat::is_sock (mode_t mode) | |
2926 | 158 { |
159 #ifdef S_ISSOCK | |
5476 | 160 return S_ISSOCK (mode); |
2926 | 161 #else |
162 return false; | |
163 #endif | |
164 } | |
165 | |
3504 | 166 extern "C" void mode_string (unsigned short, char *); |
2926 | 167 |
3504 | 168 std::string |
2926 | 169 file_stat::mode_as_string (void) const |
170 { | |
171 char buf[11]; | |
172 | |
173 mode_string (fs_mode, buf); | |
174 | |
175 buf[10] = '\0'; | |
176 | |
3504 | 177 return std::string (buf); |
2926 | 178 } |
179 | |
180 // Has FILE been modified since TIME? Returns 1 for yes, 0 for no, | |
181 // and -1 for any error. | |
182 | |
183 int | |
3504 | 184 file_stat::is_newer (const std::string& file, const octave_time& time) |
2926 | 185 { |
186 file_stat fs (file); | |
187 | |
188 return fs ? fs.is_newer (time) : -1; | |
189 } | |
190 | |
191 // Private stuff: | |
192 | |
193 void | |
194 file_stat::update_internal (bool force) | |
195 { | |
196 if (! initialized || force) | |
197 { | |
198 initialized = false; | |
199 fail = false; | |
5871 | 200 |
201 std::string full_file_name = file_ops::tilde_expand (file_name); | |
2926 | 202 |
6810 | 203 #if defined (__WIN32__) |
204 // Remove trailing slash. | |
205 if (file_ops::is_dir_sep (full_file_name[full_file_name.length () - 1]) | |
7705
e9b9f74e0289
Fix stat'ing root pathnames ('\' or '/') under Win32.
Michael Goffioul <michael.goffioul@gmail.com>
parents:
7017
diff
changeset
|
206 && full_file_name.length () != 1 |
6810 | 207 && ! (full_file_name.length() == 3 && full_file_name[1] == ':')) |
208 full_file_name.resize (full_file_name.length () - 1); | |
209 #endif | |
210 | |
5871 | 211 const char *cname = full_file_name.c_str (); |
2926 | 212 |
213 struct stat buf; | |
214 | |
3141 | 215 int status = follow_links ? stat (cname, &buf) : lstat (cname, &buf); |
2926 | 216 |
217 if (status < 0) | |
218 { | |
3504 | 219 using namespace std; |
220 | |
2926 | 221 fail = true; |
222 errmsg = strerror (errno); | |
223 } | |
224 else | |
225 { | |
226 fs_mode = buf.st_mode; | |
227 fs_ino = buf.st_ino; | |
228 fs_dev = buf.st_dev; | |
229 fs_nlink = buf.st_nlink; | |
230 fs_uid = buf.st_uid; | |
231 fs_gid = buf.st_gid; | |
232 fs_size = buf.st_size; | |
233 fs_atime = buf.st_atime; | |
234 fs_mtime = buf.st_mtime; | |
235 fs_ctime = buf.st_ctime; | |
236 | |
3887 | 237 #if defined (HAVE_STRUCT_STAT_ST_RDEV) |
2926 | 238 fs_rdev = buf.st_rdev; |
239 #endif | |
240 | |
3887 | 241 #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE) |
2926 | 242 fs_blksize = buf.st_blksize; |
243 #endif | |
244 | |
3887 | 245 #if defined (HAVE_STRUCT_STAT_ST_BLOCKS) |
2926 | 246 fs_blocks = buf.st_blocks; |
247 #endif | |
248 } | |
249 | |
250 initialized = true; | |
251 } | |
252 } | |
253 | |
254 void | |
255 file_stat::copy (const file_stat& fs) | |
256 { | |
257 file_name = fs.file_name; | |
258 follow_links = fs.follow_links; | |
259 initialized = fs.initialized; | |
260 fail = fs.fail; | |
261 errmsg = fs.errmsg; | |
262 fs_mode = fs.fs_mode; | |
263 fs_ino = fs.fs_ino; | |
264 fs_dev = fs.fs_dev; | |
265 fs_nlink = fs.fs_nlink; | |
266 fs_uid = fs.fs_uid; | |
267 fs_gid = fs.fs_gid; | |
268 fs_size = fs.fs_size; | |
269 fs_atime = fs.fs_atime; | |
270 fs_mtime = fs.fs_mtime; | |
271 fs_ctime = fs.fs_ctime; | |
272 | |
3887 | 273 #if defined (HAVE_STRUCT_STAT_ST_RDEV) |
2926 | 274 fs_rdev = fs.fs_rdev; |
275 #endif | |
276 | |
3887 | 277 #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE) |
2926 | 278 fs_blksize = fs.fs_blksize; |
279 #endif | |
280 | |
3887 | 281 #if defined (HAVE_STRUCT_STAT_ST_BLOCKS) |
2926 | 282 fs_blocks = fs.fs_blocks; |
283 #endif | |
284 } | |
285 | |
286 /* | |
287 ;;; Local Variables: *** | |
288 ;;; mode: C++ *** | |
289 ;;; End: *** | |
290 */ |