diff options
Diffstat (limited to 'src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp')
| -rwxr-xr-x | src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp b/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp new file mode 100755 index 0000000..92eeb47 --- /dev/null +++ b/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | #include <efsw/platform/posix/FileSystemImpl.hpp> | ||
| 2 | |||
| 3 | #if defined( EFSW_PLATFORM_POSIX ) | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | #include <dirent.h> | ||
| 7 | #include <efsw/FileInfo.hpp> | ||
| 8 | #include <efsw/FileSystem.hpp> | ||
| 9 | #include <unistd.h> | ||
| 10 | |||
| 11 | #ifndef _DARWIN_FEATURE_64_BIT_INODE | ||
| 12 | #define _DARWIN_FEATURE_64_BIT_INODE | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #ifndef _FILE_OFFSET_BITS | ||
| 16 | #define _FILE_OFFSET_BITS 64 | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #include <climits> | ||
| 20 | #include <cstdlib> | ||
| 21 | #include <sys/stat.h> | ||
| 22 | |||
| 23 | #if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID | ||
| 24 | #include <sys/vfs.h> | ||
| 25 | #elif EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || EFSW_OS == EFSW_OS_IOS | ||
| 26 | #include <sys/mount.h> | ||
| 27 | #include <sys/param.h> | ||
| 28 | #endif | ||
| 29 | |||
| 30 | /** Remote file systems codes */ | ||
| 31 | #define S_MAGIC_AFS 0x5346414F | ||
| 32 | #define S_MAGIC_AUFS 0x61756673 | ||
| 33 | #define S_MAGIC_CEPH 0x00C36400 | ||
| 34 | #define S_MAGIC_CIFS 0xFF534D42 | ||
| 35 | #define S_MAGIC_CODA 0x73757245 | ||
| 36 | #define S_MAGIC_FHGFS 0x19830326 | ||
| 37 | #define S_MAGIC_FUSEBLK 0x65735546 | ||
| 38 | #define S_MAGIC_FUSECTL 0x65735543 | ||
| 39 | #define S_MAGIC_GFS 0x01161970 | ||
| 40 | #define S_MAGIC_GPFS 0x47504653 | ||
| 41 | #define S_MAGIC_KAFS 0x6B414653 | ||
| 42 | #define S_MAGIC_LUSTRE 0x0BD00BD0 | ||
| 43 | #define S_MAGIC_NCP 0x564C | ||
| 44 | #define S_MAGIC_NFS 0x6969 | ||
| 45 | #define S_MAGIC_NFSD 0x6E667364 | ||
| 46 | #define S_MAGIC_OCFS2 0x7461636F | ||
| 47 | #define S_MAGIC_PANFS 0xAAD7AAEA | ||
| 48 | #define S_MAGIC_PIPEFS 0x50495045 | ||
| 49 | #define S_MAGIC_SMB 0x517B | ||
| 50 | #define S_MAGIC_SNFS 0xBEEFDEAD | ||
| 51 | #define S_MAGIC_VMHGFS 0xBACBACBC | ||
| 52 | #define S_MAGIC_VXFS 0xA501FCF5 | ||
| 53 | |||
| 54 | #if EFSW_OS == EFSW_OS_LINUX | ||
| 55 | #include <cstdio> | ||
| 56 | #include <mntent.h> | ||
| 57 | #endif | ||
| 58 | |||
| 59 | namespace efsw { namespace Platform { | ||
| 60 | |||
| 61 | #if EFSW_OS == EFSW_OS_LINUX | ||
| 62 | |||
| 63 | std::string findMountPoint( std::string file ) { | ||
| 64 | std::string cwd = FileSystem::getCurrentWorkingDirectory(); | ||
| 65 | struct stat last_stat; | ||
| 66 | struct stat file_stat; | ||
| 67 | |||
| 68 | stat( file.c_str(), &file_stat ); | ||
| 69 | |||
| 70 | std::string mp; | ||
| 71 | |||
| 72 | if ( efsw::FileSystem::isDirectory( file ) ) { | ||
| 73 | last_stat = file_stat; | ||
| 74 | |||
| 75 | if ( !FileSystem::changeWorkingDirectory( file ) ) | ||
| 76 | return ""; | ||
| 77 | } else { | ||
| 78 | std::string dir = efsw::FileSystem::pathRemoveFileName( file ); | ||
| 79 | |||
| 80 | if ( !FileSystem::changeWorkingDirectory( dir ) ) | ||
| 81 | return ""; | ||
| 82 | |||
| 83 | if ( stat( ".", &last_stat ) < 0 ) | ||
| 84 | return ""; | ||
| 85 | } | ||
| 86 | |||
| 87 | while ( true ) { | ||
| 88 | struct stat st; | ||
| 89 | |||
| 90 | if ( stat( "..", &st ) < 0 ) | ||
| 91 | goto done; | ||
| 92 | |||
| 93 | if ( st.st_dev != last_stat.st_dev || st.st_ino == last_stat.st_ino ) | ||
| 94 | break; | ||
| 95 | |||
| 96 | if ( !FileSystem::changeWorkingDirectory( ".." ) ) { | ||
| 97 | goto done; | ||
| 98 | } | ||
| 99 | |||
| 100 | last_stat = st; | ||
| 101 | } | ||
| 102 | |||
| 103 | /* Finally reached a mount point, see what it's called. */ | ||
| 104 | mp = FileSystem::getCurrentWorkingDirectory(); | ||
| 105 | |||
| 106 | done: | ||
| 107 | FileSystem::changeWorkingDirectory( cwd ); | ||
| 108 | |||
| 109 | return mp; | ||
| 110 | } | ||
| 111 | |||
| 112 | std::string findDevicePath( const std::string& directory ) { | ||
| 113 | struct mntent* ent; | ||
| 114 | FILE* aFile; | ||
| 115 | |||
| 116 | aFile = setmntent( "/proc/mounts", "r" ); | ||
| 117 | |||
| 118 | if ( aFile == NULL ) | ||
| 119 | return ""; | ||
| 120 | |||
| 121 | while ( NULL != ( ent = getmntent( aFile ) ) ) { | ||
| 122 | std::string dirName( ent->mnt_dir ); | ||
| 123 | |||
| 124 | if ( dirName == directory ) { | ||
| 125 | std::string fsName( ent->mnt_fsname ); | ||
| 126 | |||
| 127 | endmntent( aFile ); | ||
| 128 | |||
| 129 | return fsName; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | endmntent( aFile ); | ||
| 134 | |||
| 135 | return ""; | ||
| 136 | } | ||
| 137 | |||
| 138 | bool isLocalFUSEDirectory( std::string directory ) { | ||
| 139 | efsw::FileSystem::dirRemoveSlashAtEnd( directory ); | ||
| 140 | |||
| 141 | directory = findMountPoint( directory ); | ||
| 142 | |||
| 143 | if ( !directory.empty() ) { | ||
| 144 | std::string devicePath = findDevicePath( directory ); | ||
| 145 | |||
| 146 | return !devicePath.empty(); | ||
| 147 | } | ||
| 148 | |||
| 149 | return false; | ||
| 150 | } | ||
| 151 | |||
| 152 | #endif | ||
| 153 | |||
| 154 | bool FileSystem::changeWorkingDirectory( const std::string& path ) { | ||
| 155 | return -1 != chdir( path.c_str() ); | ||
| 156 | } | ||
| 157 | |||
| 158 | std::string FileSystem::getCurrentWorkingDirectory() { | ||
| 159 | char dir[PATH_MAX + 1]; | ||
| 160 | char* result = getcwd( dir, PATH_MAX + 1 ); | ||
| 161 | return result != NULL ? std::string( result ) : std::string(); | ||
| 162 | } | ||
| 163 | |||
| 164 | FileInfoMap FileSystem::filesInfoFromPath( const std::string& path ) { | ||
| 165 | FileInfoMap files; | ||
| 166 | |||
| 167 | DIR* dp; | ||
| 168 | struct dirent* dirp; | ||
| 169 | |||
| 170 | if ( ( dp = opendir( path.c_str() ) ) == NULL ) | ||
| 171 | return files; | ||
| 172 | |||
| 173 | while ( ( dirp = readdir( dp ) ) != NULL ) { | ||
| 174 | if ( strcmp( dirp->d_name, ".." ) != 0 && strcmp( dirp->d_name, "." ) != 0 ) { | ||
| 175 | std::string name( dirp->d_name ); | ||
| 176 | std::string fpath( path + name ); | ||
| 177 | |||
| 178 | files[name] = FileInfo( fpath ); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | closedir( dp ); | ||
| 183 | |||
| 184 | return files; | ||
| 185 | } | ||
| 186 | |||
| 187 | char FileSystem::getOSSlash() { | ||
| 188 | return '/'; | ||
| 189 | } | ||
| 190 | |||
| 191 | bool FileSystem::isDirectory( const std::string& path ) { | ||
| 192 | struct stat st; | ||
| 193 | int res = stat( path.c_str(), &st ); | ||
| 194 | |||
| 195 | if ( 0 == res ) { | ||
| 196 | return static_cast<bool>( S_ISDIR( st.st_mode ) ); | ||
| 197 | } | ||
| 198 | |||
| 199 | return false; | ||
| 200 | } | ||
| 201 | |||
| 202 | bool FileSystem::isRemoteFS( const std::string& directory ) { | ||
| 203 | #if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || \ | ||
| 204 | EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID || EFSW_OS == EFSW_OS_IOS | ||
| 205 | struct statfs statfsbuf; | ||
| 206 | |||
| 207 | statfs( directory.c_str(), &statfsbuf ); | ||
| 208 | |||
| 209 | switch ( statfsbuf.f_type | 0UL ) { | ||
| 210 | case S_MAGIC_FUSEBLK: /* 0x65735546 remote */ | ||
| 211 | { | ||
| 212 | #if EFSW_OS == EFSW_OS_LINUX | ||
| 213 | return !isLocalFUSEDirectory( directory ); | ||
| 214 | #endif | ||
| 215 | } | ||
| 216 | case S_MAGIC_AFS: /* 0x5346414F remote */ | ||
| 217 | case S_MAGIC_AUFS: /* 0x61756673 remote */ | ||
| 218 | case S_MAGIC_CEPH: /* 0x00C36400 remote */ | ||
| 219 | case S_MAGIC_CIFS: /* 0xFF534D42 remote */ | ||
| 220 | case S_MAGIC_CODA: /* 0x73757245 remote */ | ||
| 221 | case S_MAGIC_FHGFS: /* 0x19830326 remote */ | ||
| 222 | case S_MAGIC_FUSECTL: /* 0x65735543 remote */ | ||
| 223 | case S_MAGIC_GFS: /* 0x01161970 remote */ | ||
| 224 | case S_MAGIC_GPFS: /* 0x47504653 remote */ | ||
| 225 | case S_MAGIC_KAFS: /* 0x6B414653 remote */ | ||
| 226 | case S_MAGIC_LUSTRE: /* 0x0BD00BD0 remote */ | ||
| 227 | case S_MAGIC_NCP: /* 0x564C remote */ | ||
| 228 | case S_MAGIC_NFS: /* 0x6969 remote */ | ||
| 229 | case S_MAGIC_NFSD: /* 0x6E667364 remote */ | ||
| 230 | case S_MAGIC_OCFS2: /* 0x7461636F remote */ | ||
| 231 | case S_MAGIC_PANFS: /* 0xAAD7AAEA remote */ | ||
| 232 | case S_MAGIC_PIPEFS: /* 0x50495045 remote */ | ||
| 233 | case S_MAGIC_SMB: /* 0x517B remote */ | ||
| 234 | case S_MAGIC_SNFS: /* 0xBEEFDEAD remote */ | ||
| 235 | case S_MAGIC_VMHGFS: /* 0xBACBACBC remote */ | ||
| 236 | case S_MAGIC_VXFS: /* 0xA501FCF5 remote */ | ||
| 237 | { | ||
| 238 | return true; | ||
| 239 | } | ||
| 240 | default: { | ||
| 241 | return false; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | #endif | ||
| 245 | |||
| 246 | return false; | ||
| 247 | } | ||
| 248 | |||
| 249 | }} // namespace efsw::Platform | ||
| 250 | |||
| 251 | #endif | ||
