freetype-devel
[Top][All Lists]
Advanced

[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 );




reply via email to

[Prev in Thread] Current Thread [Next in Thread]