00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020
00021 #include <ftconfig.h>
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_SYSTEM_H
00024 #include FT_ERRORS_H
00025 #include FT_TYPES_H
00026 #include FT_INTERNAL_STREAM_H
00027
00028
00029 #ifdef HAVE_UNISTD_H
00030 #include <unistd.h>
00031 #endif
00032
00033 #include <sys/mman.h>
00034 #ifndef MAP_FILE
00035 #define MAP_FILE 0x00
00036 #endif
00037
00038 #ifdef MUNMAP_USES_VOIDP
00039 #define MUNMAP_ARG_CAST void *
00040 #else
00041 #define MUNMAP_ARG_CAST char *
00042 #endif
00043
00044 #ifdef NEED_MUNMAP_DECL
00045
00046 #ifdef __cplusplus
00047 extern "C"
00048 #else
00049 extern
00050 #endif
00051 int
00052 munmap( char* addr,
00053 int len );
00054
00055 #define MUNMAP_ARG_CAST char *
00056
00057 #endif
00058
00059
00060 #include <sys/types.h>
00061 #include <sys/stat.h>
00062
00063 #ifdef HAVE_FCNTL_H
00064 #include <fcntl.h>
00065 #endif
00066
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <string.h>
00070 #include <errno.h>
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 FT_CALLBACK_DEF( void* )
00097 ft_alloc( FT_Memory memory,
00098 long size )
00099 {
00100 FT_UNUSED( memory );
00101
00102 return malloc( size );
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 FT_CALLBACK_DEF( void* )
00127 ft_realloc( FT_Memory memory,
00128 long cur_size,
00129 long new_size,
00130 void* block )
00131 {
00132 FT_UNUSED( memory );
00133 FT_UNUSED( cur_size );
00134
00135 return realloc( block, new_size );
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 FT_CALLBACK_DEF( void )
00153 ft_free( FT_Memory memory,
00154 void* block )
00155 {
00156 FT_UNUSED( memory );
00157
00158 free( block );
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 #undef FT_COMPONENT
00176 #define FT_COMPONENT trace_io
00177
00178
00179
00180 #define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 FT_CALLBACK_DEF( void )
00195 ft_close_stream_by_munmap( FT_Stream stream )
00196 {
00197 munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
00198
00199 stream->descriptor.pointer = NULL;
00200 stream->size = 0;
00201 stream->base = 0;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 FT_CALLBACK_DEF( void )
00217 ft_close_stream_by_free( FT_Stream stream )
00218 {
00219 ft_free( NULL, stream->descriptor.pointer );
00220
00221 stream->descriptor.pointer = NULL;
00222 stream->size = 0;
00223 stream->base = 0;
00224 }
00225
00226
00227
00228
00229 FT_BASE_DEF( FT_Error )
00230 FT_Stream_Open( FT_Stream stream,
00231 const char* filepathname )
00232 {
00233 int file;
00234 struct stat stat_buf;
00235
00236
00237 if ( !stream )
00238 return FT_Err_Invalid_Stream_Handle;
00239
00240
00241 file = open( filepathname, O_RDONLY );
00242 if ( file < 0 )
00243 {
00244 FT_ERROR(( "FT_Stream_Open:" ));
00245 FT_ERROR(( " could not open `%s'\n", filepathname ));
00246 return FT_Err_Cannot_Open_Resource;
00247 }
00248
00249
00250
00251
00252
00253
00254 #ifdef F_SETFD
00255 #ifdef FD_CLOEXEC
00256 (void)fcntl( file, F_SETFD, FD_CLOEXEC );
00257 #else
00258 (void)fcntl( file, F_SETFD, 1 );
00259 #endif
00260 #endif
00261
00262 if ( fstat( file, &stat_buf ) < 0 )
00263 {
00264 FT_ERROR(( "FT_Stream_Open:" ));
00265 FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
00266 goto Fail_Map;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 if ( stat_buf.st_size > LONG_MAX )
00279 {
00280 FT_ERROR(( "FT_Stream_Open: file is too big\n" ));
00281 goto Fail_Map;
00282 }
00283 else if ( stat_buf.st_size == 0 )
00284 {
00285 FT_ERROR(( "FT_Stream_Open: zero-length file\n" ));
00286 goto Fail_Map;
00287 }
00288
00289
00290 stream->size = (unsigned long)stat_buf.st_size;
00291 stream->pos = 0;
00292 stream->base = (unsigned char *)mmap( NULL,
00293 stream->size,
00294 PROT_READ,
00295 MAP_FILE | MAP_PRIVATE,
00296 file,
00297 0 );
00298
00299
00300 if ( (long)stream->base != -1 && stream->base != NULL )
00301 stream->close = ft_close_stream_by_munmap;
00302 else
00303 {
00304 ssize_t total_read_count;
00305
00306
00307 FT_ERROR(( "FT_Stream_Open:" ));
00308 FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
00309
00310 stream->base = (unsigned char*)ft_alloc( NULL, stream->size );
00311
00312 if ( !stream->base )
00313 {
00314 FT_ERROR(( "FT_Stream_Open:" ));
00315 FT_ERROR(( " could not `alloc' memory\n" ));
00316 goto Fail_Map;
00317 }
00318
00319 total_read_count = 0;
00320 do {
00321 ssize_t read_count;
00322
00323
00324 read_count = read( file,
00325 stream->base + total_read_count,
00326 stream->size - total_read_count );
00327
00328 if ( read_count <= 0 )
00329 {
00330 if ( read_count == -1 && errno == EINTR )
00331 continue;
00332
00333 FT_ERROR(( "FT_Stream_Open:" ));
00334 FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
00335 goto Fail_Read;
00336 }
00337
00338 total_read_count += read_count;
00339
00340 } while ( (unsigned long)total_read_count != stream->size );
00341
00342 stream->close = ft_close_stream_by_free;
00343 }
00344
00345 close( file );
00346
00347 stream->descriptor.pointer = stream->base;
00348 stream->pathname.pointer = (char*)filepathname;
00349
00350 stream->read = 0;
00351
00352 FT_TRACE1(( "FT_Stream_Open:" ));
00353 FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
00354 filepathname, stream->size ));
00355
00356 return FT_Err_Ok;
00357
00358 Fail_Read:
00359 ft_free( NULL, stream->base );
00360
00361 Fail_Map:
00362 close( file );
00363
00364 stream->base = NULL;
00365 stream->size = 0;
00366 stream->pos = 0;
00367
00368 return FT_Err_Cannot_Open_Stream;
00369 }
00370
00371
00372 #ifdef FT_DEBUG_MEMORY
00373
00374 extern FT_Int
00375 ft_mem_debug_init( FT_Memory memory );
00376
00377 extern void
00378 ft_mem_debug_done( FT_Memory memory );
00379
00380 #endif
00381
00382
00383
00384
00385 FT_BASE_DEF( FT_Memory )
00386 FT_New_Memory( void )
00387 {
00388 FT_Memory memory;
00389
00390
00391 memory = (FT_Memory)malloc( sizeof ( *memory ) );
00392 if ( memory )
00393 {
00394 memory->user = 0;
00395 memory->alloc = ft_alloc;
00396 memory->realloc = ft_realloc;
00397 memory->free = ft_free;
00398 #ifdef FT_DEBUG_MEMORY
00399 ft_mem_debug_init( memory );
00400 #endif
00401 }
00402
00403 return memory;
00404 }
00405
00406
00407
00408
00409 FT_BASE_DEF( void )
00410 FT_Done_Memory( FT_Memory memory )
00411 {
00412 #ifdef FT_DEBUG_MEMORY
00413 ft_mem_debug_done( memory );
00414 #endif
00415 memory->free( memory, memory );
00416 }
00417
00418
00419