vsipreload.cpp
1 |
/******************************************************************************
|
---|---|
2 |
* $Id: vsipreload.cpp 27044 2014-03-16 23:41:27Z rouault $
|
3 |
*
|
4 |
* Project: CPL - Common Portability Library
|
5 |
* Purpose: Standalone shared library that can be LD_PRELOAD'ed as an overload of
|
6 |
* libc to enable VSI Virtual FILE API to be used with binaries using
|
7 |
* regular libc for I/O.
|
8 |
* Author: Even Rouault <even dot rouault at mines dash paris.org>
|
9 |
*
|
10 |
******************************************************************************
|
11 |
* Copyright (c) 2013, Even Rouault <even dot rouault at mines-paris dot org>
|
12 |
*
|
13 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
14 |
* copy of this software and associated documentation files (the "Software"),
|
15 |
* to deal in the Software without restriction, including without limitation
|
16 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
17 |
* and/or sell copies of the Software, and to permit persons to whom the
|
18 |
* Software is furnished to do so, subject to the following conditions:
|
19 |
*
|
20 |
* The above copyright notice and this permission notice shall be included
|
21 |
* in all copies or substantial portions of the Software.
|
22 |
*
|
23 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
24 |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
26 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
27 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
28 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
29 |
* DEALINGS IN THE SOFTWARE.
|
30 |
****************************************************************************/
|
31 |
|
32 |
// WARNING: Linux glibc ONLY
|
33 |
// Might work with some adaptations (mainly around 64bit symbols) on other Unix systems
|
34 |
|
35 |
// Compile:
|
36 |
// g++ -Wall -fPIC port/vsipreload.cpp -shared -o vsipreload.so -Iport -L. -L.libs -lgdal
|
37 |
|
38 |
// Run:
|
39 |
// LD_PRELOAD=./vsipreload.so ....
|
40 |
// e.g:
|
41 |
// LD_PRELOAD=./vsipreload.so gdalinfo /vsicurl/http://download.osgeo.org/gdal/data/ecw/spif83.ecw
|
42 |
// LD_PRELOAD=./vsipreload.so gdalinfo 'HDF4_EOS:EOS_GRID:"/vsicurl/http://download.osgeo.org/gdal/data/hdf4/MOD09Q1G_EVI.A2006233.h07v03.005.2008338190308.hdf":MODIS_NACP_EVI:MODIS_EVI'
|
43 |
// LD_PRELOAD=./vsipreload.so ogrinfo /vsicurl/http://svn.osgeo.org/gdal/trunk/autotest/ogr/data/testavc -ro
|
44 |
// even non GDAL binaries :
|
45 |
// LD_PRELOAD=./vsipreload.so h5dump -d /x /vsicurl/http://download.osgeo.org/gdal/data/netcdf/utm-big-chunks.nc
|
46 |
// LD_PRELOAD=./vsipreload.so sqlite3 /vsicurl/http://download.osgeo.org/gdal/data/sqlite3/polygon.db "select * from polygon limit 10"
|
47 |
// LD_PRELOAD=./vsipreload.so ls -al /vsicurl/http://download.osgeo.org/gdal/data/sqlite3
|
48 |
// LD_PRELOAD=./vsipreload.so find /vsicurl/http://download.osgeo.org/gdal/data/sqlite3
|
49 |
|
50 |
#define _GNU_SOURCE 1 |
51 |
#define _LARGEFILE64_SOURCE 1 |
52 |
#include <stdio.h> |
53 |
#include <stdlib.h> |
54 |
#include <assert.h> |
55 |
#include <dlfcn.h> |
56 |
#include <string.h> |
57 |
#include <fcntl.h> |
58 |
#include <unistd.h> |
59 |
#include <dirent.h> |
60 |
#include <sys/types.h> |
61 |
#include <sys/stat.h> |
62 |
|
63 |
#include <set> |
64 |
#include <map> |
65 |
#include <string> |
66 |
#include "cpl_vsi.h" |
67 |
#include "cpl_multiproc.h" |
68 |
#include "cpl_string.h" |
69 |
#include "cpl_hash_set.h" |
70 |
|
71 |
CPL_CVSID("$Id: vsipreload.cpp 27044 2014-03-16 23:41:27Z rouault $");
|
72 |
|
73 |
static int DEBUG_VSIPRELOAD = 0; |
74 |
static int DEBUG_VSIPRELOAD_ONLY_VSIL = 1; |
75 |
#define DEBUG_OUTPUT_READ 0 |
76 |
|
77 |
#ifndef NO_FSTATAT
|
78 |
#define HAVE_FSTATAT
|
79 |
#endif
|
80 |
|
81 |
#define DECLARE_SYMBOL(x, retType, args) \
|
82 |
typedef retType (*fn ## x ## Type)args;\ |
83 |
static fn ## x ## Type pfn ## x = NULL |
84 |
|
85 |
DECLARE_SYMBOL(fopen, FILE*, (const char *path, const char *mode)); |
86 |
DECLARE_SYMBOL(fopen64, FILE*, (const char *path, const char *mode)); |
87 |
DECLARE_SYMBOL(fread, size_t, (void *ptr, size_t size, size_t nmemb, FILE *stream));
|
88 |
DECLARE_SYMBOL(fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *stream)); |
89 |
DECLARE_SYMBOL(fclose, int, (FILE *stream));
|
90 |
DECLARE_SYMBOL(__xstat, int, (int ver, const char *path, struct stat *buf)); |
91 |
DECLARE_SYMBOL(__lxstat, int, (int ver, const char *path, struct stat *buf)); |
92 |
DECLARE_SYMBOL(__xstat64, int, (int ver, const char *path, struct stat64 *buf)); |
93 |
DECLARE_SYMBOL(fseeko64, int, (FILE *stream, off64_t off, int whence)); |
94 |
DECLARE_SYMBOL(fseek, int, (FILE *stream, off_t off, int whence)); |
95 |
DECLARE_SYMBOL(ftello64, off64_t, (FILE *stream)); |
96 |
DECLARE_SYMBOL(ftell, off_t, (FILE *stream)); |
97 |
DECLARE_SYMBOL(feof, int, (FILE *stream));
|
98 |
DECLARE_SYMBOL(fflush, int, (FILE *stream));
|
99 |
DECLARE_SYMBOL(fgetpos, int, (FILE *stream, fpos_t *pos));
|
100 |
DECLARE_SYMBOL(fsetpos, int, (FILE *stream, fpos_t *pos));
|
101 |
DECLARE_SYMBOL(fileno, int, (FILE *stream));
|
102 |
DECLARE_SYMBOL(ferror, int, (FILE *stream));
|
103 |
|
104 |
DECLARE_SYMBOL(fdopen, FILE*, (int fd, const char *mode)); |
105 |
DECLARE_SYMBOL(freopen, FILE*, (const char *path, const char *mode, FILE *stream)); |
106 |
|
107 |
DECLARE_SYMBOL(open, int, (const char *path, int flags, mode_t mode)); |
108 |
DECLARE_SYMBOL(open64, int, (const char *path, int flags, mode_t mode)); |
109 |
//DECLARE_SYMBOL(creat, int, (const char *path, mode_t mode));
|
110 |
DECLARE_SYMBOL(close, int, (int fd)); |
111 |
DECLARE_SYMBOL(read, ssize_t, (int fd, void *buf, size_t count)); |
112 |
DECLARE_SYMBOL(write, ssize_t, (int fd, const void *buf, size_t count)); |
113 |
DECLARE_SYMBOL(fsync, int, (int fd)); |
114 |
DECLARE_SYMBOL(fdatasync, int, (int fd)); |
115 |
DECLARE_SYMBOL(__fxstat, int, (int ver, int fd, struct stat *__stat_buf)); |
116 |
DECLARE_SYMBOL(__fxstat64, int, (int ver, int fd, struct stat64 *__stat_buf)); |
117 |
#ifdef HAVE_FSTATAT
|
118 |
DECLARE_SYMBOL(__fxstatat, int, (int ver, int dirfd, const char *pathname, struct stat *buf, int flags)); |
119 |
#endif
|
120 |
|
121 |
DECLARE_SYMBOL(lseek, off_t, (int fd, off_t off, int whence)); |
122 |
DECLARE_SYMBOL(lseek64, off64_t , (int fd, off64_t off, int whence)); |
123 |
|
124 |
DECLARE_SYMBOL(truncate, int, (const char *path, off_t length)); |
125 |
DECLARE_SYMBOL(ftruncate, int, (int fd, off_t length)); |
126 |
|
127 |
DECLARE_SYMBOL(opendir, DIR* , (const char *name)); |
128 |
DECLARE_SYMBOL(readdir, struct dirent*, (DIR *dirp));
|
129 |
DECLARE_SYMBOL(closedir, int, (DIR *dirp));
|
130 |
DECLARE_SYMBOL(dirfd, int, (DIR *dirp));
|
131 |
DECLARE_SYMBOL(fchdir, int, (int fd)); |
132 |
|
133 |
static void* hMutex = NULL; |
134 |
|
135 |
typedef struct |
136 |
{ |
137 |
char* pszDirname;
|
138 |
char** papszDir;
|
139 |
int nIter;
|
140 |
struct dirent ent;
|
141 |
int fd;
|
142 |
} VSIDIR; |
143 |
|
144 |
std::set<VSILFILE*> oSetFiles; |
145 |
std::map<int, VSILFILE*> oMapfdToVSI;
|
146 |
std::map<VSILFILE*, int> oMapVSITofd;
|
147 |
std::map<VSILFILE*, std::string> oMapVSIToString;
|
148 |
std::set<VSIDIR*> oSetVSIDIR; |
149 |
std::map<int, VSIDIR*> oMapfdToVSIDIR;
|
150 |
std::map<int, std::string> oMapDirFdToName; |
151 |
std::string osCurDir;
|
152 |
|
153 |
/************************************************************************/
|
154 |
/* myinit() */
|
155 |
/************************************************************************/
|
156 |
|
157 |
#define LOAD_SYMBOL(x) \
|
158 |
pfn ## x = (fn ## x ## Type) dlsym(RTLD_NEXT, #x); \ |
159 |
assert(pfn ## x) |
160 |
|
161 |
static void myinit(void) |
162 |
{ |
163 |
CPLMutexHolderD(&hMutex); |
164 |
|
165 |
if( pfnfopen64 != NULL ) return; |
166 |
DEBUG_VSIPRELOAD = getenv("DEBUG_VSIPRELOAD") != NULL; |
167 |
LOAD_SYMBOL(fopen); |
168 |
LOAD_SYMBOL(fopen64); |
169 |
LOAD_SYMBOL(fread); |
170 |
LOAD_SYMBOL(fwrite); |
171 |
LOAD_SYMBOL(fclose); |
172 |
LOAD_SYMBOL(fseeko64); |
173 |
LOAD_SYMBOL(fseek); |
174 |
LOAD_SYMBOL(__xstat); |
175 |
LOAD_SYMBOL(__lxstat); |
176 |
LOAD_SYMBOL(__xstat64); |
177 |
LOAD_SYMBOL(ftello64); |
178 |
LOAD_SYMBOL(ftell); |
179 |
LOAD_SYMBOL(feof); |
180 |
LOAD_SYMBOL(fflush); |
181 |
LOAD_SYMBOL(fgetpos); |
182 |
LOAD_SYMBOL(fsetpos); |
183 |
LOAD_SYMBOL(fileno); |
184 |
LOAD_SYMBOL(ferror); |
185 |
|
186 |
LOAD_SYMBOL(fdopen); |
187 |
LOAD_SYMBOL(freopen); |
188 |
|
189 |
LOAD_SYMBOL(open); |
190 |
LOAD_SYMBOL(open64); |
191 |
//LOAD_SYMBOL(creat);
|
192 |
LOAD_SYMBOL(close); |
193 |
LOAD_SYMBOL(read); |
194 |
LOAD_SYMBOL(write); |
195 |
LOAD_SYMBOL(fsync); |
196 |
LOAD_SYMBOL(fdatasync); |
197 |
LOAD_SYMBOL(__fxstat); |
198 |
LOAD_SYMBOL(__fxstat64); |
199 |
#ifdef HAVE_FSTATAT
|
200 |
LOAD_SYMBOL(__fxstatat); |
201 |
#endif
|
202 |
LOAD_SYMBOL(lseek); |
203 |
LOAD_SYMBOL(lseek64); |
204 |
|
205 |
LOAD_SYMBOL(truncate); |
206 |
LOAD_SYMBOL(ftruncate); |
207 |
|
208 |
LOAD_SYMBOL(opendir); |
209 |
LOAD_SYMBOL(readdir); |
210 |
LOAD_SYMBOL(closedir); |
211 |
LOAD_SYMBOL(dirfd); |
212 |
LOAD_SYMBOL(fchdir); |
213 |
} |
214 |
|
215 |
/************************************************************************/
|
216 |
/* getVSILFILE() */
|
217 |
/************************************************************************/
|
218 |
|
219 |
static VSILFILE* getVSILFILE(FILE* stream)
|
220 |
{ |
221 |
VSILFILE* ret; |
222 |
CPLMutexHolderD(&hMutex); |
223 |
std::set<VSILFILE*>::iterator oIter = oSetFiles.find((VSILFILE*)stream); |
224 |
if( oIter != oSetFiles.end() )
|
225 |
ret = *oIter; |
226 |
else
|
227 |
ret = NULL;
|
228 |
return ret;
|
229 |
} |
230 |
|
231 |
/************************************************************************/
|
232 |
/* getVSILFILE() */
|
233 |
/************************************************************************/
|
234 |
|
235 |
static VSILFILE* getVSILFILE(int fd) |
236 |
{ |
237 |
VSILFILE* ret; |
238 |
CPLMutexHolderD(&hMutex); |
239 |
std::map<int, VSILFILE*>::iterator oIter = oMapfdToVSI.find(fd);
|
240 |
if( oIter != oMapfdToVSI.end() )
|
241 |
ret = oIter->second; |
242 |
else
|
243 |
ret = NULL;
|
244 |
return ret;
|
245 |
} |
246 |
|
247 |
/************************************************************************/
|
248 |
/* VSIFSeekLHelper() */
|
249 |
/************************************************************************/
|
250 |
|
251 |
static int VSIFSeekLHelper(VSILFILE* fpVSIL, off64_t off, int whence) |
252 |
{ |
253 |
if( off < 0 && whence == SEEK_CUR ) |
254 |
{ |
255 |
return VSIFSeekL(fpVSIL, VSIFTellL(fpVSIL) + off, SEEK_SET);
|
256 |
} |
257 |
else if( off < 0 && whence == SEEK_END ) |
258 |
{ |
259 |
VSIFSeekL(fpVSIL, 0, SEEK_END);
|
260 |
return VSIFSeekL(fpVSIL, VSIFTellL(fpVSIL) + off, SEEK_SET);
|
261 |
} |
262 |
else
|
263 |
return VSIFSeekL(fpVSIL, off, whence);
|
264 |
} |
265 |
|
266 |
/************************************************************************/
|
267 |
/* VSIFopenHelper() */
|
268 |
/************************************************************************/
|
269 |
|
270 |
static VSILFILE* VSIFfopenHelper(const char *path, const char *mode) |
271 |
{ |
272 |
VSILFILE* fpVSIL = VSIFOpenL(path, mode); |
273 |
if( fpVSIL != NULL ) |
274 |
{ |
275 |
CPLMutexHolderD(&hMutex); |
276 |
oSetFiles.insert(fpVSIL); |
277 |
oMapVSIToString[fpVSIL] = path; |
278 |
} |
279 |
return fpVSIL;
|
280 |
} |
281 |
|
282 |
/************************************************************************/
|
283 |
/* getfdFromVSILFILE() */
|
284 |
/************************************************************************/
|
285 |
|
286 |
static int getfdFromVSILFILE(VSILFILE* fpVSIL) |
287 |
{ |
288 |
CPLMutexHolderD(&hMutex); |
289 |
|
290 |
int fd;
|
291 |
std::map<VSILFILE*, int>::iterator oIter = oMapVSITofd.find(fpVSIL);
|
292 |
if( oIter != oMapVSITofd.end() )
|
293 |
fd = oIter->second; |
294 |
else
|
295 |
{ |
296 |
fd = open("/dev/zero", O_RDONLY);
|
297 |
assert(fd >= 0);
|
298 |
oMapVSITofd[fpVSIL] = fd; |
299 |
oMapfdToVSI[fd] = fpVSIL; |
300 |
} |
301 |
return fd;
|
302 |
} |
303 |
|
304 |
/************************************************************************/
|
305 |
/* VSIFopenHelper() */
|
306 |
/************************************************************************/
|
307 |
|
308 |
static int VSIFopenHelper(const char *path, int flags) |
309 |
{ |
310 |
const char* pszMode = "rb"; |
311 |
if ((flags & 3) == O_RDONLY) |
312 |
pszMode = "rb";
|
313 |
else if ((flags & 3) == O_WRONLY) |
314 |
{ |
315 |
if( flags & O_APPEND )
|
316 |
pszMode = "ab";
|
317 |
else
|
318 |
pszMode = "wb";
|
319 |
} |
320 |
else
|
321 |
{ |
322 |
if( flags & O_APPEND )
|
323 |
pszMode = "ab+";
|
324 |
else
|
325 |
pszMode = "rb+";
|
326 |
} |
327 |
VSILFILE* fpVSIL = VSIFfopenHelper(path, pszMode ); |
328 |
int fd;
|
329 |
if( fpVSIL != NULL ) |
330 |
{ |
331 |
if( flags & O_TRUNC )
|
332 |
{ |
333 |
VSIFTruncateL(fpVSIL, 0);
|
334 |
VSIFSeekL(fpVSIL, 0, SEEK_SET);
|
335 |
} |
336 |
fd = getfdFromVSILFILE(fpVSIL); |
337 |
} |
338 |
else
|
339 |
fd = -1;
|
340 |
return fd;
|
341 |
} |
342 |
|
343 |
/************************************************************************/
|
344 |
/* GET_DEBUG_VSIPRELOAD_COND() */
|
345 |
/************************************************************************/
|
346 |
|
347 |
static int GET_DEBUG_VSIPRELOAD_COND(const char* path) |
348 |
{ |
349 |
return (DEBUG_VSIPRELOAD && (!DEBUG_VSIPRELOAD_ONLY_VSIL || strncmp(path, "/vsi", 4) == 0) ); |
350 |
} |
351 |
|
352 |
static int GET_DEBUG_VSIPRELOAD_COND(VSILFILE* fpVSIL) |
353 |
{ |
354 |
return (DEBUG_VSIPRELOAD && (!DEBUG_VSIPRELOAD_ONLY_VSIL || fpVSIL != NULL)); |
355 |
} |
356 |
|
357 |
static int GET_DEBUG_VSIPRELOAD_COND(VSIDIR* dirP) |
358 |
{ |
359 |
return (DEBUG_VSIPRELOAD && (!DEBUG_VSIPRELOAD_ONLY_VSIL || oSetVSIDIR.find(dirP) != oSetVSIDIR.end()));
|
360 |
} |
361 |
|
362 |
/************************************************************************/
|
363 |
/* copyVSIStatBufLToBuf() */
|
364 |
/************************************************************************/
|
365 |
|
366 |
static void copyVSIStatBufLToBuf(VSIStatBufL* bufSrc, struct stat *buf) |
367 |
{ |
368 |
buf->st_dev = bufSrc->st_dev; |
369 |
buf->st_ino = bufSrc->st_ino; |
370 |
buf->st_mode = bufSrc->st_mode | S_IRUSR | S_IRGRP | S_IROTH; // S_IXUSR | S_IXGRP | S_IXOTH;
|
371 |
buf->st_nlink = 1; //bufSrc->st_nlink; |
372 |
buf->st_uid = bufSrc->st_uid; |
373 |
buf->st_gid = bufSrc->st_gid; |
374 |
buf->st_rdev = bufSrc->st_rdev; |
375 |
buf->st_size = bufSrc->st_size; |
376 |
buf->st_blksize = bufSrc->st_blksize; |
377 |
buf->st_blocks = bufSrc->st_blocks; |
378 |
buf->st_atime = bufSrc->st_atime; |
379 |
buf->st_mtime = bufSrc->st_mtime; |
380 |
buf->st_ctime = bufSrc->st_ctime; |
381 |
} |
382 |
|
383 |
/************************************************************************/
|
384 |
/* copyVSIStatBufLToBuf64() */
|
385 |
/************************************************************************/
|
386 |
|
387 |
static void copyVSIStatBufLToBuf64(VSIStatBufL *bufSrc, struct stat64 *buf) |
388 |
{ |
389 |
buf->st_dev = bufSrc->st_dev; |
390 |
buf->st_ino = bufSrc->st_ino; |
391 |
buf->st_mode = bufSrc->st_mode | S_IRUSR | S_IRGRP | S_IROTH; // S_IXUSR | S_IXGRP | S_IXOTH;
|
392 |
buf->st_nlink = 1; //bufSrc->st_nlink; |
393 |
buf->st_uid = bufSrc->st_uid; |
394 |
buf->st_gid = bufSrc->st_gid; |
395 |
buf->st_rdev = bufSrc->st_rdev; |
396 |
buf->st_size = bufSrc->st_size; |
397 |
buf->st_blksize = bufSrc->st_blksize; |
398 |
buf->st_blocks = bufSrc->st_blocks; |
399 |
buf->st_atime = bufSrc->st_atime; |
400 |
buf->st_mtime = bufSrc->st_mtime; |
401 |
buf->st_ctime = bufSrc->st_ctime; |
402 |
} |
403 |
|
404 |
/************************************************************************/
|
405 |
/* fopen() */
|
406 |
/************************************************************************/
|
407 |
|
408 |
FILE *fopen(const char *path, const char *mode) |
409 |
{ |
410 |
myinit(); |
411 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
412 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fopen(%s, %s)\n", path, mode); |
413 |
FILE* ret; |
414 |
if( strncmp(path, "/vsi", 4) == 0 ) |
415 |
ret = (FILE*) VSIFfopenHelper(path, mode); |
416 |
else
|
417 |
ret = pfnfopen(path, mode); |
418 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fopen() = %p\n", ret); |
419 |
return ret;
|
420 |
} |
421 |
|
422 |
/************************************************************************/
|
423 |
/* fopen64() */
|
424 |
/************************************************************************/
|
425 |
|
426 |
FILE *fopen64(const char *path, const char *mode) |
427 |
{ |
428 |
myinit(); |
429 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
430 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fopen64(%s, %s)\n", path, mode); |
431 |
FILE* ret; |
432 |
if( strncmp(path, "/vsi", 4) == 0 ) |
433 |
ret = (FILE*) VSIFfopenHelper(path, mode); |
434 |
else
|
435 |
ret = pfnfopen64(path, mode); |
436 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fopen64() = %p\n", ret); |
437 |
return ret;
|
438 |
} |
439 |
|
440 |
/************************************************************************/
|
441 |
/* fread() */
|
442 |
/************************************************************************/
|
443 |
|
444 |
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
445 |
{ |
446 |
myinit(); |
447 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
448 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
449 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fread(stream=%p,size=%d,nmemb=%d)\n", |
450 |
stream, (int)size, (int)nmemb); |
451 |
size_t ret; |
452 |
if( fpVSIL )
|
453 |
ret = VSIFReadL(ptr, size, nmemb, fpVSIL); |
454 |
else
|
455 |
ret = pfnfread(ptr, size, nmemb, stream); |
456 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fread(stream=%p,size=%d,nmemb=%d) -> %d\n", |
457 |
stream, (int)size, (int)nmemb, (int)ret); |
458 |
return ret;
|
459 |
} |
460 |
|
461 |
/************************************************************************/
|
462 |
/* fwrite() */
|
463 |
/************************************************************************/
|
464 |
|
465 |
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) |
466 |
{ |
467 |
myinit(); |
468 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
469 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
470 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fwrite(stream=%p,size=%d,nmemb=%d)\n", |
471 |
stream, (int)size, (int)nmemb); |
472 |
size_t ret; |
473 |
if( fpVSIL != NULL ) |
474 |
ret = VSIFWriteL(ptr, size, nmemb, fpVSIL); |
475 |
else
|
476 |
ret = pfnfwrite(ptr, size, nmemb, stream); |
477 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fwrite(stream=%p,size=%d,nmemb=%d) -> %d\n", |
478 |
stream, (int)size, (int)nmemb, (int)ret); |
479 |
return ret;
|
480 |
} |
481 |
|
482 |
/************************************************************************/
|
483 |
/* fclose() */
|
484 |
/************************************************************************/
|
485 |
|
486 |
int fclose(FILE *stream)
|
487 |
{ |
488 |
myinit(); |
489 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
490 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
491 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fclose(stream=%p)\n", stream); |
492 |
if( fpVSIL != NULL ) |
493 |
{ |
494 |
CPLMutexHolderD(&hMutex); |
495 |
|
496 |
int ret = VSIFCloseL(fpVSIL);
|
497 |
oMapVSIToString.erase(fpVSIL); |
498 |
oSetFiles.erase(fpVSIL); |
499 |
|
500 |
std::map<VSILFILE*, int>::iterator oIter = oMapVSITofd.find(fpVSIL);
|
501 |
if( oIter != oMapVSITofd.end() )
|
502 |
{ |
503 |
int fd = oIter->second;
|
504 |
pfnclose(fd); |
505 |
oMapVSITofd.erase(oIter); |
506 |
oMapfdToVSI.erase(fd); |
507 |
} |
508 |
|
509 |
return ret;
|
510 |
} |
511 |
else
|
512 |
return pfnfclose(stream);
|
513 |
} |
514 |
|
515 |
/************************************************************************/
|
516 |
/* __xstat() */
|
517 |
/************************************************************************/
|
518 |
|
519 |
int __xstat(int ver, const char *path, struct stat *buf) |
520 |
{ |
521 |
myinit(); |
522 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
523 |
if( DEBUG_VSIPRELOAD && (osCurDir.size() != 0 && path[0] != '/') ) |
524 |
DEBUG_VSIPRELOAD_COND = 1;
|
525 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__xstat(%s)\n", path); |
526 |
if( (osCurDir.size() != 0 && path[0] != '/') || strncmp(path, "/vsi", 4) == 0 ) |
527 |
{ |
528 |
VSIStatBufL sStatBufL; |
529 |
int ret;
|
530 |
std::string newpath;
|
531 |
if( (osCurDir.size() != 0 && path[0] != '/') ) |
532 |
{ |
533 |
newpath = CPLFormFilename(osCurDir.c_str(), path, NULL);
|
534 |
path = newpath.c_str(); |
535 |
} |
536 |
ret = VSIStatL(path, &sStatBufL); |
537 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(path);
|
538 |
if( ret == 0 ) |
539 |
{ |
540 |
copyVSIStatBufLToBuf(&sStatBufL, buf); |
541 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
542 |
"__xstat(%s) ret = 0, mode = %d, size=%d\n",
|
543 |
path, sStatBufL.st_mode, (int)sStatBufL.st_size);
|
544 |
} |
545 |
return ret;
|
546 |
} |
547 |
else
|
548 |
{ |
549 |
int ret = pfn__xstat(ver, path, buf);
|
550 |
if( ret == 0 ) |
551 |
{ |
552 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
553 |
"__xstat ret = 0, mode = %d\n", buf->st_mode);
|
554 |
} |
555 |
return ret;
|
556 |
} |
557 |
} |
558 |
|
559 |
/************************************************************************/
|
560 |
/* __lxstat() */
|
561 |
/************************************************************************/
|
562 |
|
563 |
int __lxstat(int ver, const char *path, struct stat *buf) |
564 |
{ |
565 |
myinit(); |
566 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
567 |
if( DEBUG_VSIPRELOAD && (osCurDir.size() != 0 && path[0] != '/') ) |
568 |
DEBUG_VSIPRELOAD_COND = 1;
|
569 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__lxstat(%s)\n", path); |
570 |
if( (osCurDir.size() != 0 && path[0] != '/') || strncmp(path, "/vsi", 4) == 0 ) |
571 |
{ |
572 |
VSIStatBufL sStatBufL; |
573 |
int ret;
|
574 |
std::string newpath;
|
575 |
if( (osCurDir.size() != 0 && path[0] != '/') ) |
576 |
{ |
577 |
newpath = CPLFormFilename(osCurDir.c_str(), path, NULL);
|
578 |
path = newpath.c_str(); |
579 |
} |
580 |
ret = VSIStatL(path, &sStatBufL); |
581 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(path);
|
582 |
if( ret == 0 ) |
583 |
{ |
584 |
copyVSIStatBufLToBuf(&sStatBufL, buf); |
585 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
586 |
"__lxstat(%s) ret = 0, mode = %d, size=%d\n",
|
587 |
path, sStatBufL.st_mode, (int)sStatBufL.st_size);
|
588 |
} |
589 |
return ret;
|
590 |
} |
591 |
else
|
592 |
{ |
593 |
int ret = pfn__lxstat(ver, path, buf);
|
594 |
if( ret == 0 ) |
595 |
{ |
596 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
597 |
"__lxstat ret = 0, mode = %d\n", buf->st_mode);
|
598 |
} |
599 |
return ret;
|
600 |
} |
601 |
} |
602 |
|
603 |
/************************************************************************/
|
604 |
/* __xstat64() */
|
605 |
/************************************************************************/
|
606 |
|
607 |
int __xstat64(int ver, const char *path, struct stat64 *buf) |
608 |
{ |
609 |
myinit(); |
610 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
611 |
if( DEBUG_VSIPRELOAD && (osCurDir.size() != 0 && path[0] != '/') ) |
612 |
DEBUG_VSIPRELOAD_COND = 1;
|
613 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__xstat64(%s)\n", path); |
614 |
if( (osCurDir.size() != 0 && path[0] != '/') || strncmp(path, "/vsi", 4) == 0 ) |
615 |
{ |
616 |
VSIStatBufL sStatBufL; |
617 |
int ret;
|
618 |
std::string newpath;
|
619 |
if( (osCurDir.size() != 0 && path[0] != '/') ) |
620 |
{ |
621 |
newpath = CPLFormFilename(osCurDir.c_str(), path, NULL);
|
622 |
path = newpath.c_str(); |
623 |
} |
624 |
ret = VSIStatL(path, &sStatBufL); |
625 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(path);
|
626 |
if( ret == 0 ) |
627 |
{ |
628 |
copyVSIStatBufLToBuf64(&sStatBufL, buf); |
629 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
630 |
"__xstat64(%s) ret = 0, mode = %d, size = %d\n",
|
631 |
path, buf->st_mode, (int)buf->st_size);
|
632 |
} |
633 |
return ret;
|
634 |
} |
635 |
else
|
636 |
return pfn__xstat64(ver, path, buf);
|
637 |
} |
638 |
|
639 |
/************************************************************************/
|
640 |
/* fseeko64() */
|
641 |
/************************************************************************/
|
642 |
|
643 |
int fseeko64 (FILE *stream, off64_t off, int whence) |
644 |
{ |
645 |
myinit(); |
646 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
647 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
648 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fseeko64(stream=%p, off=%d, whence=%d)\n", |
649 |
stream, (int)off, whence);
|
650 |
if( fpVSIL != NULL ) |
651 |
return VSIFSeekLHelper(fpVSIL, off, whence);
|
652 |
else
|
653 |
return pfnfseeko64(stream, off, whence);
|
654 |
} |
655 |
|
656 |
/************************************************************************/
|
657 |
/* fseeko() */
|
658 |
/************************************************************************/
|
659 |
|
660 |
int fseeko (FILE *stream, off_t off, int whence) |
661 |
{ |
662 |
myinit(); |
663 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
664 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
665 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fseeko(stream=%p, off=%d, whence=%d)\n", |
666 |
stream, (int)off, whence);
|
667 |
if( fpVSIL != NULL ) |
668 |
return VSIFSeekLHelper(fpVSIL, off, whence);
|
669 |
else
|
670 |
return pfnfseeko64(stream, off, whence);
|
671 |
} |
672 |
|
673 |
/************************************************************************/
|
674 |
/* fseek() */
|
675 |
/************************************************************************/
|
676 |
|
677 |
int fseek (FILE *stream, off_t off, int whence) |
678 |
{ |
679 |
myinit(); |
680 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
681 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
682 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fseek(stream=%p, off=%d, whence=%d)\n", |
683 |
stream, (int)off, whence);
|
684 |
if( fpVSIL != NULL ) |
685 |
return VSIFSeekLHelper(fpVSIL, off, whence);
|
686 |
else
|
687 |
return pfnfseek(stream, off, whence);
|
688 |
} |
689 |
|
690 |
/************************************************************************/
|
691 |
/* ftello64() */
|
692 |
/************************************************************************/
|
693 |
|
694 |
off64_t ftello64(FILE *stream) |
695 |
{ |
696 |
myinit(); |
697 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
698 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
699 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "ftello64(stream=%p)\n", stream); |
700 |
if( fpVSIL != NULL ) |
701 |
return VSIFTellL(fpVSIL);
|
702 |
else
|
703 |
return pfnftello64(stream);
|
704 |
} |
705 |
|
706 |
/************************************************************************/
|
707 |
/* ftello() */
|
708 |
/************************************************************************/
|
709 |
|
710 |
off_t ftello(FILE *stream) |
711 |
{ |
712 |
myinit(); |
713 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
714 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
715 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "ftello(stream=%p)\n", stream); |
716 |
if( fpVSIL != NULL ) |
717 |
return VSIFTellL(fpVSIL);
|
718 |
else
|
719 |
return pfnftello64(stream);
|
720 |
} |
721 |
|
722 |
/************************************************************************/
|
723 |
/* ftell() */
|
724 |
/************************************************************************/
|
725 |
|
726 |
off_t ftell(FILE *stream) |
727 |
{ |
728 |
myinit(); |
729 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
730 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
731 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "ftell(stream=%p)\n", stream); |
732 |
if( fpVSIL != NULL ) |
733 |
return VSIFTellL(fpVSIL);
|
734 |
else
|
735 |
return pfnftell(stream);
|
736 |
} |
737 |
|
738 |
/************************************************************************/
|
739 |
/* feof() */
|
740 |
/************************************************************************/
|
741 |
|
742 |
int feof(FILE *stream)
|
743 |
{ |
744 |
myinit(); |
745 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
746 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
747 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "feof(stream=%p)\n", stream); |
748 |
if( fpVSIL != NULL ) |
749 |
return VSIFEofL(fpVSIL);
|
750 |
else
|
751 |
return pfnfeof(stream);
|
752 |
} |
753 |
|
754 |
/************************************************************************/
|
755 |
/* rewind() */
|
756 |
/************************************************************************/
|
757 |
|
758 |
void rewind(FILE *stream)
|
759 |
{ |
760 |
fseek(stream, 0, SEEK_SET);
|
761 |
} |
762 |
|
763 |
/************************************************************************/
|
764 |
/* fflush() */
|
765 |
/************************************************************************/
|
766 |
|
767 |
int fflush(FILE *stream)
|
768 |
{ |
769 |
myinit(); |
770 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
771 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
772 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fflush(stream=%p)\n", stream); |
773 |
if( fpVSIL != NULL ) |
774 |
return 0; |
775 |
else
|
776 |
return pfnfflush(stream);
|
777 |
} |
778 |
|
779 |
/************************************************************************/
|
780 |
/* fgetpos() */
|
781 |
/************************************************************************/
|
782 |
|
783 |
int fgetpos(FILE *stream, fpos_t *pos)
|
784 |
{ |
785 |
myinit(); |
786 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
787 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
788 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fgetpos(stream=%p)\n", stream); |
789 |
if( fpVSIL != NULL ) |
790 |
{ |
791 |
fprintf(stderr, "fgetpos() unimplemented for VSILFILE\n");
|
792 |
return -1; // FIXME |
793 |
} |
794 |
else
|
795 |
return pfnfgetpos(stream, pos);
|
796 |
} |
797 |
|
798 |
/************************************************************************/
|
799 |
/* fsetpos() */
|
800 |
/************************************************************************/
|
801 |
|
802 |
int fsetpos(FILE *stream, fpos_t *pos)
|
803 |
{ |
804 |
myinit(); |
805 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
806 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
807 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fsetpos(stream=%p)\n", stream); |
808 |
if( fpVSIL != NULL ) |
809 |
{ |
810 |
fprintf(stderr, "fsetpos() unimplemented for VSILFILE\n");
|
811 |
return -1; // FIXME |
812 |
} |
813 |
else
|
814 |
return pfnfsetpos(stream, pos);
|
815 |
} |
816 |
|
817 |
/************************************************************************/
|
818 |
/* fileno() */
|
819 |
/************************************************************************/
|
820 |
|
821 |
int fileno(FILE *stream)
|
822 |
{ |
823 |
myinit(); |
824 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
825 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
826 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fileno(stream=%p)\n", stream); |
827 |
int fd;
|
828 |
if( fpVSIL != NULL ) |
829 |
fd = getfdFromVSILFILE(fpVSIL); |
830 |
else
|
831 |
fd = pfnfileno(stream); |
832 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fileno(stream=%p) = %d\n", stream, fd); |
833 |
return fd;
|
834 |
} |
835 |
|
836 |
/************************************************************************/
|
837 |
/* ferror() */
|
838 |
/************************************************************************/
|
839 |
|
840 |
int ferror(FILE *stream)
|
841 |
{ |
842 |
myinit(); |
843 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
844 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
845 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "ferror(stream=%p)\n", stream); |
846 |
if( fpVSIL != NULL ) |
847 |
{ |
848 |
fprintf(stderr, "ferror() unimplemented for VSILFILE\n");
|
849 |
return 0; // FIXME ? |
850 |
} |
851 |
else
|
852 |
return pfnferror(stream);
|
853 |
} |
854 |
|
855 |
/************************************************************************/
|
856 |
/* fdopen() */
|
857 |
/************************************************************************/
|
858 |
|
859 |
FILE * fdopen(int fd, const char *mode) |
860 |
{ |
861 |
myinit(); |
862 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
863 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
864 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fdopen(fd=%d)\n", fd); |
865 |
if( fpVSIL != NULL ) |
866 |
{ |
867 |
fprintf(stderr, "fdopen() unimplemented for VSILFILE\n");
|
868 |
return NULL; // FIXME ? |
869 |
} |
870 |
else
|
871 |
return pfnfdopen(fd, mode);
|
872 |
} |
873 |
|
874 |
/************************************************************************/
|
875 |
/* freopen() */
|
876 |
/************************************************************************/
|
877 |
|
878 |
FILE *freopen(const char *path, const char *mode, FILE *stream) |
879 |
{ |
880 |
myinit(); |
881 |
VSILFILE* fpVSIL = getVSILFILE(stream); |
882 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
883 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "freopen(path=%s,mode=%s,stream=%p)\n", path, mode, stream); |
884 |
if( fpVSIL != NULL ) |
885 |
{ |
886 |
fprintf(stderr, "freopen() unimplemented for VSILFILE\n");
|
887 |
return NULL; // FIXME ? |
888 |
} |
889 |
else
|
890 |
return pfnfreopen(path, mode, stream);
|
891 |
} |
892 |
|
893 |
/************************************************************************/
|
894 |
/* open() */
|
895 |
/************************************************************************/
|
896 |
|
897 |
int open(const char *path, int flags, ...) |
898 |
{ |
899 |
myinit(); |
900 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
901 |
if( DEBUG_VSIPRELOAD && osCurDir.size() != 0 && path[0] != '/' ) |
902 |
DEBUG_VSIPRELOAD_COND = 1;
|
903 |
if (DEBUG_VSIPRELOAD_COND)
|
904 |
{ |
905 |
if( osCurDir.size() != 0 && path[0] != '/' ) |
906 |
fprintf(stderr, "open(%s)\n", CPLFormFilename(osCurDir.c_str(), path, NULL)); |
907 |
else
|
908 |
fprintf(stderr, "open(%s)\n", path);
|
909 |
} |
910 |
|
911 |
va_list args; |
912 |
va_start(args, flags); |
913 |
mode_t mode = va_arg(args, mode_t); |
914 |
int fd;
|
915 |
if( osCurDir.size() != 0 && path[0] != '/' && (flags & 3) == O_RDONLY && (flags & O_DIRECTORY) != 0 ) |
916 |
{ |
917 |
VSIStatBufL sStatBufL; |
918 |
char* newname = (char*)CPLFormFilename(osCurDir.c_str(), path, NULL); |
919 |
if( strchr(osCurDir.c_str(), '/') != NULL && strcmp(path, "..") == 0 ) |
920 |
{ |
921 |
char* lastslash = strrchr(newname, '/'); |
922 |
if( lastslash != NULL ) |
923 |
{ |
924 |
*lastslash = 0;
|
925 |
lastslash = strrchr(newname, '/');
|
926 |
if( lastslash != NULL ) |
927 |
*lastslash = 0;
|
928 |
} |
929 |
} |
930 |
if( VSIStatL(newname, &sStatBufL) == 0 && |
931 |
S_ISDIR(sStatBufL.st_mode) ) |
932 |
{ |
933 |
fd = open("/dev/zero", O_RDONLY);
|
934 |
CPLMutexHolderD(&hMutex) |
935 |
oMapDirFdToName[fd] = newname; |
936 |
} |
937 |
else
|
938 |
fd = -1;
|
939 |
} |
940 |
else if( strncmp(path, "/vsi", 4) == 0 ) |
941 |
fd = VSIFopenHelper(path, flags); |
942 |
else
|
943 |
fd = pfnopen(path, flags, mode); |
944 |
va_end(args); |
945 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "open(%s) = %d\n", path, fd); |
946 |
return fd;
|
947 |
} |
948 |
|
949 |
/************************************************************************/
|
950 |
/* open64() */
|
951 |
/************************************************************************/
|
952 |
|
953 |
int open64(const char *path, int flags, ...) |
954 |
{ |
955 |
myinit(); |
956 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
957 |
if( DEBUG_VSIPRELOAD && osCurDir.size() != 0 && path[0] != '/' ) |
958 |
DEBUG_VSIPRELOAD_COND = 1;
|
959 |
if (DEBUG_VSIPRELOAD_COND)
|
960 |
{ |
961 |
if( osCurDir.size() != 0 && path[0] != '/' ) |
962 |
fprintf(stderr, "open64(%s)\n", CPLFormFilename(osCurDir.c_str(), path, NULL)); |
963 |
else
|
964 |
fprintf(stderr, "open64(%s)\n", path);
|
965 |
} |
966 |
|
967 |
va_list args; |
968 |
va_start(args, flags); |
969 |
mode_t mode = va_arg(args, mode_t); |
970 |
int fd;
|
971 |
if( osCurDir.size() != 0 && path[0] != '/' && (flags & 3) == O_RDONLY && (flags & O_DIRECTORY) != 0 ) |
972 |
{ |
973 |
VSIStatBufL sStatBufL; |
974 |
char* newname = (char*)CPLFormFilename(osCurDir.c_str(), path, NULL); |
975 |
if( strchr(osCurDir.c_str(), '/') != NULL && strcmp(path, "..") == 0 ) |
976 |
{ |
977 |
char* lastslash = strrchr(newname, '/'); |
978 |
if( lastslash != NULL ) |
979 |
{ |
980 |
*lastslash = 0;
|
981 |
lastslash = strrchr(newname, '/');
|
982 |
if( lastslash != NULL ) |
983 |
*lastslash = 0;
|
984 |
} |
985 |
} |
986 |
if( VSIStatL(newname, &sStatBufL) == 0 && |
987 |
S_ISDIR(sStatBufL.st_mode) ) |
988 |
{ |
989 |
fd = open("/dev/zero", O_RDONLY);
|
990 |
CPLMutexHolderD(&hMutex) |
991 |
oMapDirFdToName[fd] = newname; |
992 |
} |
993 |
else
|
994 |
fd = -1;
|
995 |
} |
996 |
else if( strncmp(path, "/vsi", 4) == 0 ) |
997 |
fd = VSIFopenHelper(path, flags); |
998 |
else
|
999 |
fd = pfnopen64(path, flags, mode); |
1000 |
va_end(args); |
1001 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "open64(%s) = %d\n", path, fd); |
1002 |
return fd;
|
1003 |
} |
1004 |
|
1005 |
/************************************************************************/
|
1006 |
/* creat() */
|
1007 |
/************************************************************************/
|
1008 |
|
1009 |
int creat(const char *path, mode_t mode) |
1010 |
{ |
1011 |
return open64(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
|
1012 |
} |
1013 |
|
1014 |
/************************************************************************/
|
1015 |
/* close() */
|
1016 |
/************************************************************************/
|
1017 |
|
1018 |
int close(int fd) |
1019 |
{ |
1020 |
myinit(); |
1021 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1022 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1023 |
{ |
1024 |
CPLMutexHolderD(&hMutex); |
1025 |
assert( oMapfdToVSIDIR.find(fd) == oMapfdToVSIDIR.end() ); |
1026 |
|
1027 |
if( oMapDirFdToName.find(fd) != oMapDirFdToName.end())
|
1028 |
{ |
1029 |
oMapDirFdToName.erase(fd); |
1030 |
if( DEBUG_VSIPRELOAD )
|
1031 |
DEBUG_VSIPRELOAD_COND = 1;
|
1032 |
} |
1033 |
} |
1034 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "close(fd=%d)\n", fd); |
1035 |
if( fpVSIL != NULL ) |
1036 |
{ |
1037 |
VSIFCloseL(fpVSIL); |
1038 |
CPLMutexHolderD(&hMutex); |
1039 |
oSetFiles.erase(fpVSIL); |
1040 |
pfnclose(oMapVSITofd[fpVSIL]); |
1041 |
oMapVSITofd.erase(fpVSIL); |
1042 |
oMapfdToVSI.erase(fd); |
1043 |
oMapVSIToString.erase(fpVSIL); |
1044 |
return 0; |
1045 |
} |
1046 |
else
|
1047 |
return pfnclose(fd);
|
1048 |
} |
1049 |
|
1050 |
/************************************************************************/
|
1051 |
/* read() */
|
1052 |
/************************************************************************/
|
1053 |
|
1054 |
ssize_t read(int fd, void *buf, size_t count) |
1055 |
{ |
1056 |
myinit(); |
1057 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1058 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1059 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "read(fd=%d, count=%d)\n", fd, (int)count); |
1060 |
ssize_t ret; |
1061 |
if( fpVSIL != NULL ) |
1062 |
ret = VSIFReadL(buf, 1, count, fpVSIL);
|
1063 |
else
|
1064 |
ret = pfnread(fd, buf, count); |
1065 |
if (DEBUG_VSIPRELOAD_COND && DEBUG_OUTPUT_READ && ret < 40) |
1066 |
{ |
1067 |
fprintf(stderr, "read() : ");
|
1068 |
for(int i=0;i<ret;i++) |
1069 |
{ |
1070 |
if( ((unsigned char*)buf)[i] >= 'A' && ((unsigned char*)buf)[i] <= 'Z' ) |
1071 |
fprintf(stderr, "%c ", ((unsigned char*)buf)[i]); |
1072 |
else
|
1073 |
fprintf(stderr, "\\%02X ", ((unsigned char*)buf)[i]); |
1074 |
} |
1075 |
fprintf(stderr, "\n");
|
1076 |
} |
1077 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "read() -> %d\n", (int)ret); |
1078 |
return ret;
|
1079 |
} |
1080 |
|
1081 |
/************************************************************************/
|
1082 |
/* write() */
|
1083 |
/************************************************************************/
|
1084 |
|
1085 |
ssize_t write(int fd, const void *buf, size_t count) |
1086 |
{ |
1087 |
myinit(); |
1088 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1089 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1090 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "write(fd=%d, count=%d)\n", fd, (int)count); |
1091 |
if( fpVSIL != NULL ) |
1092 |
return VSIFWriteL(buf, 1, count, fpVSIL); |
1093 |
else
|
1094 |
return pfnwrite(fd, buf, count);
|
1095 |
} |
1096 |
|
1097 |
/************************************************************************/
|
1098 |
/* fsync() */
|
1099 |
/************************************************************************/
|
1100 |
|
1101 |
int fsync(int fd) |
1102 |
{ |
1103 |
myinit(); |
1104 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1105 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1106 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fsync(fd=%d)\n", fd); |
1107 |
if( fpVSIL != NULL ) |
1108 |
return 0; |
1109 |
else
|
1110 |
return pfnfsync(fd);
|
1111 |
} |
1112 |
|
1113 |
/************************************************************************/
|
1114 |
/* fdatasync() */
|
1115 |
/************************************************************************/
|
1116 |
|
1117 |
int fdatasync(int fd) |
1118 |
{ |
1119 |
myinit(); |
1120 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1121 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1122 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fdatasync(fd=%d)\n", fd); |
1123 |
if( fpVSIL != NULL ) |
1124 |
return 0; |
1125 |
else
|
1126 |
return pfnfdatasync(fd);
|
1127 |
} |
1128 |
|
1129 |
/************************************************************************/
|
1130 |
/* __fxstat() */
|
1131 |
/************************************************************************/
|
1132 |
|
1133 |
int __fxstat (int ver, int fd, struct stat *buf) |
1134 |
{ |
1135 |
myinit(); |
1136 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1137 |
std::string name;
|
1138 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1139 |
{ |
1140 |
CPLMutexHolderD(&hMutex) |
1141 |
if( oMapDirFdToName.find(fd) != oMapDirFdToName.end())
|
1142 |
{ |
1143 |
name = oMapDirFdToName[fd]; |
1144 |
if( DEBUG_VSIPRELOAD )
|
1145 |
DEBUG_VSIPRELOAD_COND = 1;
|
1146 |
} |
1147 |
} |
1148 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__fxstat(fd=%d)\n", fd); |
1149 |
if( name.size() )
|
1150 |
{ |
1151 |
VSIStatBufL sStatBufL; |
1152 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__fxstat(%s)\n", name.c_str()); |
1153 |
int ret = VSIStatL(name.c_str(), &sStatBufL);
|
1154 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(name.c_str());
|
1155 |
if( ret == 0 ) |
1156 |
{ |
1157 |
copyVSIStatBufLToBuf(&sStatBufL, buf); |
1158 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1159 |
"__fxstat ret = 0, mode = %d, size = %d\n",
|
1160 |
sStatBufL.st_mode, (int)sStatBufL.st_size);
|
1161 |
} |
1162 |
return ret;
|
1163 |
} |
1164 |
else if( fpVSIL != NULL ) |
1165 |
{ |
1166 |
VSIStatBufL sStatBufL; |
1167 |
{ |
1168 |
CPLMutexHolderD(&hMutex); |
1169 |
name = oMapVSIToString[fpVSIL]; |
1170 |
} |
1171 |
int ret = VSIStatL(name.c_str(), &sStatBufL);
|
1172 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(name.c_str());
|
1173 |
if( ret == 0 ) |
1174 |
{ |
1175 |
copyVSIStatBufLToBuf(&sStatBufL, buf); |
1176 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1177 |
"__fxstat ret = 0, mode = %d, size = %d\n",
|
1178 |
sStatBufL.st_mode, (int)sStatBufL.st_size);
|
1179 |
} |
1180 |
return ret;
|
1181 |
} |
1182 |
else
|
1183 |
return pfn__fxstat(ver, fd, buf);
|
1184 |
} |
1185 |
|
1186 |
/************************************************************************/
|
1187 |
/* __fxstat64() */
|
1188 |
/************************************************************************/
|
1189 |
|
1190 |
int __fxstat64 (int ver, int fd, struct stat64 *buf) |
1191 |
{ |
1192 |
myinit(); |
1193 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1194 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1195 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__fxstat64(fd=%d)\n", fd); |
1196 |
if( fpVSIL != NULL ) |
1197 |
{ |
1198 |
VSIStatBufL sStatBufL; |
1199 |
std::string name;
|
1200 |
{ |
1201 |
CPLMutexHolderD(&hMutex); |
1202 |
name = oMapVSIToString[fpVSIL]; |
1203 |
} |
1204 |
int ret = VSIStatL(name.c_str(), &sStatBufL);
|
1205 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(name.c_str());
|
1206 |
if( ret == 0 ) |
1207 |
{ |
1208 |
copyVSIStatBufLToBuf64(&sStatBufL, buf); |
1209 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1210 |
"__fxstat64 ret = 0, mode = %d, size = %d\n",
|
1211 |
buf->st_mode, (int)buf->st_size);
|
1212 |
} |
1213 |
return ret;
|
1214 |
} |
1215 |
else
|
1216 |
return pfn__fxstat64(ver, fd, buf);
|
1217 |
} |
1218 |
|
1219 |
/************************************************************************/
|
1220 |
/* __fxstatat() */
|
1221 |
/************************************************************************/
|
1222 |
|
1223 |
#ifdef HAVE_FSTATAT
|
1224 |
int __fxstatat (int ver, int dirfd, const char *pathname, struct stat *buf, |
1225 |
int flags)
|
1226 |
{ |
1227 |
myinit(); |
1228 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(pathname);
|
1229 |
if( DEBUG_VSIPRELOAD && osCurDir.size() != 0 ) |
1230 |
DEBUG_VSIPRELOAD_COND = 1;
|
1231 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "__fxstatat(dirfd=%d,pathname=%s,flags=%d)\n", dirfd, pathname, flags); |
1232 |
|
1233 |
if( osCurDir.size() != 0 || strncmp(pathname, "/vsi", 4) == 0 ) |
1234 |
{ |
1235 |
VSIStatBufL sStatBufL; |
1236 |
int ret;
|
1237 |
if( osCurDir.size() && dirfd == AT_FDCWD && pathname[0] != '/' ) |
1238 |
pathname = CPLFormFilename(osCurDir.c_str(), pathname, NULL);
|
1239 |
ret = VSIStatL(pathname, &sStatBufL); |
1240 |
sStatBufL.st_ino = (int)CPLHashSetHashStr(pathname);
|
1241 |
if( ret == 0 ) |
1242 |
{ |
1243 |
copyVSIStatBufLToBuf(&sStatBufL, buf); |
1244 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1245 |
"__fxstatat(%s) ret = 0, mode = %d, size = %d\n",
|
1246 |
pathname, buf->st_mode, (int)buf->st_size);
|
1247 |
} |
1248 |
return ret;
|
1249 |
} |
1250 |
else
|
1251 |
return pfn__fxstatat(ver, dirfd, pathname, buf, flags);
|
1252 |
} |
1253 |
#endif
|
1254 |
|
1255 |
/************************************************************************/
|
1256 |
/* lseek() */
|
1257 |
/************************************************************************/
|
1258 |
|
1259 |
off_t lseek(int fd, off_t off, int whence) |
1260 |
{ |
1261 |
myinit(); |
1262 |
off_t ret; |
1263 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1264 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1265 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1266 |
"lseek(fd=%d, off=%d, whence=%d)\n", fd, (int)off, whence); |
1267 |
if( fpVSIL != NULL ) |
1268 |
{ |
1269 |
VSIFSeekLHelper(fpVSIL, off, whence); |
1270 |
ret = VSIFTellL(fpVSIL); |
1271 |
} |
1272 |
else
|
1273 |
ret = pfnlseek(fd, off, whence); |
1274 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "lseek() -> ret = %d\n", (int)ret); |
1275 |
return ret;
|
1276 |
} |
1277 |
|
1278 |
/************************************************************************/
|
1279 |
/* lseek64() */
|
1280 |
/************************************************************************/
|
1281 |
|
1282 |
off64_t lseek64(int fd, off64_t off, int whence) |
1283 |
{ |
1284 |
myinit(); |
1285 |
off_t ret; |
1286 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1287 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1288 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1289 |
"lseek64(fd=%d, off=%d, whence=%d)\n", fd, (int)off, whence); |
1290 |
if( fpVSIL != NULL ) |
1291 |
{ |
1292 |
VSIFSeekLHelper(fpVSIL, off, whence); |
1293 |
ret = VSIFTellL(fpVSIL); |
1294 |
} |
1295 |
else
|
1296 |
ret = pfnlseek64(fd, off, whence); |
1297 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr,
|
1298 |
"lseek64() -> ret = %d\n", (int)ret); |
1299 |
return ret;
|
1300 |
} |
1301 |
|
1302 |
/************************************************************************/
|
1303 |
/* truncate() */
|
1304 |
/************************************************************************/
|
1305 |
|
1306 |
int truncate(const char *path, off_t length) |
1307 |
{ |
1308 |
myinit(); |
1309 |
int ret;
|
1310 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
1311 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "truncate(%s)\n", path); |
1312 |
|
1313 |
if( strncmp(path, "/vsi", 4) == 0 ) |
1314 |
{ |
1315 |
VSILFILE* fpVSIL = VSIFOpenL(path, "wb+");
|
1316 |
if( fpVSIL )
|
1317 |
{ |
1318 |
ret = VSIFTruncateL(fpVSIL, length); |
1319 |
VSIFCloseL(fpVSIL); |
1320 |
} |
1321 |
else
|
1322 |
ret = -1;
|
1323 |
} |
1324 |
else
|
1325 |
ret = pfntruncate(path, length); |
1326 |
return ret;
|
1327 |
} |
1328 |
|
1329 |
/************************************************************************/
|
1330 |
/* ftruncate() */
|
1331 |
/************************************************************************/
|
1332 |
|
1333 |
int ftruncate(int fd, off_t length) |
1334 |
{ |
1335 |
myinit(); |
1336 |
int ret;
|
1337 |
VSILFILE* fpVSIL = getVSILFILE(fd); |
1338 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(fpVSIL);
|
1339 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "ftruncate(fd=%d)\n", fd); |
1340 |
if( fpVSIL != NULL ) |
1341 |
{ |
1342 |
ret = VSIFTruncateL(fpVSIL, length); |
1343 |
} |
1344 |
else
|
1345 |
ret = pfnftruncate(fd, length); |
1346 |
return ret;
|
1347 |
} |
1348 |
|
1349 |
/************************************************************************/
|
1350 |
/* opendir() */
|
1351 |
/************************************************************************/
|
1352 |
|
1353 |
DIR *opendir(const char *name) |
1354 |
{ |
1355 |
myinit(); |
1356 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(name);
|
1357 |
if( DEBUG_VSIPRELOAD && osCurDir.size() != 0 ) |
1358 |
DEBUG_VSIPRELOAD_COND = 1;
|
1359 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "opendir(%s)\n", name); |
1360 |
|
1361 |
DIR * ret; |
1362 |
if( osCurDir.size() != 0 || strncmp(name, "/vsi", 4) == 0 ) |
1363 |
{ |
1364 |
char** papszDir;
|
1365 |
if( osCurDir.size() != 0 && name[0] != '/' ) |
1366 |
name = CPLFormFilename(osCurDir.c_str(), name, NULL);
|
1367 |
papszDir = VSIReadDir(name); |
1368 |
if( papszDir == NULL ) |
1369 |
{ |
1370 |
VSIStatBufL sStatBufL; |
1371 |
if( VSIStatL(name, &sStatBufL) == 0 && S_ISDIR(sStatBufL.st_mode) ) |
1372 |
{ |
1373 |
papszDir = (char**) CPLMalloc(sizeof(char*)); |
1374 |
papszDir[0] = NULL; |
1375 |
} |
1376 |
} |
1377 |
if( papszDir == NULL ) |
1378 |
ret = NULL;
|
1379 |
else
|
1380 |
{ |
1381 |
VSIDIR* mydir = (VSIDIR*)malloc(sizeof(VSIDIR));
|
1382 |
mydir->pszDirname = CPLStrdup(name); |
1383 |
mydir->papszDir = papszDir; |
1384 |
mydir->nIter = 0;
|
1385 |
mydir->fd = -1;
|
1386 |
ret = (DIR*)mydir; |
1387 |
CPLMutexHolderD(&hMutex); |
1388 |
oSetVSIDIR.insert(mydir); |
1389 |
} |
1390 |
} |
1391 |
else
|
1392 |
ret = pfnopendir(name); |
1393 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "opendir(%s) -> %p\n", name, ret); |
1394 |
return ret;
|
1395 |
} |
1396 |
|
1397 |
/************************************************************************/
|
1398 |
/* readdir() */
|
1399 |
/************************************************************************/
|
1400 |
|
1401 |
struct dirent *readdir(DIR *dirp)
|
1402 |
{ |
1403 |
myinit(); |
1404 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND((VSIDIR*)dirp);
|
1405 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "readdir(%p)\n", dirp); |
1406 |
if( oSetVSIDIR.find((VSIDIR*)dirp) != oSetVSIDIR.end() )
|
1407 |
{ |
1408 |
VSIDIR* mydir = (VSIDIR*)dirp; |
1409 |
char* pszName = mydir->papszDir[mydir->nIter++];
|
1410 |
if( pszName == NULL ) |
1411 |
return NULL; |
1412 |
mydir->ent.d_ino = 0;
|
1413 |
mydir->ent.d_off = 0;
|
1414 |
mydir->ent.d_reclen = sizeof(mydir->ent);
|
1415 |
VSIStatBufL sStatBufL; |
1416 |
VSIStatL(CPLFormFilename(mydir->pszDirname, pszName, NULL), &sStatBufL);
|
1417 |
if( DEBUG_VSIPRELOAD_COND && S_ISDIR(sStatBufL.st_mode) )
|
1418 |
fprintf(stderr, "%s is dir\n", pszName);
|
1419 |
mydir->ent.d_type = S_ISDIR(sStatBufL.st_mode) ? DT_DIR : |
1420 |
S_ISREG(sStatBufL.st_mode) ? DT_REG : |
1421 |
S_ISLNK(sStatBufL.st_mode) ? DT_LNK : |
1422 |
DT_UNKNOWN; |
1423 |
strncpy(mydir->ent.d_name, pszName, 256);
|
1424 |
mydir->ent.d_name[255] = '\0'; |
1425 |
return &(mydir->ent);
|
1426 |
} |
1427 |
else
|
1428 |
return pfnreaddir(dirp);
|
1429 |
} |
1430 |
|
1431 |
/************************************************************************/
|
1432 |
/* closedir() */
|
1433 |
/************************************************************************/
|
1434 |
|
1435 |
int closedir(DIR *dirp)
|
1436 |
{ |
1437 |
myinit(); |
1438 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND((VSIDIR*)dirp);
|
1439 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "closedir(%p)\n", dirp); |
1440 |
if( oSetVSIDIR.find((VSIDIR*)dirp) != oSetVSIDIR.end() )
|
1441 |
{ |
1442 |
VSIDIR* mydir = (VSIDIR*)dirp; |
1443 |
CPLFree(mydir->pszDirname); |
1444 |
CSLDestroy(mydir->papszDir); |
1445 |
CPLMutexHolderD(&hMutex); |
1446 |
if( mydir->fd >= 0 ) |
1447 |
{ |
1448 |
oMapfdToVSIDIR.erase(mydir->fd); |
1449 |
close(mydir->fd); |
1450 |
} |
1451 |
oSetVSIDIR.erase(mydir); |
1452 |
free(mydir); |
1453 |
return 0; |
1454 |
} |
1455 |
else
|
1456 |
return pfnclosedir(dirp);
|
1457 |
} |
1458 |
|
1459 |
/************************************************************************/
|
1460 |
/* dirfd() */
|
1461 |
/************************************************************************/
|
1462 |
|
1463 |
int dirfd(DIR *dirp)
|
1464 |
{ |
1465 |
myinit(); |
1466 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND((VSIDIR*)dirp);
|
1467 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "dirfd(%p)\n", dirp); |
1468 |
int ret;
|
1469 |
if( oSetVSIDIR.find((VSIDIR*)dirp) != oSetVSIDIR.end() )
|
1470 |
{ |
1471 |
VSIDIR* mydir = (VSIDIR*)dirp; |
1472 |
if( mydir->fd < 0 ) |
1473 |
{ |
1474 |
mydir->fd = open("/dev/zero", O_RDONLY);
|
1475 |
CPLMutexHolderD(&hMutex); |
1476 |
oMapfdToVSIDIR[mydir->fd] = mydir; |
1477 |
} |
1478 |
ret = mydir->fd; |
1479 |
} |
1480 |
else
|
1481 |
ret = pfndirfd(dirp); |
1482 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "dirfd(%p) -> %d\n", dirp, ret); |
1483 |
return ret;
|
1484 |
} |
1485 |
|
1486 |
/************************************************************************/
|
1487 |
/* fchdir() */
|
1488 |
/************************************************************************/
|
1489 |
|
1490 |
int fchdir(int fd) |
1491 |
{ |
1492 |
VSIDIR* mydir = NULL;
|
1493 |
{ |
1494 |
CPLMutexHolderD(&hMutex); |
1495 |
if( oMapfdToVSIDIR.find(fd) != oMapfdToVSIDIR.end() )
|
1496 |
mydir = oMapfdToVSIDIR[fd]; |
1497 |
} |
1498 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(mydir);
|
1499 |
std::string name;
|
1500 |
{ |
1501 |
CPLMutexHolderD(&hMutex) |
1502 |
if( oMapDirFdToName.find(fd) != oMapDirFdToName.end())
|
1503 |
{ |
1504 |
name = oMapDirFdToName[fd]; |
1505 |
if( DEBUG_VSIPRELOAD )
|
1506 |
DEBUG_VSIPRELOAD_COND = 1;
|
1507 |
} |
1508 |
} |
1509 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fchdir(%d)\n", fd); |
1510 |
if( name.size() )
|
1511 |
{ |
1512 |
osCurDir = name; |
1513 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fchdir(%d) -> %s\n", fd, osCurDir.c_str()); |
1514 |
return 0; |
1515 |
} |
1516 |
else if( mydir != NULL ) |
1517 |
{ |
1518 |
osCurDir = mydir->pszDirname; |
1519 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fchdir(%d) -> %s\n", fd, osCurDir.c_str()); |
1520 |
return 0; |
1521 |
} |
1522 |
else
|
1523 |
{ |
1524 |
osCurDir = "";
|
1525 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "fchdir(%d) -> %s\n", fd, osCurDir.c_str()); |
1526 |
return pfnfchdir(fd);
|
1527 |
} |
1528 |
} |
1529 |
|
1530 |
/************************************************************************/
|
1531 |
/* acl_extended_file() */
|
1532 |
/************************************************************************/
|
1533 |
|
1534 |
// #include <acl/acl.h>
|
1535 |
extern "C" int acl_extended_file(const char *name); |
1536 |
DECLARE_SYMBOL(acl_extended_file, int, (const char *name)); |
1537 |
|
1538 |
int acl_extended_file(const char *path) |
1539 |
{ |
1540 |
myinit(); |
1541 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
1542 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "acl_extended_file(%s)\n", path); |
1543 |
int ret;
|
1544 |
if( strncmp(path, "/vsi", 4) == 0 ) |
1545 |
ret = -1;
|
1546 |
else
|
1547 |
{ |
1548 |
if( pfnacl_extended_file == NULL ) |
1549 |
pfnacl_extended_file = (fnacl_extended_fileType) dlsym(RTLD_NEXT, "acl_extended_file");
|
1550 |
if( pfnacl_extended_file == NULL ) |
1551 |
ret = -1;
|
1552 |
else
|
1553 |
ret = pfnacl_extended_file(path); |
1554 |
} |
1555 |
return ret;
|
1556 |
} |
1557 |
|
1558 |
/************************************************************************/
|
1559 |
/* getfilecon() */
|
1560 |
/************************************************************************/
|
1561 |
|
1562 |
// #include <selinux/selinux.h>
|
1563 |
extern "C" int getfilecon(const char *name, void* con); |
1564 |
DECLARE_SYMBOL(getfilecon, int, (const char *name, void* con)); |
1565 |
|
1566 |
int getfilecon(const char *path, /*security_context_t **/ void* con) |
1567 |
{ |
1568 |
myinit(); |
1569 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
1570 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "getfilecon(%s)\n", path); |
1571 |
int ret;
|
1572 |
if( strncmp(path, "/vsi", 4) == 0 ) |
1573 |
{ |
1574 |
errno = ENOTSUP; |
1575 |
ret = -1;
|
1576 |
} |
1577 |
else
|
1578 |
{ |
1579 |
if( pfngetfilecon == NULL ) |
1580 |
pfngetfilecon = (fngetfileconType) dlsym(RTLD_NEXT, "getfilecon");
|
1581 |
if( pfngetfilecon == NULL ) |
1582 |
ret = -1;
|
1583 |
else
|
1584 |
ret = pfngetfilecon(path, con); |
1585 |
} |
1586 |
return ret;
|
1587 |
} |
1588 |
|
1589 |
/************************************************************************/
|
1590 |
/* lgetfilecon() */
|
1591 |
/************************************************************************/
|
1592 |
|
1593 |
// #include <selinux/selinux.h>
|
1594 |
extern "C" int lgetfilecon(const char *name, void* con); |
1595 |
DECLARE_SYMBOL(lgetfilecon, int, (const char *name, void* con)); |
1596 |
|
1597 |
int lgetfilecon(const char *path, /*security_context_t **/ void* con) |
1598 |
{ |
1599 |
myinit(); |
1600 |
int DEBUG_VSIPRELOAD_COND = GET_DEBUG_VSIPRELOAD_COND(path);
|
1601 |
if (DEBUG_VSIPRELOAD_COND) fprintf(stderr, "lgetfilecon(%s)\n", path); |
1602 |
int ret;
|
1603 |
if( strncmp(path, "/vsi", 4) == 0 ) |
1604 |
{ |
1605 |
errno = ENOTSUP; |
1606 |
ret = -1;
|
1607 |
} |
1608 |
else
|
1609 |
{ |
1610 |
if( pfnlgetfilecon == NULL ) |
1611 |
pfnlgetfilecon = (fnlgetfileconType) dlsym(RTLD_NEXT, "lgetfilecon");
|
1612 |
if( pfnlgetfilecon == NULL ) |
1613 |
ret = -1;
|
1614 |
else
|
1615 |
ret = pfnlgetfilecon(path, con); |
1616 |
} |
1617 |
return ret;
|
1618 |
} |