/modules/freetype2/builds/unix/ftsystem.c

http://github.com/zpao/v8monkey · C · 419 lines · 208 code · 83 blank · 128 comment · 20 complexity · fb2559e19c18eece4429142e77024fde MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* ftsystem.c */
  4. /* */
  5. /* Unix-specific FreeType low-level system interface (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  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. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. /* we use our special ftconfig.h file, not the standard one */
  19. #include <ftconfig.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_SYSTEM_H
  22. #include FT_ERRORS_H
  23. #include FT_TYPES_H
  24. #include FT_INTERNAL_STREAM_H
  25. /* memory-mapping includes and definitions */
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #include <sys/mman.h>
  30. #ifndef MAP_FILE
  31. #define MAP_FILE 0x00
  32. #endif
  33. #ifdef MUNMAP_USES_VOIDP
  34. #define MUNMAP_ARG_CAST void *
  35. #else
  36. #define MUNMAP_ARG_CAST char *
  37. #endif
  38. #ifdef NEED_MUNMAP_DECL
  39. #ifdef __cplusplus
  40. extern "C"
  41. #else
  42. extern
  43. #endif
  44. int
  45. munmap( char* addr,
  46. int len );
  47. #define MUNMAP_ARG_CAST char *
  48. #endif /* NEED_DECLARATION_MUNMAP */
  49. #include <sys/types.h>
  50. #include <sys/stat.h>
  51. #ifdef HAVE_FCNTL_H
  52. #include <fcntl.h>
  53. #endif
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <string.h>
  57. #include <errno.h>
  58. /*************************************************************************/
  59. /* */
  60. /* MEMORY MANAGEMENT INTERFACE */
  61. /* */
  62. /*************************************************************************/
  63. /*************************************************************************/
  64. /* */
  65. /* <Function> */
  66. /* ft_alloc */
  67. /* */
  68. /* <Description> */
  69. /* The memory allocation function. */
  70. /* */
  71. /* <Input> */
  72. /* memory :: A pointer to the memory object. */
  73. /* */
  74. /* size :: The requested size in bytes. */
  75. /* */
  76. /* <Return> */
  77. /* The address of newly allocated block. */
  78. /* */
  79. FT_CALLBACK_DEF( void* )
  80. ft_alloc( FT_Memory memory,
  81. long size )
  82. {
  83. FT_UNUSED( memory );
  84. return malloc( size );
  85. }
  86. /*************************************************************************/
  87. /* */
  88. /* <Function> */
  89. /* ft_realloc */
  90. /* */
  91. /* <Description> */
  92. /* The memory reallocation function. */
  93. /* */
  94. /* <Input> */
  95. /* memory :: A pointer to the memory object. */
  96. /* */
  97. /* cur_size :: The current size of the allocated memory block. */
  98. /* */
  99. /* new_size :: The newly requested size in bytes. */
  100. /* */
  101. /* block :: The current address of the block in memory. */
  102. /* */
  103. /* <Return> */
  104. /* The address of the reallocated memory block. */
  105. /* */
  106. FT_CALLBACK_DEF( void* )
  107. ft_realloc( FT_Memory memory,
  108. long cur_size,
  109. long new_size,
  110. void* block )
  111. {
  112. FT_UNUSED( memory );
  113. FT_UNUSED( cur_size );
  114. return realloc( block, new_size );
  115. }
  116. /*************************************************************************/
  117. /* */
  118. /* <Function> */
  119. /* ft_free */
  120. /* */
  121. /* <Description> */
  122. /* The memory release function. */
  123. /* */
  124. /* <Input> */
  125. /* memory :: A pointer to the memory object. */
  126. /* */
  127. /* block :: The address of block in memory to be freed. */
  128. /* */
  129. FT_CALLBACK_DEF( void )
  130. ft_free( FT_Memory memory,
  131. void* block )
  132. {
  133. FT_UNUSED( memory );
  134. free( block );
  135. }
  136. /*************************************************************************/
  137. /* */
  138. /* RESOURCE MANAGEMENT INTERFACE */
  139. /* */
  140. /*************************************************************************/
  141. /*************************************************************************/
  142. /* */
  143. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  144. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  145. /* messages during execution. */
  146. /* */
  147. #undef FT_COMPONENT
  148. #define FT_COMPONENT trace_io
  149. /* We use the macro STREAM_FILE for convenience to extract the */
  150. /* system-specific stream handle from a given FreeType stream object */
  151. #define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
  152. /*************************************************************************/
  153. /* */
  154. /* <Function> */
  155. /* ft_close_stream_by_munmap */
  156. /* */
  157. /* <Description> */
  158. /* The function to close a stream which is opened by mmap. */
  159. /* */
  160. /* <Input> */
  161. /* stream :: A pointer to the stream object. */
  162. /* */
  163. FT_CALLBACK_DEF( void )
  164. ft_close_stream_by_munmap( FT_Stream stream )
  165. {
  166. munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
  167. stream->descriptor.pointer = NULL;
  168. stream->size = 0;
  169. stream->base = 0;
  170. }
  171. /*************************************************************************/
  172. /* */
  173. /* <Function> */
  174. /* ft_close_stream_by_free */
  175. /* */
  176. /* <Description> */
  177. /* The function to close a stream which is created by ft_alloc. */
  178. /* */
  179. /* <Input> */
  180. /* stream :: A pointer to the stream object. */
  181. /* */
  182. FT_CALLBACK_DEF( void )
  183. ft_close_stream_by_free( FT_Stream stream )
  184. {
  185. ft_free( NULL, stream->descriptor.pointer );
  186. stream->descriptor.pointer = NULL;
  187. stream->size = 0;
  188. stream->base = 0;
  189. }
  190. /* documentation is in ftobjs.h */
  191. FT_BASE_DEF( FT_Error )
  192. FT_Stream_Open( FT_Stream stream,
  193. const char* filepathname )
  194. {
  195. int file;
  196. struct stat stat_buf;
  197. if ( !stream )
  198. return FT_Err_Invalid_Stream_Handle;
  199. /* open the file */
  200. file = open( filepathname, O_RDONLY );
  201. if ( file < 0 )
  202. {
  203. FT_ERROR(( "FT_Stream_Open:" ));
  204. FT_ERROR(( " could not open `%s'\n", filepathname ));
  205. return FT_Err_Cannot_Open_Resource;
  206. }
  207. /* Here we ensure that a "fork" will _not_ duplicate */
  208. /* our opened input streams on Unix. This is critical */
  209. /* since it avoids some (possible) access control */
  210. /* issues and cleans up the kernel file table a bit. */
  211. /* */
  212. #ifdef F_SETFD
  213. #ifdef FD_CLOEXEC
  214. (void)fcntl( file, F_SETFD, FD_CLOEXEC );
  215. #else
  216. (void)fcntl( file, F_SETFD, 1 );
  217. #endif /* FD_CLOEXEC */
  218. #endif /* F_SETFD */
  219. if ( fstat( file, &stat_buf ) < 0 )
  220. {
  221. FT_ERROR(( "FT_Stream_Open:" ));
  222. FT_ERROR(( " could not `fstat' file `%s'\n", filepathname ));
  223. goto Fail_Map;
  224. }
  225. /* XXX: TODO -- real 64bit platform support */
  226. /* */
  227. /* `stream->size' is typedef'd to unsigned long (in */
  228. /* freetype/ftsystem.h); `stat_buf.st_size', however, is usually */
  229. /* typedef'd to off_t (in sys/stat.h). */
  230. /* On some platforms, the former is 32bit and the latter is 64bit. */
  231. /* To avoid overflow caused by fonts in huge files larger than */
  232. /* 2GB, do a test. Temporary fix proposed by Sean McBride. */
  233. /* */
  234. if ( stat_buf.st_size > LONG_MAX )
  235. {
  236. FT_ERROR(( "FT_Stream_Open: file is too big\n" ));
  237. goto Fail_Map;
  238. }
  239. else if ( stat_buf.st_size == 0 )
  240. {
  241. FT_ERROR(( "FT_Stream_Open: zero-length file\n" ));
  242. goto Fail_Map;
  243. }
  244. /* This cast potentially truncates a 64bit to 32bit! */
  245. stream->size = (unsigned long)stat_buf.st_size;
  246. stream->pos = 0;
  247. stream->base = (unsigned char *)mmap( NULL,
  248. stream->size,
  249. PROT_READ,
  250. MAP_FILE | MAP_PRIVATE,
  251. file,
  252. 0 );
  253. /* on some RTOS, mmap might return 0 */
  254. if ( (long)stream->base != -1 && stream->base != NULL )
  255. stream->close = ft_close_stream_by_munmap;
  256. else
  257. {
  258. ssize_t total_read_count;
  259. FT_ERROR(( "FT_Stream_Open:" ));
  260. FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
  261. stream->base = (unsigned char*)ft_alloc( NULL, stream->size );
  262. if ( !stream->base )
  263. {
  264. FT_ERROR(( "FT_Stream_Open:" ));
  265. FT_ERROR(( " could not `alloc' memory\n" ));
  266. goto Fail_Map;
  267. }
  268. total_read_count = 0;
  269. do {
  270. ssize_t read_count;
  271. read_count = read( file,
  272. stream->base + total_read_count,
  273. stream->size - total_read_count );
  274. if ( read_count <= 0 )
  275. {
  276. if ( read_count == -1 && errno == EINTR )
  277. continue;
  278. FT_ERROR(( "FT_Stream_Open:" ));
  279. FT_ERROR(( " error while `read'ing file `%s'\n", filepathname ));
  280. goto Fail_Read;
  281. }
  282. total_read_count += read_count;
  283. } while ( (unsigned long)total_read_count != stream->size );
  284. stream->close = ft_close_stream_by_free;
  285. }
  286. close( file );
  287. stream->descriptor.pointer = stream->base;
  288. stream->pathname.pointer = (char*)filepathname;
  289. stream->read = 0;
  290. FT_TRACE1(( "FT_Stream_Open:" ));
  291. FT_TRACE1(( " opened `%s' (%d bytes) successfully\n",
  292. filepathname, stream->size ));
  293. return FT_Err_Ok;
  294. Fail_Read:
  295. ft_free( NULL, stream->base );
  296. Fail_Map:
  297. close( file );
  298. stream->base = NULL;
  299. stream->size = 0;
  300. stream->pos = 0;
  301. return FT_Err_Cannot_Open_Stream;
  302. }
  303. #ifdef FT_DEBUG_MEMORY
  304. extern FT_Int
  305. ft_mem_debug_init( FT_Memory memory );
  306. extern void
  307. ft_mem_debug_done( FT_Memory memory );
  308. #endif
  309. /* documentation is in ftobjs.h */
  310. FT_BASE_DEF( FT_Memory )
  311. FT_New_Memory( void )
  312. {
  313. FT_Memory memory;
  314. memory = (FT_Memory)malloc( sizeof ( *memory ) );
  315. if ( memory )
  316. {
  317. memory->user = 0;
  318. memory->alloc = ft_alloc;
  319. memory->realloc = ft_realloc;
  320. memory->free = ft_free;
  321. #ifdef FT_DEBUG_MEMORY
  322. ft_mem_debug_init( memory );
  323. #endif
  324. }
  325. return memory;
  326. }
  327. /* documentation is in ftobjs.h */
  328. FT_BASE_DEF( void )
  329. FT_Done_Memory( FT_Memory memory )
  330. {
  331. #ifdef FT_DEBUG_MEMORY
  332. ft_mem_debug_done( memory );
  333. #endif
  334. memory->free( memory, memory );
  335. }
  336. /* END */