]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/portability/file_system.cpp
import stlplus 3.7
[chaz/yoink] / src / stlplus / portability / file_system.cpp
index 983d98483ac92d8285d8e44df41a008fe69524e2..cac32927e30adf39e7513891bb022235e54ab879 100644 (file)
@@ -2,7 +2,7 @@
 \r
 //   Author:    Andy Rushton\r
 //   Copyright: (c) Southampton University 1999-2004\r
-//              (c) Andy Rushton           2004-2009\r
+//              (c) Andy Rushton           2004 onwards\r
 //   License:   BSD License, see ../docs/license.html\r
 \r
 //   This is a portable interface to the file system.\r
 #include <direct.h>\r
 #include <fcntl.h>\r
 #include <io.h>\r
-#include <sys/stat.h>\r
 #include <sys/types.h>\r
+#include <sys/stat.h>\r
 #else\r
 #include <dirent.h>\r
 #include <fcntl.h>\r
 #include <sys/param.h>\r
 #include <unistd.h>\r
-#include <sys/stat.h>\r
 #include <sys/types.h>\r
+#include <sys/stat.h>\r
 #endif\r
 \r
 ////////////////////////////////////////////////////////////////////////////////\r
@@ -406,10 +406,60 @@ namespace stlplus
 ////////////////////////////////////////////////////////////////////////////////\r
 // classifying functions\r
 \r
+// Under both Windows and Unix, the stat function is used for classification\r
+\r
+// Under Linux, the following classifications are defined\r
+// source: Linux man page for stat(2) http://linux.die.net/man/2/stat\r
+//   S_IFMT    0170000 bitmask for the file type bitfields\r
+//   S_IFSOCK  0140000 socket (Note this overlaps with S_IFDIR)\r
+//   S_IFLNK   0120000 symbolic link\r
+//   S_IFREG   0100000 regular file\r
+//   S_IFBLK   0060000 block device\r
+//   S_IFDIR   0040000 directory\r
+//   S_IFCHR   0020000 character device\r
+//   S_IFIFO   0010000 FIFO\r
+// There are also some Posix-standard macros:\r
+//   S_ISREG(m)        is it a regular file? \r
+//   S_ISDIR(m)        directory? \r
+//   S_ISCHR(m)        character device? \r
+//   S_ISBLK(m)        block device? \r
+//   S_ISFIFO(m)       FIFO (named pipe)? \r
+//   S_ISLNK(m)        symbolic link? (Not in POSIX.1-1996.) \r
+//   S_ISSOCK(m)       socket? (Not in POSIX.1-1996.)\r
+// Under Windows, the following are defined:\r
+// source: Header file sys/stat.h distributed with Visual Studio 10\r
+//   _S_IFMT  (S_IFMT)   0xF000 file type mask\r
+//   _S_IFREG (S_IFREG)  0x8000 regular\r
+//   _S_IFDIR (S_IFDIR)  0x4000 directory\r
+//   _S_IFCHR (S_IFCHR)  0x2000 character special\r
+//   _S_IFIFO            0x1000 pipe\r
+\r
 #ifdef MSWINDOWS\r
 // file type tests are not defined for some reason on Windows despite them providing the stat() function!\r
 #define R_OK 4\r
 #define W_OK 2\r
+// Posix-style macros for Windows\r
+#ifndef S_ISREG\r
+#define S_ISREG(mode)  ((mode & _S_IFMT) == _S_IFREG)\r
+#endif\r
+#ifndef S_ISDIR\r
+#define S_ISDIR(mode)  ((mode & _S_IFMT) == _S_IFDIR)\r
+#endif\r
+#ifndef S_ISCHR\r
+#define S_ISCHR(mode)  ((mode & _S_IFMT) == _S_IFCHR)\r
+#endif\r
+#ifndef S_ISBLK\r
+#define S_ISBLK(mode)  (false)\r
+#endif\r
+#ifndef S_ISFIFO\r
+#define S_ISFIFO(mode) ((mode & _S_IFMT) == _S_IFIFO)\r
+#endif\r
+#ifndef S_ISLNK\r
+#define S_ISLNK(mode)  (false)\r
+#endif\r
+#ifndef S_ISSOCK\r
+#define S_ISSOCK(mode) (false)\r
+#endif\r
 #endif\r
 \r
   bool is_present (const std::string& thing)\r
@@ -431,8 +481,11 @@ namespace stlplus
       path.erase(path.size()-1,1);\r
     // now test if this thing exists using the built-in stat function and if so, is it a folder\r
     struct stat buf;\r
-    if (!(stat(path.c_str(), &buf) == 0)) {return false;}\r
-    return (buf.st_mode & S_IFDIR) != 0;\r
+    if (!(stat(path.c_str(), &buf) == 0))\r
+      return false;\r
+    // If the object is present, see if it is a directory\r
+    // this is the Posix-approved way of testing\r
+    return S_ISDIR(buf.st_mode);\r
   }\r
 \r
   bool is_file (const std::string& thing)\r
@@ -443,8 +496,12 @@ namespace stlplus
       path.erase(path.size()-1,1);\r
     // now test if this thing exists using the built-in stat function and if so, is it a file\r
     struct stat buf;\r
-    if (!(stat(path.c_str(), &buf) == 0)) {return false;}\r
-    return (buf.st_mode & S_IFREG) != 0;\r
+    if (!(stat(path.c_str(), &buf) == 0))\r
+      return false;\r
+    // If the object is present, see if it is a file or file-like object\r
+    // Note that devices are neither folders nor files\r
+    // this is the Posix-approved way of testing\r
+    return S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode) || S_ISSOCK(buf.st_mode) || S_ISFIFO(buf.st_mode);\r
   }\r
 \r
 ////////////////////////////////////////////////////////////////////////////////\r
@@ -464,7 +521,8 @@ namespace stlplus
 \r
   bool file_writable (const std::string& filespec)\r
   {\r
-    // a file is writable if it exists as a file and is writable or if it doesn't exist but could be created and would be writable\r
+    // a file is writable if it exists as a file and is writable or if\r
+    // it doesn't exist but could be created and would be writable\r
     if (is_present(filespec))\r
     {\r
       if (!is_file(filespec)) return false;\r
@@ -707,8 +765,13 @@ namespace stlplus
     return std::string(_fullpath(abspath, ".", MAX_PATH+1));\r
 #else\r
     char pathname [MAXPATHLEN+1];\r
-    getcwd(pathname,MAXPATHLEN+1);\r
-    return std::string(pathname);\r
+    char* result = getcwd(pathname,MAXPATHLEN+1);\r
+    if (!result)\r
+    {\r
+      // should really report the error from errno\r
+      return std::string();\r
+    }\r
+    return std::string(result);\r
 #endif\r
   }\r
 \r
This page took 0.019833 seconds and 4 git commands to generate.