3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
13 #include "support/FileInfo.h"
14 #include "support/lstrings.h"
16 #include <boost/assert.hpp>
19 #include <sys/types.h>
28 # define S_IRUSR S_IREAD
30 # define S_IRUSR 00400
36 # define S_IWUSR S_IWRITE
38 # define S_IWUSR 00200
44 # define S_IXUSR S_IEXEC
46 # define S_IXUSR 00100
50 #ifdef STAT_MACROS_BROKEN
63 #if !defined(S_ISBLK) && defined(S_IFBLK)
64 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
66 #if !defined(S_ISCHR) && defined(S_IFCHR)
67 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
69 #if !defined(S_ISDIR) && defined(S_IFDIR)
70 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
72 #if !defined(S_ISREG) && defined(S_IFREG)
73 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
75 #if !defined(S_ISFIFO) && defined(S_IFIFO)
76 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
78 #if !defined(S_ISLNK) && defined(S_IFLNK)
79 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
81 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
82 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
84 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
85 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
86 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
88 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
89 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
95 // builds 'rwx' string describing file access rights
96 void flagRWX(mode_t i, char * str)
98 str[0] = (i & S_IRUSR) ? 'r' : '-';
99 str[1] = (i & S_IWUSR) ? 'w' : '-';
100 str[2] = (i & S_IXUSR) ? 'x' : '-';
103 // updates mode string to match suid/sgid/sticky bits
104 void setSticky(mode_t i, char * str)
108 str[3] = (str[3] == 'x') ? 's' : 'S';
112 str[6] = (str[6] == 'x') ? 's' : 'S';
116 str[9] = (str[9] == 'x') ? 's' : 'S';
120 // returns a letter describing a file type (ls style)
121 char typeLetter(mode_t i)
124 if (S_ISBLK(i)) return 'b';
126 if (S_ISCHR(i)) return 'c';
127 if (S_ISDIR(i)) return 'd';
128 if (S_ISREG(i)) return '-';
130 if (S_ISFIFO(i)) return 'p';
133 if (S_ISLNK(i)) return 'l';
136 if (S_ISSOCK(i)) return 's';
139 if (S_ISMPC(i)) return 'm';
142 if (S_ISNWK(i)) return 'n';
159 FileInfo::FileInfo(string const & path, bool link)
160 // Win32 stat() doesn't dig trailing slashes.
161 // Posix stat() doesn't care, but we'll remove it anyway.
162 : fname_(rtrim(path, "/"))
169 FileInfo::FileInfo(int fildes)
172 status_ = fstat(fildes, &buf_);
178 void FileInfo::init()
185 void FileInfo::dostat(bool link)
189 status_ = ::lstat(fname_.c_str(), &buf_);
191 status_ = ::stat(fname_.c_str(), &buf_);
193 status_ = ::stat(fname_.c_str(), &buf_);
201 FileInfo & FileInfo::newFile(string const & path, bool link)
203 // Win32 stat() doesn't dig trailing slashes.
204 // Posix stat() doesn't care, but we'll remove it anyway.
205 fname_ = rtrim(path, "/");
213 FileInfo & FileInfo::newFile(int fildes)
217 status_ = fstat(fildes, &buf_);
224 // should not be in FileInfo
225 char FileInfo::typeIndicator() const
227 BOOST_ASSERT(isOK());
228 if (S_ISDIR(buf_.st_mode))
231 if (S_ISLNK(buf_.st_mode))
235 if (S_ISFIFO(buf_.st_mode))
239 if (S_ISSOCK(buf_.st_mode))
246 mode_t FileInfo::getMode() const
248 BOOST_ASSERT(isOK());
253 // should not be in FileInfo
254 string FileInfo::modeString() const
256 BOOST_ASSERT(isOK());
258 str[0] = typeLetter(buf_.st_mode);
259 flagRWX((buf_.st_mode & 0700) << 0, &str[1]);
260 flagRWX((buf_.st_mode & 0070) << 3, &str[4]);
261 flagRWX((buf_.st_mode & 0007) << 6, &str[7]);
262 setSticky(buf_.st_mode, str);
269 time_t FileInfo::getModificationTime() const
271 BOOST_ASSERT(isOK());
272 return buf_.st_mtime;
276 time_t FileInfo::getAccessTime() const
278 BOOST_ASSERT(isOK());
279 return buf_.st_atime;
283 time_t FileInfo::getStatusChangeTime() const
285 BOOST_ASSERT(isOK());
286 return buf_.st_ctime;
290 uid_t FileInfo::getUid() const
292 BOOST_ASSERT(isOK());
297 gid_t FileInfo::getGid() const
299 BOOST_ASSERT(isOK());
304 off_t FileInfo::getSize() const
306 BOOST_ASSERT(isOK());
311 int FileInfo::getError() const
317 bool FileInfo::isOK() const
323 bool FileInfo::isLink() const
325 BOOST_ASSERT(isOK());
327 return S_ISLNK(buf_.st_mode);
334 bool FileInfo::isRegular() const
336 BOOST_ASSERT(isOK());
337 return S_ISREG(buf_.st_mode);
341 bool FileInfo::isDir() const
343 BOOST_ASSERT(isOK());
344 return S_ISDIR(buf_.st_mode);
348 bool FileInfo::isChar() const
350 BOOST_ASSERT(isOK());
351 return S_ISCHR(buf_.st_mode);
355 bool FileInfo::isBlock() const
357 BOOST_ASSERT(isOK());
358 return S_ISBLK(buf_.st_mode);
362 bool FileInfo::isFifo() const
364 BOOST_ASSERT(isOK());
365 return S_ISFIFO(buf_.st_mode);
369 bool FileInfo::isSocket() const
371 BOOST_ASSERT(isOK());
373 return S_ISSOCK(buf_.st_mode);
380 // should not be in FileInfo
381 bool FileInfo::access(int p) const
383 // if we don't have a filename we fail
387 // If we were really kind, we would also tell why
388 // the file access failed.
389 return ::access(fname_.c_str(), p) == 0;
392 } // namespace support