1 : /******************************************************************************
2 : * $Id: cpl_vsisimple.cpp 19857 2010-06-13 11:53:31Z 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 19857 2010-06-13 11:53:31Z 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 8665 : FILE *VSIFOpen( const char * pszFilename, const char * pszAccess )
85 :
86 : {
87 8665 : FILE *fp = fopen( (char *) pszFilename, (char *) pszAccess );
88 8665 : int nError = errno;
89 :
90 : VSIDebug3( "VSIFOpen(%s,%s) = %p", pszFilename, pszAccess, fp );
91 :
92 8665 : errno = nError;
93 8665 : return( fp );
94 : }
95 :
96 : /************************************************************************/
97 : /* VSIFClose() */
98 : /************************************************************************/
99 :
100 7956 : int VSIFClose( FILE * fp )
101 :
102 : {
103 : VSIDebug1( "VSIClose(%p)", fp );
104 :
105 7956 : return( fclose(fp) );
106 : }
107 :
108 : /************************************************************************/
109 : /* VSIFSeek() */
110 : /************************************************************************/
111 :
112 408869 : int VSIFSeek( FILE * fp, long nOffset, int nWhence )
113 :
114 : {
115 408869 : int nResult = fseek( fp, nOffset, nWhence );
116 408869 : 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 408869 : errno = nError;
139 408869 : return nResult;
140 : }
141 :
142 : /************************************************************************/
143 : /* VSIFTell() */
144 : /************************************************************************/
145 :
146 1489823 : long VSIFTell( FILE * fp )
147 :
148 : {
149 1489823 : long nOffset = ftell(fp);
150 1489823 : int nError = errno;
151 :
152 : VSIDebug2( "VSIFTell(%p) = %ld", fp, nOffset );
153 :
154 1489823 : errno = nError;
155 1489823 : return nOffset;
156 : }
157 :
158 : /************************************************************************/
159 : /* VSIRewind() */
160 : /************************************************************************/
161 :
162 6686 : void VSIRewind( FILE * fp )
163 :
164 : {
165 : VSIDebug1("VSIRewind(%p)", fp );
166 6686 : rewind( fp );
167 6686 : }
168 :
169 : /************************************************************************/
170 : /* VSIFRead() */
171 : /************************************************************************/
172 :
173 424187 : size_t VSIFRead( void * pBuffer, size_t nSize, size_t nCount, FILE * fp )
174 :
175 : {
176 424187 : size_t nResult = fread( pBuffer, nSize, nCount, fp );
177 424187 : int nError = errno;
178 :
179 : VSIDebug4( "VSIFRead(%p,%ld,%ld) = %ld",
180 : fp, (long)nSize, (long)nCount, (long)nResult );
181 :
182 424187 : errno = nError;
183 424187 : return nResult;
184 : }
185 :
186 : /************************************************************************/
187 : /* VSIFWrite() */
188 : /************************************************************************/
189 :
190 11999 : size_t VSIFWrite( const void *pBuffer, size_t nSize, size_t nCount, FILE * fp )
191 :
192 : {
193 11999 : size_t nResult = fwrite( pBuffer, nSize, nCount, fp );
194 11999 : int nError = errno;
195 :
196 : VSIDebug4( "VSIFWrite(%p,%ld,%ld) = %ld",
197 : fp, (long)nSize, (long)nCount, (long)nResult );
198 :
199 11999 : errno = nError;
200 11999 : 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 443612 : char *VSIFGets( char *pszBuffer, int nBufferSize, FILE * fp )
219 :
220 : {
221 443612 : return( fgets( pszBuffer, nBufferSize, fp ) );
222 : }
223 :
224 : /************************************************************************/
225 : /* VSIFGetc() */
226 : /************************************************************************/
227 :
228 8375 : int VSIFGetc( FILE * fp )
229 :
230 : {
231 8375 : 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 164 : int VSIFPrintf( FILE * fp, const char * pszFormat, ... )
253 :
254 : {
255 : va_list args;
256 : int nReturn;
257 :
258 164 : va_start( args, pszFormat );
259 164 : nReturn = vfprintf( fp, pszFormat, args );
260 164 : va_end( args );
261 :
262 164 : return( nReturn );
263 : }
264 :
265 : /************************************************************************/
266 : /* VSIFEof() */
267 : /************************************************************************/
268 :
269 241274 : int VSIFEof( FILE * fp )
270 :
271 : {
272 241274 : 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 1866374 : void *VSICalloc( size_t nCount, size_t nSize )
335 :
336 : {
337 : #ifdef DEBUG_VSIMALLOC
338 : size_t nMul = nCount * nSize;
339 : if (nCount != 0 && nMul / nCount != nSize)
340 : {
341 : fprintf(stderr, "Overflow in VSICalloc(%d, %d)\n",
342 : (int)nCount, (int)nSize);
343 : return NULL;
344 : }
345 : void* ptr = VSIMalloc(nCount * nSize);
346 : if (ptr == NULL)
347 : return NULL;
348 :
349 : memset(ptr, 0, nCount * nSize);
350 : #ifdef DEBUG_VSIMALLOC_STATS
351 : {
352 : CPLMutexHolderD(&hMemStatMutex);
353 : nVSICallocs ++;
354 : nVSIMallocs --;
355 : }
356 : #endif
357 : return ptr;
358 : #else
359 1866374 : return( calloc( nCount, nSize ) );
360 : #endif
361 : }
362 :
363 : /************************************************************************/
364 : /* VSIMalloc() */
365 : /************************************************************************/
366 :
367 2954636 : void *VSIMalloc( size_t nSize )
368 :
369 : {
370 : #ifdef DEBUG_VSIMALLOC
371 : char* ptr = (char*) malloc(4 + sizeof(size_t) + nSize);
372 : if (ptr == NULL)
373 : return NULL;
374 : ptr[0] = 'V';
375 : ptr[1] = 'S';
376 : ptr[2] = 'I';
377 : ptr[3] = 'M';
378 : memcpy(ptr + 4, &nSize, sizeof(size_t));
379 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
380 : {
381 : CPLMutexHolderD(&hMemStatMutex);
382 : #ifdef DEBUG_VSIMALLOC_VERBOSE
383 : fprintf(stderr, "Thread[%p] VSIMalloc(%d) = %p\n",
384 : (void*)CPLGetPID(), (int)nSize, ptr + 4 + sizeof(size_t));
385 : #endif
386 : #ifdef DEBUG_VSIMALLOC_STATS
387 : nVSIMallocs ++;
388 : if (nMaxTotalAllocs == 0)
389 : atexit(VSIShowMemStats);
390 : nCurrentTotalAllocs += nSize;
391 : if (nCurrentTotalAllocs > nMaxTotalAllocs)
392 : nMaxTotalAllocs = nCurrentTotalAllocs;
393 : #endif
394 : }
395 : #endif
396 : return ptr + 4 + sizeof(size_t);
397 : #else
398 2954636 : return( malloc( nSize ) );
399 : #endif
400 : }
401 :
402 : #ifdef DEBUG_VSIMALLOC
403 : void VSICheckMarker(char* ptr)
404 : {
405 : if (memcmp(ptr, "VSIM", 4) != 0)
406 : {
407 : CPLError(CE_Fatal, CPLE_AppDefined,
408 : "Inconsistant use of VSI memory allocation primitives for %p : %c%c%c%c",
409 : ptr, ptr[0], ptr[1], ptr[2], ptr[3]);
410 : }
411 : }
412 :
413 : #endif
414 :
415 : /************************************************************************/
416 : /* VSIRealloc() */
417 : /************************************************************************/
418 :
419 6226991 : void * VSIRealloc( void * pData, size_t nNewSize )
420 :
421 : {
422 : #ifdef DEBUG_VSIMALLOC
423 : if (pData == NULL)
424 : return VSIMalloc(nNewSize);
425 :
426 : char* ptr = ((char*)pData) - 4 - sizeof(size_t);
427 : VSICheckMarker(ptr);
428 : #ifdef DEBUG_VSIMALLOC_STATS
429 : size_t nOldSize;
430 : memcpy(&nOldSize, ptr + 4, sizeof(size_t));
431 : #endif
432 :
433 : ptr = (char*) realloc(ptr, nNewSize + 4 + sizeof(size_t));
434 : if (ptr == NULL)
435 : return NULL;
436 : memcpy(ptr + 4, &nNewSize, sizeof(size_t));
437 :
438 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
439 : {
440 : CPLMutexHolderD(&hMemStatMutex);
441 : #ifdef DEBUG_VSIMALLOC_VERBOSE
442 : fprintf(stderr, "Thread[%p] VSIRealloc(%p, %d) = %p\n",
443 : (void*)CPLGetPID(), pData, (int)nNewSize, ptr + 4 + sizeof(size_t));
444 : #endif
445 : #ifdef DEBUG_VSIMALLOC_STATS
446 : nVSIReallocs ++;
447 : nCurrentTotalAllocs -= nOldSize;
448 : nCurrentTotalAllocs += nNewSize;
449 : if (nCurrentTotalAllocs > nMaxTotalAllocs)
450 : nMaxTotalAllocs = nCurrentTotalAllocs;
451 : #endif
452 : }
453 : #endif
454 : return ptr + 4 + sizeof(size_t);
455 : #else
456 6226991 : return( realloc( pData, nNewSize ) );
457 : #endif
458 : }
459 :
460 : /************************************************************************/
461 : /* VSIFree() */
462 : /************************************************************************/
463 :
464 14823454 : void VSIFree( void * pData )
465 :
466 : {
467 : #ifdef DEBUG_VSIMALLOC
468 : if (pData == NULL)
469 : return;
470 :
471 : char* ptr = ((char*)pData) - 4 - sizeof(size_t);
472 : VSICheckMarker(ptr);
473 : ptr[0] = 'M';
474 : ptr[1] = 'I';
475 : ptr[2] = 'S';
476 : ptr[3] = 'V';
477 : #if defined(DEBUG_VSIMALLOC_STATS) || defined(DEBUG_VSIMALLOC_VERBOSE)
478 : size_t nOldSize;
479 : memcpy(&nOldSize, ptr + 4, sizeof(size_t));
480 : {
481 : CPLMutexHolderD(&hMemStatMutex);
482 : #ifdef DEBUG_VSIMALLOC_VERBOSE
483 : fprintf(stderr, "Thread[%p] VSIFree(%p, (%d bytes))\n",
484 : (void*)CPLGetPID(), pData, (int)nOldSize);
485 : #endif
486 : #ifdef DEBUG_VSIMALLOC_STATS
487 : nVSIFrees ++;
488 : nCurrentTotalAllocs -= nOldSize;
489 : #endif
490 : }
491 : #endif
492 : free(ptr);
493 : #else
494 14823454 : if( pData != NULL )
495 11239105 : free( pData );
496 : #endif
497 14823454 : }
498 :
499 : /************************************************************************/
500 : /* VSIStrdup() */
501 : /************************************************************************/
502 :
503 6330837 : char *VSIStrdup( const char * pszString )
504 :
505 : {
506 : #ifdef DEBUG_VSIMALLOC
507 : int nSize = strlen(pszString) + 1;
508 : char* ptr = (char*) VSIMalloc(nSize);
509 : if (ptr == NULL)
510 : return NULL;
511 : memcpy(ptr, pszString, nSize);
512 : return ptr;
513 : #else
514 6330837 : return( strdup( pszString ) );
515 : #endif
516 : }
517 :
518 : /************************************************************************/
519 : /* VSICheckMul2() */
520 : /************************************************************************/
521 :
522 15140 : static size_t VSICheckMul2( size_t mul1, size_t mul2, int *pbOverflowFlag)
523 : {
524 15140 : size_t res = mul1 * mul2;
525 15140 : if (mul1 != 0)
526 : {
527 15140 : if (res / mul1 == mul2)
528 : {
529 15140 : if (pbOverflowFlag)
530 15140 : *pbOverflowFlag = FALSE;
531 15140 : return res;
532 : }
533 : else
534 : {
535 0 : if (pbOverflowFlag)
536 0 : *pbOverflowFlag = TRUE;
537 : CPLError(CE_Failure, CPLE_OutOfMemory,
538 : "Multiplication overflow : %lu * %lu",
539 0 : (unsigned long)mul1, (unsigned long)mul2);
540 : }
541 : }
542 : else
543 : {
544 0 : if (pbOverflowFlag)
545 0 : *pbOverflowFlag = FALSE;
546 : }
547 0 : return 0;
548 : }
549 :
550 : /************************************************************************/
551 : /* VSICheckMul3() */
552 : /************************************************************************/
553 :
554 7015 : static size_t VSICheckMul3( size_t mul1, size_t mul2, size_t mul3, int *pbOverflowFlag)
555 : {
556 7015 : if (mul1 != 0)
557 : {
558 7015 : size_t res = mul1 * mul2;
559 7015 : if (res / mul1 == mul2)
560 : {
561 7015 : size_t res2 = res * mul3;
562 7015 : if (mul3 != 0)
563 : {
564 7015 : if (res2 / mul3 == res)
565 : {
566 7015 : if (pbOverflowFlag)
567 7015 : *pbOverflowFlag = FALSE;
568 7015 : return res2;
569 : }
570 : else
571 : {
572 0 : if (pbOverflowFlag)
573 0 : *pbOverflowFlag = TRUE;
574 : CPLError(CE_Failure, CPLE_OutOfMemory,
575 : "Multiplication overflow : %lu * %lu * %lu",
576 0 : (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
577 : }
578 : }
579 : else
580 : {
581 0 : if (pbOverflowFlag)
582 0 : *pbOverflowFlag = FALSE;
583 : }
584 : }
585 : else
586 : {
587 0 : if (pbOverflowFlag)
588 0 : *pbOverflowFlag = TRUE;
589 : CPLError(CE_Failure, CPLE_OutOfMemory,
590 : "Multiplication overflow : %lu * %lu * %lu",
591 0 : (unsigned long)mul1, (unsigned long)mul2, (unsigned long)mul3);
592 : }
593 : }
594 : else
595 : {
596 0 : if (pbOverflowFlag)
597 0 : *pbOverflowFlag = FALSE;
598 : }
599 0 : return 0;
600 : }
601 :
602 :
603 :
604 : /**
605 : VSIMalloc2 allocates (nSize1 * nSize2) bytes.
606 : In case of overflow of the multiplication, or if memory allocation fails, a
607 : NULL pointer is returned and a CE_Failure error is raised with CPLError().
608 : If nSize1 == 0 || nSize2 == 0, a NULL pointer will also be returned.
609 : CPLFree() or VSIFree() can be used to free memory allocated by this function.
610 : */
611 15140 : void CPL_DLL *VSIMalloc2( size_t nSize1, size_t nSize2 )
612 : {
613 15140 : int bOverflowFlag = FALSE;
614 : size_t nSizeToAllocate;
615 : void* pReturn;
616 :
617 15140 : nSizeToAllocate = VSICheckMul2( nSize1, nSize2, &bOverflowFlag );
618 15140 : if (bOverflowFlag)
619 0 : return NULL;
620 :
621 15140 : if (nSizeToAllocate == 0)
622 62 : return NULL;
623 :
624 15078 : pReturn = VSIMalloc(nSizeToAllocate);
625 :
626 15078 : if( pReturn == NULL )
627 : {
628 : CPLError( CE_Failure, CPLE_OutOfMemory,
629 : "VSIMalloc2(): Out of memory allocating %lu bytes.\n",
630 0 : (unsigned long)nSizeToAllocate );
631 : }
632 :
633 15078 : return pReturn;
634 : }
635 :
636 : /**
637 : VSIMalloc3 allocates (nSize1 * nSize2 * nSize3) bytes.
638 : In case of overflow of the multiplication, or if memory allocation fails, a
639 : NULL pointer is returned and a CE_Failure error is raised with CPLError().
640 : If nSize1 == 0 || nSize2 == 0 || nSize3 == 0, a NULL pointer will also be returned.
641 : CPLFree() or VSIFree() can be used to free memory allocated by this function.
642 : */
643 7015 : void CPL_DLL *VSIMalloc3( size_t nSize1, size_t nSize2, size_t nSize3 )
644 : {
645 7015 : int bOverflowFlag = FALSE;
646 :
647 : size_t nSizeToAllocate;
648 : void* pReturn;
649 :
650 7015 : nSizeToAllocate = VSICheckMul3( nSize1, nSize2, nSize3, &bOverflowFlag );
651 7015 : if (bOverflowFlag)
652 0 : return NULL;
653 :
654 7015 : if (nSizeToAllocate == 0)
655 0 : return NULL;
656 :
657 7015 : pReturn = VSIMalloc(nSizeToAllocate);
658 :
659 7015 : if( pReturn == NULL )
660 : {
661 : CPLError( CE_Failure, CPLE_OutOfMemory,
662 : "VSIMalloc3(): Out of memory allocating %lu bytes.\n",
663 0 : (unsigned long)nSizeToAllocate );
664 : }
665 :
666 7015 : return pReturn;
667 : }
668 :
669 :
670 : /************************************************************************/
671 : /* VSIStat() */
672 : /************************************************************************/
673 :
674 3181 : int VSIStat( const char * pszFilename, VSIStatBuf * pStatBuf )
675 :
676 : {
677 : #if defined(macos_pre10)
678 : return -1;
679 : #else
680 3181 : return( stat( pszFilename, pStatBuf ) );
681 : #endif
682 : }
683 :
684 : /************************************************************************/
685 : /* VSITime() */
686 : /************************************************************************/
687 :
688 0 : unsigned long VSITime( unsigned long * pnTimeToSet )
689 :
690 : {
691 : time_t tTime;
692 :
693 0 : tTime = time( NULL );
694 :
695 0 : if( pnTimeToSet != NULL )
696 0 : *pnTimeToSet = (unsigned long) tTime;
697 :
698 0 : return (unsigned long) tTime;
699 : }
700 :
701 : /************************************************************************/
702 : /* VSICTime() */
703 : /************************************************************************/
704 :
705 0 : const char *VSICTime( unsigned long nTime )
706 :
707 : {
708 0 : time_t tTime = (time_t) nTime;
709 :
710 0 : return (const char *) ctime( &tTime );
711 : }
712 :
713 : /************************************************************************/
714 : /* VSIGMTime() */
715 : /************************************************************************/
716 :
717 0 : struct tm *VSIGMTime( const time_t *pnTime, struct tm *poBrokenTime )
718 : {
719 :
720 : #if HAVE_GMTIME_R
721 : gmtime_r( pnTime, poBrokenTime );
722 : #else
723 : struct tm *poTime;
724 0 : poTime = gmtime( pnTime );
725 0 : memcpy( poBrokenTime, poTime, sizeof(tm) );
726 : #endif
727 :
728 0 : return poBrokenTime;
729 : }
730 :
731 : /************************************************************************/
732 : /* VSILocalTime() */
733 : /************************************************************************/
734 :
735 0 : struct tm *VSILocalTime( const time_t *pnTime, struct tm *poBrokenTime )
736 : {
737 :
738 : #if HAVE_LOCALTIME_R
739 : localtime_r( pnTime, poBrokenTime );
740 : #else
741 : struct tm *poTime;
742 0 : poTime = localtime( pnTime );
743 0 : memcpy( poBrokenTime, poTime, sizeof(tm) );
744 : #endif
745 :
746 0 : return poBrokenTime;
747 : }
748 :
749 : /************************************************************************/
750 : /* VSIStrerror() */
751 : /************************************************************************/
752 :
753 0 : char *VSIStrerror( int nErrno )
754 :
755 : {
756 0 : return strerror( nErrno );
757 : }
|