1 : /******************************************************************************
2 : * $Id: cpl_vsisimple.cpp 18293 2009-12-14 23:17:24Z rouault $
3 : *
4 : * Project: Common Portability Library
5 : * Purpose: Simple implementation of POSIX VSI functions.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1998, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************
29 : *
30 : * NB: Note that in wrappers we are always saving the error state (errno
31 : * variable) to avoid side effects during debug prints or other possible
32 : * standard function calls (error states will be overwritten after such
33 : * a call).
34 : *
35 : ****************************************************************************/
36 :
37 : #include "cpl_config.h"
38 : #include "cpl_port.h"
39 : #include "cpl_vsi.h"
40 : #include "cpl_error.h"
41 :
42 : /* Uncomment to check consistent usage of VSIMalloc(), VSIRealloc(), */
43 : /* VSICalloc(), VSIFree(), VSIStrdup() */
44 : //#define DEBUG_VSIMALLOC
45 :
46 : /* Uncomment to compute memory usage statistics. */
47 : /* DEBUG_VSIMALLOC must also be defined */
48 : //#define DEBUG_VSIMALLOC_STATS
49 :
50 : /* Uncomment to print every memory allocation or deallocation. */
51 : /* DEBUG_VSIMALLOC must also be defined */
52 : //#define DEBUG_VSIMALLOC_VERBOSE
53 :
54 : CPL_CVSID("$Id: cpl_vsisimple.cpp 18293 2009-12-14 23:17:24Z rouault $");
55 :
56 : /* for stat() */
57 :
58 : /* Unix or Windows NT/2000/XP */
59 : #if !defined(WIN32) && !defined(WIN32CE)
60 : # include <unistd.h>
61 : #elif !defined(WIN32CE) /* not Win32 platform */
62 : # include <io.h>
63 : # include <fcntl.h>
64 : # include <direct.h>
65 : #endif
66 :
67 : /* Windows CE or other platforms */
68 : #if defined(WIN32CE)
69 : # include <wce_io.h>
70 : # include <wce_stat.h>
71 : # include <wce_stdio.h>
72 : # include <wce_string.h>
73 : # include <wce_time.h>
74 : # define time wceex_time
75 : #else
76 : # include <sys/stat.h>
77 : # include <time.h>
78 : #endif
79 :
80 : /************************************************************************/
81 : /* VSIFOpen() */
82 : /************************************************************************/
83 :
84 9139 : FILE *VSIFOpen( const char * pszFilename, const char * pszAccess )
85 :
86 : {
87 9139 : FILE *fp = fopen( (char *) pszFilename, (char *) pszAccess );
88 9139 : int nError = errno;
89 :
90 : VSIDebug3( "VSIFOpen(%s,%s) = %p", pszFilename, pszAccess, fp );
91 :
92 9139 : errno = nError;
93 9139 : return( fp );
94 : }
95 :
96 : /************************************************************************/
97 : /* VSIFClose() */
98 : /************************************************************************/
99 :
100 5915 : int VSIFClose( FILE * fp )
101 :
102 : {
103 : VSIDebug1( "VSIClose(%p)", fp );
104 :
105 5915 : return( fclose(fp) );
106 : }
107 :
108 : /************************************************************************/
109 : /* VSIFSeek() */
110 : /************************************************************************/
111 :
112 411873 : int VSIFSeek( FILE * fp, long nOffset, int nWhence )
113 :
114 : {
115 411873 : int nResult = fseek( fp, nOffset, nWhence );
116 411873 : int nError = errno;
117 :
118 : #ifdef VSI_DEBUG
119 : if( nWhence == SEEK_SET )
120 : {
121 : VSIDebug3( "VSIFSeek(%p,%ld,SEEK_SET) = %d", fp, nOffset, nResult );
122 : }
123 : else if( nWhence == SEEK_END )
124 : {
125 : VSIDebug3( "VSIFSeek(%p,%ld,SEEK_END) = %d", fp, nOffset, nResult );
126 : }
127 : else if( nWhence == SEEK_CUR )
128 : {
129 : VSIDebug3( "VSIFSeek(%p,%ld,SEEK_CUR) = %d", fp, nOffset, nResult );
130 : }
131 : else
132 : {
133 : VSIDebug4( "VSIFSeek(%p,%ld,%d-Unknown) = %d",
134 : fp, nOffset, nWhence, nResult );
135 : }
136 : #endif
137 :
138 411873 : errno = nError;
139 411873 : return nResult;
140 : }
141 :
142 : /************************************************************************/
143 : /* VSIFTell() */
144 : /************************************************************************/
145 :
146 1244554 : long VSIFTell( FILE * fp )
147 :
148 : {
149 1244554 : long nOffset = ftell(fp);
150 1244554 : int nError = errno;
151 :
152 : VSIDebug2( "VSIFTell(%p) = %ld", fp, nOffset );
153 :
154 1244554 : errno = nError;
155 1244554 : return nOffset;
156 : }
157 :
158 : /************************************************************************/
159 : /* VSIRewind() */
160 : /************************************************************************/
161 :
162 5153 : void VSIRewind( FILE * fp )
163 :
164 : {
165 : VSIDebug1("VSIRewind(%p)", fp );
166 5153 : rewind( fp );
167 5153 : }
168 :
169 : /************************************************************************/
170 : /* VSIFRead() */
171 : /************************************************************************/
172 :
173 423686 : size_t VSIFRead( void * pBuffer, size_t nSize, size_t nCount, FILE * fp )
174 :
175 : {
176 423686 : size_t nResult = fread( pBuffer, nSize, nCount, fp );
177 423686 : int nError = errno;
178 :
179 : VSIDebug4( "VSIFRead(%p,%ld,%ld) = %ld",
180 : fp, (long)nSize, (long)nCount, (long)nResult );
181 :
182 423686 : errno = nError;
183 423686 : return nResult;
184 : }
185 :
186 : /************************************************************************/
187 : /* VSIFWrite() */
188 : /************************************************************************/
189 :
190 11801 : size_t VSIFWrite( const void *pBuffer, size_t nSize, size_t nCount, FILE * fp )
191 :
192 : {
193 11801 : size_t nResult = fwrite( pBuffer, nSize, nCount, fp );
194 11801 : int nError = errno;
195 :
196 : VSIDebug4( "VSIFWrite(%p,%ld,%ld) = %ld",
197 : fp, (long)nSize, (long)nCount, (long)nResult );
198 :
199 11801 : errno = nError;
200 11801 : return nResult;
201 : }
202 :
203 : /************************************************************************/
204 : /* VSIFFlush() */
205 : /************************************************************************/
206 :
207 2 : void VSIFFlush( FILE * fp )
208 :
209 : {
210 : VSIDebug1( "VSIFFlush(%p)", fp );
211 2 : fflush( fp );
212 2 : }
213 :
214 : /************************************************************************/
215 : /* VSIFGets() */
216 : /************************************************************************/
217 :
218 197909 : char *VSIFGets( char *pszBuffer, int nBufferSize, FILE * fp )
219 :
220 : {
221 197909 : return( fgets( pszBuffer, nBufferSize, fp ) );
222 : }
223 :
224 : /************************************************************************/
225 : /* VSIFGetc() */
226 : /************************************************************************/
227 :
228 8315 : int VSIFGetc( FILE * fp )
229 :
230 : {
231 8315 : return( fgetc( fp ) );
232 : }
233 :
234 : /************************************************************************/
235 : /* VSIUngetc() */
236 : /************************************************************************/
237 :
238 117 : int VSIUngetc( int c, FILE * fp )
239 :
240 : {
241 117 : return( ungetc( c, fp ) );
242 : }
243 :
244 : /************************************************************************/
245 : /* VSIFPrintf() */
246 : /* */
247 : /* This is a little more complicated than just calling */
248 : /* fprintf() because of the variable arguments. Instead we */
249 : /* have to use vfprintf(). */
250 : /************************************************************************/
251 :
252 958 : int VSIFPrintf( FILE * fp, const char * pszFormat, ... )
253 :
254 : {
255 : va_list args;
256 : int nReturn;
257 :
258 958 : va_start( args, pszFormat );
259 958 : nReturn = vfprintf( fp, pszFormat, args );
260 958 : va_end( args );
261 :
262 958 : return( nReturn );
263 : }
264 :
265 : /************************************************************************/
266 : /* VSIFEof() */
267 : /************************************************************************/
268 :
269 1082 : int VSIFEof( FILE * fp )
270 :
271 : {
272 1082 : return( feof( fp ) );
273 : }
274 :
275 : /************************************************************************/
276 : /* VSIFPuts() */
277 : /************************************************************************/
278 :
279 0 : int VSIFPuts( const char * pszString, FILE * fp )
280 :
281 : {
282 0 : return fputs( pszString, fp );
283 : }
284 :
285 : /************************************************************************/
286 : /* VSIFPutc() */
287 : /************************************************************************/
288 :
289 41 : int VSIFPutc( int nChar, FILE * fp )
290 :
291 : {
292 41 : return( fputc( nChar, fp ) );
293 : }
294 :
295 :
296 : #ifdef DEBUG_VSIMALLOC_STATS
297 : #include "cpl_multiproc.h"
298 :
299 : static void* hMemStatMutex = 0;
300 : static size_t nCurrentTotalAllocs = 0;
301 : static size_t nMaxTotalAllocs = 0;
302 : static GUIntBig nVSIMallocs = 0;
303 : static GUIntBig nVSICallocs = 0;
304 : static GUIntBig nVSIReallocs = 0;
305 : static GUIntBig nVSIFrees = 0;
306 :
307 : /************************************************************************/
308 : /* VSIShowMemStats() */
309 : /************************************************************************/
310 :
311 : void VSIShowMemStats()
312 : {
313 : printf("Current VSI memory usage : " CPL_FRMT_GUIB " bytes\n",
314 : (GUIntBig)nCurrentTotalAllocs);
315 : printf("Maximum VSI memory usage : " CPL_FRMT_GUIB " bytes\n",
316 : (GUIntBig)nMaxTotalAllocs);
317 : printf("Number of calls to VSIMalloc() : " CPL_FRMT_GUIB "\n",
318 : nVSIMallocs);
319 : printf("Number of calls to VSICalloc() : " CPL_FRMT_GUIB "\n",
320 : nVSICallocs);
321 : printf("Number of calls to VSIRealloc() : " CPL_FRMT_GUIB "\n",
322 : nVSIReallocs);
323 : printf("Number of calls to VSIFree() : " CPL_FRMT_GUIB "\n",
324 : nVSIFrees);
325 : printf("VSIMalloc + VSICalloc - VSIFree : " CPL_FRMT_GUIB "\n",
326 : nVSIMallocs + nVSICallocs - nVSIFrees);
327 : }
328 : #endif
329 :
330 : /************************************************************************/
331 : /* VSICalloc() */
332 : /************************************************************************/
333 :
334 1128838 : void *VSICalloc( size_t nCount, size_t nSize )
335 :
336 : {
337 : #ifdef DEBUG_VSIMALLOC
338 : void* ptr = VSIMalloc(nCount * nSize);
339 : memset(ptr, 0, nCount * nSize);
340 : #ifdef DEBUG_VSIMALLOC_STATS
341 : {
342 : CPLMutexHolderD(&hMemStatMutex);
343 : nVSICallocs ++;
344 : nVSIMallocs --;
345 : }
346 : #endif
347 : return ptr;
348 : #else
349 1128838 : return( calloc( nCount, nSize ) );
350 : #endif
351 : }
352 :
353 : /************************************************************************/
354 : /* VSIMalloc() */
355 : /************************************************************************/
356 :
357 1818547 : void *VSIMalloc( size_t nSize )
358 :
359 : {
360 : #ifdef DEBUG_VSIMALLOC
361 : char* ptr = (char*) malloc(4 + sizeof(size_t) + nSize);
362 : ptr[0] = 'V';
363 : ptr[1] = 'S';
364 : ptr[2] = 'I';
365 : ptr[3] = 'M';
366 : memcpy(ptr + 4, &nSize, sizeof(size_t));
367 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
368 : {
369 : CPLMutexHolderD(&hMemStatMutex);
370 : #ifdef DEBUG_VSIMALLOC_VERBOSE
371 : fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p\n",
372 : (void*)CPLGetPID(), (int)nSize, ptr + 4 + sizeof(size_t));
373 : #endif
374 : #ifdef DEBUG_VSIMALLOC_STATS
375 : nVSIMallocs ++;
376 : if (nMaxTotalAllocs == 0)
377 : atexit(VSIShowMemStats);
378 : nCurrentTotalAllocs += nSize;
379 : if (nCurrentTotalAllocs > nMaxTotalAllocs)
380 : nMaxTotalAllocs = nCurrentTotalAllocs;
381 : #endif
382 : }
383 : #endif
384 : return ptr + 4 + sizeof(size_t);
385 : #else
386 1818547 : return( malloc( nSize ) );
387 : #endif
388 : }
389 :
390 : #ifdef DEBUG_VSIMALLOC
391 : void VSICheckMarker(char* ptr)
392 : {
393 : if (memcmp(ptr, "VSIM", 4) != 0)
394 : {
395 : CPLError(CE_Fatal, CPLE_AppDefined,
396 : "Inconsistant use of VSI memory allocation primitives for %p : %c%c%c%c",
397 : ptr, ptr[0], ptr[1], ptr[2], ptr[3]);
398 : }
399 : }
400 :
401 : #endif
402 :
403 : /************************************************************************/
404 : /* VSIRealloc() */
405 : /************************************************************************/
406 :
407 1717580 : void * VSIRealloc( void * pData, size_t nNewSize )
408 :
409 : {
410 : #ifdef DEBUG_VSIMALLOC
411 : if (pData == NULL)
412 : return VSIMalloc(nNewSize);
413 :
414 : char* ptr = ((char*)pData) - 4 - sizeof(size_t);
415 : VSICheckMarker(ptr);
416 : #ifdef DEBUG_VSIMALLOC_STATS
417 : size_t nOldSize;
418 : memcpy(&nOldSize, ptr + 4, sizeof(size_t));
419 : #endif
420 :
421 : ptr = (char*) realloc(ptr, nNewSize + 4 + sizeof(size_t));
422 : memcpy(ptr + 4, &nNewSize, sizeof(size_t));
423 :
424 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
425 : {
426 : CPLMutexHolderD(&hMemStatMutex);
427 : #ifdef DEBUG_VSIMALLOC_VERBOSE
428 : fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n",
429 : (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 4 + sizeof(size_t));
430 : #endif
431 : #ifdef DEBUG_VSIMALLOC_STATS
432 : nVSIReallocs ++;
433 : nCurrentTotalAllocs -= nOldSize;
434 : nCurrentTotalAllocs += nNewSize;
435 : if (nCurrentTotalAllocs > nMaxTotalAllocs)
436 : nMaxTotalAllocs = nCurrentTotalAllocs;
437 : #endif
438 : }
439 : #endif
440 : return ptr + 4 + sizeof(size_t);
441 : #else
442 1717580 : return( realloc( pData, nNewSize ) );
443 : #endif
444 : }
445 :
446 : /************************************************************************/
447 : /* VSIFree() */
448 : /************************************************************************/
449 :
450 8051186 : void VSIFree( void * pData )
451 :
452 : {
453 : #ifdef DEBUG_VSIMALLOC
454 : if (pData == NULL)
455 : return;
456 :
457 : char* ptr = ((char*)pData) - 4 - sizeof(size_t);
458 : VSICheckMarker(ptr);
459 : ptr[0] = 'M';
460 : ptr[1] = 'I';
461 : ptr[2] = 'S';
462 : ptr[3] = 'V';
463 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
464 : size_t nOldSize;
465 : memcpy(&nOldSize, ptr + 4, sizeof(size_t));
466 : {
467 : CPLMutexHolderD(&hMemStatMutex);
468 : #ifdef DEBUG_VSIMALLOC_VERBOSE
469 : fprintf(stderr, "Thread[%p] VSIFree(%p, (%d bytes))\n",
470 : (void*)CPLGetPID(), pData, (int)nOldSize);
471 : #endif
472 : #ifdef DEBUG_VSIMALLOC_STATS
473 : nVSIFrees ++;
474 : nCurrentTotalAllocs -= nOldSize;
475 : #endif
476 : }
477 : #endif
478 : free(ptr);
479 : #else
480 8051186 : if( pData != NULL )
481 5156517 : free( pData );
482 : #endif
483 8051186 : }
484 :
485 : /************************************************************************/
486 : /* VSIStrdup() */
487 : /************************************************************************/
488 :
489 2137828 : char *VSIStrdup( const char * pszString )
490 :
491 : {
492 : #ifdef DEBUG_VSIMALLOC
493 : int nSize = strlen(pszString) + 1;
494 : char* ptr = (char*) VSIMalloc(nSize);
495 : memcpy(ptr, pszString, nSize);
496 : return ptr;
497 : #else
498 2137828 : return( strdup( pszString ) );
499 : #endif
500 : }
501 :
502 : /************************************************************************/
503 : /* VSICheckMul2() */
504 : /************************************************************************/
505 :
506 12808 : static size_t VSICheckMul2( size_t mul1, size_t mul2, int *pbOverflowFlag)
507 : {
508 12808 : size_t res = mul1 * mul2;
509 12808 : if (mul1 != 0)
510 : {
511 12808 : if (res / mul1 == mul2)
512 : {
513 12808 : if (pbOverflowFlag)
514 12808 : *pbOverflowFlag = FALSE;
515 12808 : return res;
516 : }
517 : else
518 : {
519 0 : if (pbOverflowFlag)
520 0 : *pbOverflowFlag = TRUE;
521 : CPLError(CE_Failure, CPLE_OutOfMemory,
522 : "Multiplication overflow : %lu * %lu",
523 0 : (unsigned long)mul1, (unsigned long)mul2);
524 : }
525 : }
526 : else
527 : {
528 0 : if (pbOverflowFlag)
529 0 : *pbOverflowFlag = FALSE;
530 : }
531 0 : return 0;
532 : }
533 :
534 : /************************************************************************/
535 : /* VSICheckMul3() */
536 : /************************************************************************/
537 :
538 6823 : static size_t VSICheckMul3( size_t mul1, size_t mul2, size_t mul3, int *pbOverflowFlag)
539 : {
540 6823 : if (mul1 != 0)
541 : {
542 6823 : size_t res = mul1 * mul2;
543 6823 : if (res / mul1 == mul2)
544 : {
545 6823 : size_t res2 = res * mul3;
546 6823 : if (mul3 != 0)
547 : {
548 6823 : if (res2 / mul3 == res)
549 : {
550 6823 : if (pbOverflowFlag)
551 6823 : *pbOverflowFlag = FALSE;
552 6823 : return res2;
553 : }
554 : else
555 : {
556 0 : if (pbOverflowFlag)
557 0 : *pbOverflowFlag = TRUE;
558 : CPLError(CE_Failure, CPLE_OutOfMemory,
559 : "Multiplication overflow : %lu * %lu * %lu",
560 0 : (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
561 : }
562 : }
563 : else
564 : {
565 0 : if (pbOverflowFlag)
566 0 : *pbOverflowFlag = FALSE;
567 : }
568 : }
569 : else
570 : {
571 0 : if (pbOverflowFlag)
572 0 : *pbOverflowFlag = TRUE;
573 : CPLError(CE_Failure, CPLE_OutOfMemory,
574 : "Multiplication overflow : %lu * %lu * %lu",
575 0 : (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
576 : }
577 : }
578 : else
579 : {
580 0 : if (pbOverflowFlag)
581 0 : *pbOverflowFlag = FALSE;
582 : }
583 0 : return 0;
584 : }
585 :
586 :
587 :
588 : /**
589 : VSIMalloc2 allocates (nSize1 * nSize2) bytes.
590 : In case of overflow of the multiplication, or if memory allocation fails, a
591 : NULL pointer is returned and a CE_Failure error is raised with CPLError().
592 : If nSize1 == 0 || nSize2 == 0, a NULL pointer will also be returned.
593 : CPLFree() or VSIFree() can be used to free memory allocated by this function.
594 : */
595 12808 : void CPL_DLL *VSIMalloc2( size_t nSize1, size_t nSize2 )
596 : {
597 12808 : int bOverflowFlag = FALSE;
598 : size_t nSizeToAllocate;
599 : void* pReturn;
600 :
601 12808 : nSizeToAllocate = VSICheckMul2( nSize1, nSize2, &bOverflowFlag );
602 12808 : if (bOverflowFlag)
603 0 : return NULL;
604 :
605 12808 : if (nSizeToAllocate == 0)
606 13 : return NULL;
607 :
608 12795 : pReturn = VSIMalloc(nSizeToAllocate);
609 :
610 12795 : if( pReturn == NULL )
611 : {
612 : CPLError( CE_Failure, CPLE_OutOfMemory,
613 : "VSIMalloc2(): Out of memory allocating %lu bytes.\n",
614 0 : (unsigned long)nSizeToAllocate );
615 : }
616 :
617 12795 : return pReturn;
618 : }
619 :
620 : /**
621 : VSIMalloc3 allocates (nSize1 * nSize2 * nSize3) bytes.
622 : In case of overflow of the multiplication, or if memory allocation fails, a
623 : NULL pointer is returned and a CE_Failure error is raised with CPLError().
624 : If nSize1 == 0 || nSize2 == 0 || nSize3 == 0, a NULL pointer will also be returned.
625 : CPLFree() or VSIFree() can be used to free memory allocated by this function.
626 : */
627 6823 : void CPL_DLL *VSIMalloc3( size_t nSize1, size_t nSize2, size_t nSize3 )
628 : {
629 6823 : int bOverflowFlag = FALSE;
630 :
631 : size_t nSizeToAllocate;
632 : void* pReturn;
633 :
634 6823 : nSizeToAllocate = VSICheckMul3( nSize1, nSize2, nSize3, &bOverflowFlag );
635 6823 : if (bOverflowFlag)
636 0 : return NULL;
637 :
638 6823 : if (nSizeToAllocate == 0)
639 0 : return NULL;
640 :
641 6823 : pReturn = VSIMalloc(nSizeToAllocate);
642 :
643 6823 : if( pReturn == NULL )
644 : {
645 : CPLError( CE_Failure, CPLE_OutOfMemory,
646 : "VSIMalloc3(): Out of memory allocating %lu bytes.\n",
647 0 : (unsigned long)nSizeToAllocate );
648 : }
649 :
650 6823 : return pReturn;
651 : }
652 :
653 :
654 : /************************************************************************/
655 : /* VSIStat() */
656 : /************************************************************************/
657 :
658 2527 : int VSIStat( const char * pszFilename, VSIStatBuf * pStatBuf )
659 :
660 : {
661 : #if defined(macos_pre10)
662 : return -1;
663 : #else
664 2527 : return( stat( pszFilename, pStatBuf ) );
665 : #endif
666 : }
667 :
668 : /************************************************************************/
669 : /* VSITime() */
670 : /************************************************************************/
671 :
672 0 : unsigned long VSITime( unsigned long * pnTimeToSet )
673 :
674 : {
675 : time_t tTime;
676 :
677 0 : tTime = time( NULL );
678 :
679 0 : if( pnTimeToSet != NULL )
680 0 : *pnTimeToSet = (unsigned long) tTime;
681 :
682 0 : return (unsigned long) tTime;
683 : }
684 :
685 : /************************************************************************/
686 : /* VSICTime() */
687 : /************************************************************************/
688 :
689 0 : const char *VSICTime( unsigned long nTime )
690 :
691 : {
692 0 : time_t tTime = (time_t) nTime;
693 :
694 0 : return (const char *) ctime( &tTime );
695 : }
696 :
697 : /************************************************************************/
698 : /* VSIGMTime() */
699 : /************************************************************************/
700 :
701 0 : struct tm *VSIGMTime( const time_t *pnTime, struct tm *poBrokenTime )
702 : {
703 :
704 : #if HAVE_GMTIME_R
705 : gmtime_r( pnTime, poBrokenTime );
706 : #else
707 : struct tm *poTime;
708 0 : poTime = gmtime( pnTime );
709 0 : memcpy( poBrokenTime, poTime, sizeof(tm) );
710 : #endif
711 :
712 0 : return poBrokenTime;
713 : }
714 :
715 : /************************************************************************/
716 : /* VSILocalTime() */
717 : /************************************************************************/
718 :
719 0 : struct tm *VSILocalTime( const time_t *pnTime, struct tm *poBrokenTime )
720 : {
721 :
722 : #if HAVE_LOCALTIME_R
723 : localtime_r( pnTime, poBrokenTime );
724 : #else
725 : struct tm *poTime;
726 0 : poTime = localtime( pnTime );
727 0 : memcpy( poBrokenTime, poTime, sizeof(tm) );
728 : #endif
729 :
730 0 : return poBrokenTime;
731 : }
732 :
733 : /************************************************************************/
734 : /* VSIStrerror() */
735 : /************************************************************************/
736 :
737 0 : char *VSIStrerror( int nErrno )
738 :
739 : {
740 0 : return strerror( nErrno );
741 : }
|