aboutsummaryrefslogtreecommitdiff
path: root/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp')
-rwxr-xr-xsrc/3rdParty/efsw/platform/posix/FileSystemImpl.cpp251
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
59namespace efsw { namespace Platform {
60
61#if EFSW_OS == EFSW_OS_LINUX
62
63std::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
106done:
107 FileSystem::changeWorkingDirectory( cwd );
108
109 return mp;
110}
111
112std::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
138bool 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
154bool FileSystem::changeWorkingDirectory( const std::string& path ) {
155 return -1 != chdir( path.c_str() );
156}
157
158std::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
164FileInfoMap 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
187char FileSystem::getOSSlash() {
188 return '/';
189}
190
191bool 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
202bool 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