[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Devel] fall-back for mmap
From: |
Masatake YAMATO |
Subject: |
Re: [Devel] fall-back for mmap |
Date: |
Tue, 27 Jan 2004 21:15:35 +0900 (JST) |
Hi,
> Masatake YAMATO <address@hidden> wrote:
>
> + if ( stream->size != read ( file, stream->base, stream->size ) )
> + {
> + FT_ERROR(( "FT_Stream_Open:" ));
> + FT_ERROR(( " could not `read' file `%s'\n", filepathname ));
> + goto Fail_Read;
> + }
>
> Please don't do this! This is not guaranteed to work - read()
> may legally read less bytes than requested. Perhaps it was
> interrupted by a signal, or perhaps it's just a wierd (but legal)
> filesystem driver. The only safe way to call read() is in a loop.
> If you read less than you requested, or if read() returns -1 and
> sets errno to EINTR, then try again to read the rest of the file.
Thank you for your suggestion.
A loop around read() is added.
Masatake YAMATO
Index: builds/unix/ftsystem.c
===================================================================
RCS file: /cvsroot/freetype2/builds/unix/ftsystem.c,v
retrieving revision 1.24
diff -u -r1.24 ftsystem.c
--- ftsystem.c 2002/03/29 07:43:03 1.24
+++ ftsystem.c 2004/01/27 12:06:42
@@ -67,8 +67,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
-
/*************************************************************************/
/* */
/* MEMORY MANAGEMENT INTERFACE */
@@ -182,16 +182,16 @@
/*************************************************************************/
/* */
/* <Function> */
- /* ft_close_stream */
+ /* ft_close_stream_by_munmap */
/* */
/* <Description> */
- /* The function to close a stream. */
+ /* The function to close a stream which is opened by mmap */
/* */
/* <Input> */
/* stream :: A pointer to the stream object. */
/* */
FT_CALLBACK_DEF( void )
- ft_close_stream( FT_Stream stream )
+ ft_close_stream_by_munmap( FT_Stream stream )
{
munmap( (MUNMAP_ARG_CAST)stream->descriptor.pointer, stream->size );
@@ -200,6 +200,26 @@
stream->base = 0;
}
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* ft_close_stream_by_free */
+ /* */
+ /* <Description> */
+ /* The function to close a stream which is created by ft_alloc. */
+ /* */
+ /* <Input> */
+ /* stream :: A pointer to the stream object. */
+ /* */
+ FT_CALLBACK_DEF( void )
+ ft_close_stream_by_free ( FT_Stream stream )
+ {
+ ft_free ( NULL, stream->descriptor.pointer );
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+ stream->base = 0;
+ }
/* documentation is in ftobjs.h */
@@ -252,11 +272,47 @@
file,
0 );
- if ( (long)stream->base == -1 )
+ if ( (long)stream->base != -1 )
+ stream->close = ft_close_stream_by_munmap;
+ else
{
+ ssize_t total_read_count;
+
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
- goto Fail_Map;
+
+ stream->base = ft_alloc ( NULL, stream->size );
+
+ if ( ! stream->base )
+ {
+ FT_ERROR(( "FT_Stream_Open:" ));
+ FT_ERROR(( " could not `alloc' memory\n" ));
+ goto Fail_Map;
+ }
+
+ total_read_count = 0;
+ do {
+ ssize_t read_count;
+
+ read_count = read ( file,
+ stream->base + total_read_count,
+ stream->size - total_read_count );
+
+ if ( ( read_count == -1 ) )
+ {
+ if ( errno == EINTR )
+ continue ;
+
+ FT_ERROR(( "FT_Stream_Open:" ));
+ FT_ERROR(( " error is occurred in `read' file `%s'\n", filepathname
));
+ goto Fail_Read;
+ }
+
+ total_read_count += read_count;
+
+ } while ( total_read_count != stream->size );
+
+ stream->close = ft_close_stream_by_free;
}
close( file );
@@ -264,7 +320,6 @@
stream->descriptor.pointer = stream->base;
stream->pathname.pointer = (char*)filepathname;
- stream->close = ft_close_stream;
stream->read = 0;
FT_TRACE1(( "FT_Stream_Open:" ));
@@ -272,6 +327,9 @@
filepathname, stream->size ));
return FT_Err_Ok;
+
+ Fail_Read:
+ ft_free ( NULL, stream->base );
Fail_Map:
close( file );