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"
15 #include <boost/assert.hpp>
25 # define S_IRUSR S_IREAD
27 # define S_IRUSR 00400
33 # define S_IWUSR S_IWRITE
35 # define S_IWUSR 00200
41 # define S_IXUSR S_IEXEC
43 # define S_IXUSR 00100
47 #ifdef STAT_MACROS_BROKEN
60 #if !defined(S_ISBLK) && defined(S_IFBLK)
61 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
63 #if !defined(S_ISCHR) && defined(S_IFCHR)
64 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
66 #if !defined(S_ISDIR) && defined(S_IFDIR)
67 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
69 #if !defined(S_ISREG) && defined(S_IFREG)
70 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
72 #if !defined(S_ISFIFO) && defined(S_IFIFO)
73 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
75 #if !defined(S_ISLNK) && defined(S_IFLNK)
76 #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
78 #if !defined(S_ISSOCK) && defined(S_IFSOCK)
79 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
81 #if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
82 #define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
83 #define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
85 #if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
86 #define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
92 // builds 'rwx' string describing file access rights
93 void flagRWX(mode_t i, char * str)
95 str[0] = (i & S_IRUSR) ? 'r' : '-';
96 str[1] = (i & S_IWUSR) ? 'w' : '-';
97 str[2] = (i & S_IXUSR) ? 'x' : '-';
100 // updates mode string to match suid/sgid/sticky bits
101 void setSticky(mode_t i, char * str)
105 str[3] = (str[3] == 'x') ? 's' : 'S';
109 str[6] = (str[6] == 'x') ? 's' : 'S';
113 str[9] = (str[9] == 'x') ? 's' : 'S';
117 // returns a letter describing a file type (ls style)
118 char typeLetter(mode_t i)
121 if (S_ISBLK(i)) return 'b';
123 if (S_ISCHR(i)) return 'c';
124 if (S_ISDIR(i)) return 'd';
125 if (S_ISREG(i)) return '-';
127 if (S_ISFIFO(i)) return 'p';
130 if (S_ISLNK(i)) return 'l';
133 if (S_ISSOCK(i)) return 's';
136 if (S_ISMPC(i)) return 'm';
139 if (S_ISNWK(i)) return 'n';
157 FileInfo::FileInfo(string const & path, bool link)
165 FileInfo::FileInfo(int fildes)
168 status_ = fstat(fildes, &buf_);
174 void FileInfo::init()
181 void FileInfo::dostat(bool link)
184 status_ = ::lstat(fname_.c_str(), &buf_);
186 status_ = ::stat(fname_.c_str(), &buf_);
192 FileInfo & FileInfo::newFile(string const & path, bool link)
202 FileInfo & FileInfo::newFile(int fildes)
206 status_ = fstat(fildes, &buf_);
213 // should not be in FileInfo
214 char FileInfo::typeIndicator() const
216 BOOST_ASSERT(isOK());
217 if (S_ISDIR(buf_.st_mode))
220 if (S_ISLNK(buf_.st_mode))
224 if (S_ISFIFO(buf_.st_mode))
228 if (S_ISSOCK(buf_.st_mode))
231 if (S_ISREG(buf_.st_mode) && (buf_.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH)))
237 mode_t FileInfo::getMode() const
239 BOOST_ASSERT(isOK());
244 // should not be in FileInfo
245 string FileInfo::modeString() const
247 BOOST_ASSERT(isOK());
249 str[0] = typeLetter(buf_.st_mode);
250 flagRWX((buf_.st_mode & 0700) << 0, &str[1]);
251 flagRWX((buf_.st_mode & 0070) << 3, &str[4]);
252 flagRWX((buf_.st_mode & 0007) << 6, &str[7]);
253 setSticky(buf_.st_mode, str);
260 time_t FileInfo::getModificationTime() const
262 BOOST_ASSERT(isOK());
263 return buf_.st_mtime;
267 time_t FileInfo::getAccessTime() const
269 BOOST_ASSERT(isOK());
270 return buf_.st_atime;
274 time_t FileInfo::getStatusChangeTime() const
276 BOOST_ASSERT(isOK());
277 return buf_.st_ctime;
281 nlink_t FileInfo::getNumberOfLinks() const
283 BOOST_ASSERT(isOK());
284 return buf_.st_nlink;
288 uid_t FileInfo::getUid() const
290 BOOST_ASSERT(isOK());
295 gid_t FileInfo::getGid() const
297 BOOST_ASSERT(isOK());
302 off_t FileInfo::getSize() const
304 BOOST_ASSERT(isOK());
309 int FileInfo::getError() const
315 bool FileInfo::isOK() const
321 bool FileInfo::isLink() const
323 BOOST_ASSERT(isOK());
324 return S_ISLNK(buf_.st_mode);
328 bool FileInfo::isRegular() const
330 BOOST_ASSERT(isOK());
331 return S_ISREG(buf_.st_mode);
335 bool FileInfo::isDir() const
337 BOOST_ASSERT(isOK());
338 return S_ISDIR(buf_.st_mode);
342 bool FileInfo::isChar() const
344 BOOST_ASSERT(isOK());
345 return S_ISCHR(buf_.st_mode);
349 bool FileInfo::isBlock() const
351 BOOST_ASSERT(isOK());
352 return S_ISBLK(buf_.st_mode);
356 bool FileInfo::isFifo() const
358 BOOST_ASSERT(isOK());
359 return S_ISFIFO(buf_.st_mode);
363 bool FileInfo::isSocket() const
365 BOOST_ASSERT(isOK());
367 return S_ISSOCK(buf_.st_mode);
374 // should not be in FileInfo
375 bool FileInfo::access(int p) const
377 // if we don't have a filename we fail
381 // If we were really kind, we would also tell why
382 // the file access failed.
383 return ::access(fname_.c_str(), p) == 0;
386 } // namespace support