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 | ||