1
/***************************************************************************/
5
/* Unix-specific FreeType low-level system interface (body). */
7
/* Copyright 1996-2001, 2002, 2004 by */
8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
10
/* This file is part of the FreeType project, and may only be used, */
11
/* modified, and distributed under the terms of the FreeType project */
12
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13
/* this file you indicate that you have read the license and */
14
/* understand and accept it fully. */
16
/***************************************************************************/
20
/* we use our special ftconfig.h file, not the standard one */
22
#include FT_INTERNAL_DEBUG_H
26
#include FT_INTERNAL_OBJECTS_H
28
/* memory-mapping includes and definitions */
38
#ifdef MUNMAP_USES_VOIDP
39
#define MUNMAP_ARG_CAST void *
41
#define MUNMAP_ARG_CAST char *
44
#ifdef NEED_MUNMAP_DECL
55
#define MUNMAP_ARG_CAST char *
57
#endif /* NEED_DECLARATION_MUNMAP */
60
#include <sys/types.h>
73
/*************************************************************************/
75
/* MEMORY MANAGEMENT INTERFACE */
77
/*************************************************************************/
80
/*************************************************************************/
86
/* The memory allocation function. */
89
/* memory :: A pointer to the memory object. */
91
/* size :: The requested size in bytes. */
94
/* The address of newly allocated block. */
96
FT_CALLBACK_DEF( void* )
97
ft_alloc( FT_Memory memory,
102
return malloc( size );
106
/*************************************************************************/
112
/* The memory reallocation function. */
115
/* memory :: A pointer to the memory object. */
117
/* cur_size :: The current size of the allocated memory block. */
119
/* new_size :: The newly requested size in bytes. */
121
/* block :: The current address of the block in memory. */
124
/* The address of the reallocated memory block. */
126
FT_CALLBACK_DEF( void* )
127
ft_realloc( FT_Memory memory,
133
FT_UNUSED( cur_size );
135
return realloc( block, new_size );
139
/*************************************************************************/
145
/* The memory release function. */
148
/* memory :: A pointer to the memory object. */
150
/* block :: The address of block in memory to be freed. */
152
FT_CALLBACK_DEF( void )
153
ft_free( FT_Memory memory,
162
/*************************************************************************/
164
/* RESOURCE MANAGEMENT INTERFACE */
166
/*************************************************************************/
169
/*************************************************************************/
171
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
172
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
173
/* messages during execution. */
176
#define FT_COMPONENT trace_io
178
/* We use the macro STREAM_FILE for convenience to extract the */
179
/* system-specific stream handle from a given FreeType stream object */
180
#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
183
/*************************************************************************/
186
/* ft_close_stream_by_munmap */
189
/* The function to close a stream which is opened by mmap. */
192
/* stream :: A pointer to the stream object. */
194
FT_CALLBACK_DEF( void )
195
ft_close_stream_by_munmap( FT_Stream stream )
197
munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
199
stream->descriptor.pointer = NULL;
205
/*************************************************************************/
208
/* ft_close_stream_by_free */
211
/* The function to close a stream which is created by ft_alloc. */
214
/* stream :: A pointer to the stream object. */
216
FT_CALLBACK_DEF( void )
217
ft_close_stream_by_free( FT_Stream stream )
219
ft_free( NULL, stream->descriptor.pointer );
221
stream->descriptor.pointer = NULL;
227
/* documentation is in ftobjs.h */
229
FT_EXPORT_DEF( FT_Error )
230
FT_Stream_Open( FT_Stream stream,
231
const char* filepathname )
234
struct stat stat_buf;
238
return FT_Err_Invalid_Stream_Handle;
241
file = open( filepathname, O_RDONLY );
244
FT_ERROR(( "FT_Stream_Open:" ));
245
FT_ERROR(( " could not open `%s'\n", filepathname ));
246
return FT_Err_Cannot_Open_Resource;
249
/* Here we ensure that a "fork" will _not_ duplicate */
250
/* our opened input streams on Unix. This is critical */
251
/* since it avoids some (possible) access control */
252
/* issues and cleans up the kernel file table a bit. */
256
(void)fcntl( file, F_SETFD, FD_CLOEXEC );
258
(void)fcntl( file, F_SETFD, 1 );
259
#endif /* FD_CLOEXEC */
262
if ( fstat( file, &stat_buf ) < 0 )
264
FT_ERROR(( "FT_Stream_Open:" ));
265
FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
269
stream->size = stat_buf.st_size;
271
stream->base = (unsigned char *)mmap( NULL,
274
MAP_FILE | MAP_PRIVATE,
278
if ( (long)stream->base != -1 )
279
stream->close = ft_close_stream_by_munmap;
282
ssize_t total_read_count;
285
FT_ERROR(( "FT_Stream_Open:" ));
286
FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
288
stream->base = ft_alloc( NULL, stream->size );
292
FT_ERROR(( "FT_Stream_Open:" ));
293
FT_ERROR(( " could not `alloc' memory\n" ));
297
total_read_count = 0;
302
read_count = read( file,
303
stream->base + total_read_count,
304
stream->size - total_read_count );
306
if ( ( read_count == -1 ) )
308
if ( errno == EINTR )
311
FT_ERROR(( "FT_Stream_Open:" ));
312
FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
316
total_read_count += read_count;
318
} while ( total_read_count != stream->size );
320
stream->close = ft_close_stream_by_free;
325
stream->descriptor.pointer = stream->base;
326
stream->pathname.pointer = (char*)filepathname;
330
FT_TRACE1(( "FT_Stream_Open:" ));
331
FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
332
filepathname, stream->size ));
337
ft_free( NULL, stream->base );
346
return FT_Err_Cannot_Open_Stream;
350
#ifdef FT_DEBUG_MEMORY
353
ft_mem_debug_init( FT_Memory memory );
356
ft_mem_debug_done( FT_Memory memory );
361
/* documentation is in ftobjs.h */
363
FT_EXPORT_DEF( FT_Memory )
364
FT_New_Memory( void )
369
memory = (FT_Memory)malloc( sizeof ( *memory ) );
373
memory->alloc = ft_alloc;
374
memory->realloc = ft_realloc;
375
memory->free = ft_free;
376
#ifdef FT_DEBUG_MEMORY
377
ft_mem_debug_init( memory );
385
/* documentation is in ftobjs.h */
387
FT_EXPORT_DEF( void )
388
FT_Done_Memory( FT_Memory memory )
390
#ifdef FT_DEBUG_MEMORY
391
ft_mem_debug_done( memory );
393
memory->free( memory, memory );