[gs-code-review] Re: Implementing a 64 bits file access, improved 2.

Igor V. Melichev igor.melichev at artifex.com
Mon Sep 4 07:05:17 PDT 2006


[Log message beg]
Implementing a 64 bits file access.

DETAILS :

This is a preliminary implementation.
Now it compiles for MSVC8, Linux/gcc .
For other platforms/compilers it is stubbed with 32 bits file access.

We could not figure out why Cygwin/gcc defines fopen64, ftello64, fseeko64,
and then cannot link them. Maybe something is wrong with linker options ?

EXPECTED DIFFERENCES :

None.
[Log message end]

See attachment.
-------------- next part --------------
 
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp.h	Wed Mar 22 10:37:51 2006
--- files\gs\src\gp.h	Thu Aug 31 15:38:31 2006
***************
*** 37,40 ****
--- 37,45 ----
  #include "srdline.h"
  
+ /*
+  * int64_t is used in the 64 bits file access.
+  */
+ #include "stdint_.h"
+ 
  /* ------ Initialization/termination ------ */
  
***************
*** 405,407 ****
--- 410,459 ----
  void gp_enumerate_fonts_free(void *enum_state);
  
+ /* --------- 64 bit file access ----------- */
+ 
+ /* The following functions are analogues of ones with
+    same name without the "_64" suffix. 
+    They perform same function with allowing big files
+    (over 4 gygabytes length).
+ 
+    If the platform does not allow big files,
+    these functions are mapped to regular file i/o functions.
+    On 64 bits platforms they work same as
+    regular file i/o functions.
+ 
+    We continue using the old file i/o functions
+    because most files do not need 64 bits access.
+    The upgrading of old code to the new 64 bits access
+    to be done step by step on real necessity,
+    with replacing old function names with 
+    new function names through code,
+    together with providing the int64_t type for storing 
+    file offsets in intermediate structures and variables.
+ 
+    We assume that the result of 64 bits variant of 'ftell'
+    can be represented in int64_t on all platforms,
+    rather the result type of the native 64 bits function is
+    compiler dependent (__off_t on Linux, _off_t on Cygwin, 
+    __int64 on Windows).
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode);
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode);
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode);
+ 
+ int64_t gp_ftell_64(FILE *stream);
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin);
+ 
+ /* We don't define gp_fread_64, gp_fwrite_64,
+    because (1) known platforms allow regular fread, fwrite
+    to be applied to a file opened with O_LARGEFILE, 
+    fopen64, etc.; (2) Ghostscript code does not
+    perform writing/reading a long (over 4gb) block
+    in one operation.
+  */
+ 
  #endif /* gp_INCLUDED */
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gpmisc.c	Wed Aug 23 14:21:32 2006
--- files\gs\src\gpmisc.c	Fri Sep  1 12:24:59 2006
***************
*** 46,51 ****
   * conditions and symlink attacks.
   */
! FILE *
! gp_fopentemp(const char *fname, const char *mode)
  {
      int flags = O_EXCL;
--- 46,51 ----
   * conditions and symlink attacks.
   */
! private FILE *
! gp_fopentemp_generic(const char *fname, const char *mode, bool b64)
  {
      int flags = O_EXCL;
***************
*** 55,58 ****
--- 55,66 ----
      FILE *file;
  
+ #if defined (O_LARGEFILE)
+     /* It works for Linux/gcc. */
+     if (b64)
+ 	flags |= O_LARGEFILE;
+ #else
+     /* fixme : Not sure what to do. Unimplemented. */
+     /* MSVC has no O_LARGEFILE, but MSVC build never calls this function. */
+ #endif
      while (*p)
  	switch (*p++) {
***************
*** 86,90 ****
--- 94,102 ----
       * which defines it as (const char *).  Patch this here.
       */
+ #if defined (O_LARGEFILE)
+     file = (b64 ? fdopen64 : fdopen)(fildes, (char *)mode); /* still really const */
+ #else
      file = fdopen(fildes, (char *)mode); /* still really const */
+ #endif
      if (file == 0)
  	close(fildes);
***************
*** 92,95 ****
--- 104,117 ----
  }
  
+ FILE *gp_fopentemp_64(const char *fname, const char *mode)
+ {
+     return gp_fopentemp_generic(fname, mode, true);
+ }
+ 
+ FILE *gp_fopentemp(const char *fname, const char *mode)
+ {
+     return gp_fopentemp_generic(fname, mode, false);
+ }
+ 
  /* Append a string to buffer. */
  private inline bool
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gpmisc.h	Wed Mar 15 15:05:05 2006
--- files\gs\src\gpmisc.h	Thu Aug 31 21:25:23 2006
***************
*** 35,38 ****
--- 35,39 ----
   */
  FILE *gp_fopentemp(const char *fname, const char *mode);
+ FILE *gp_fopentemp_64(const char *fname, const char *mode);
  
  /*
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_iwatc.c	Wed Mar 15 15:04:29 2006
--- files\gs\src\gp_iwatc.c	Thu Aug 31 21:06:27 2006
***************
*** 195,196 ****
--- 195,232 ----
  {
  }  
+ 
+ /* --------- 64 bit file access ----------- */
+ /* fixme: Not implemented yet.
+  * Currently we stub it with 32 bits access. 
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+     return fopen(filename, mode);
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file(prefix, fname, mode);
+ }
+ 
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     return gp_open_printer(fname, binary_mode);
+ }
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+     return ftell(stream);
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseek(stream, offset1, origin);
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_macio.c	Wed Mar 15 15:04:37 2006
--- files\gs\src\gp_macio.c	Thu Aug 31 21:06:41 2006
***************
*** 1015,1016 ****
--- 1015,1051 ----
  }
                                                                                  
+ /* --------- 64 bit file access ----------- */
+ /* fixme: Not implemented yet.
+  * Currently we stub it with 32 bits access. 
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+     return fopen(filename, mode);
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file(prefix, fname, mode);
+ }
+ 
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     return gp_open_printer(fname, binary_mode);
+ }
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+     return ftell(stream);
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseek(stream, offset1, origin);
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_mswin.c	Wed Mar 15 15:04:47 2006
--- files\gs\src\gp_mswin.c	Fri Sep  1 12:27:11 2006
***************
*** 799,800 ****
--- 799,853 ----
  {
  }           
+ 
+ /* --------- 64 bit file access ----------- */
+ /* MSVC versions before 8 doen't provide big files.
+    MSVC 8 doesn't distinguish big and small files,
+    but provide special positioning functions
+    to access data behind 4GB.
+    Currently we support 64 bits file access with MSVC only.
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+     return fopen(filename, mode);
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file(prefix, fname, mode);
+ }
+ 
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     /* Assuming gp_open_scratch_file_64 is same as gp_open_scratch_file -
+        see the body of gp_open_printer. */
+     return gp_open_printer(fname, binary_mode);
+ }
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+ #if !defined(_MSC_VER)
+     return ftell(steram);
+ #elif _MSC_VER < 1400
+     return ftell(steram);
+ #else
+     return _ftelli64(stream);
+ #endif
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+ #if !defined(_MSC_VER)
+     return fseek(steram, offset, origin);
+ #elif _MSC_VER < 1400
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseek(stream, offset1, origin);
+ #else
+     return _fseeki64(stream, offset, origin);
+ #endif
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_os2.c	Wed Mar 15 15:04:20 2006
--- files\gs\src\gp_os2.c	Thu Aug 31 21:06:54 2006
***************
*** 859,860 ****
--- 859,896 ----
  {
  }           
+ 
+ /* --------- 64 bit file access ----------- */
+ /* fixme: Not implemented yet.
+  * Currently we stub it with 32 bits access. 
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+     return fopen(filename, mode);
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file(prefix, fname, mode);
+ }
+ 
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     return gp_open_printer(fname, binary_mode);
+ }
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+     return ftell(stream);
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseek(stream, offset1, origin);
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_unifs.c	Wed Mar 15 15:04:15 2006
--- files\gs\src\gp_unifs.c	Mon Sep  4 18:00:14 2006
***************
*** 15,21 ****
  /* "Unix-like" file system platform routines for Ghostscript */
  
  #include "memory_.h"
  #include "string_.h"
- #include "stdio_.h"		/* for FILENAME_MAX */
  #include "gx.h"
  #include "gp.h"
--- 15,21 ----
  /* "Unix-like" file system platform routines for Ghostscript */
  
+ #include "stdio_.h"		/* for FILENAME_MAX */
  #include "memory_.h"
  #include "string_.h"
  #include "gx.h"
  #include "gp.h"
***************
*** 58,64 ****
  /* Create and open a scratch file with a given name prefix. */
  /* Write the actual file name at fname. */
! FILE *
! gp_open_scratch_file(const char *prefix, char fname[gp_file_name_sizeof],
! 		     const char *mode)
  {	/* The -8 is for XXXXXX plus a possible final / and -. */
      int prefix_length = strlen(prefix);
--- 58,64 ----
  /* Create and open a scratch file with a given name prefix. */
  /* Write the actual file name at fname. */
! private FILE *
! gp_open_scratch_file_generic(const char *prefix, char fname[gp_file_name_sizeof],
! 		     const char *mode, bool b64)
  {	/* The -8 is for XXXXXX plus a possible final / and -. */
      int prefix_length = strlen(prefix);
***************
*** 90,94 ****
--- 90,101 ----
  	memcpy(ofname, fname, gp_file_name_sizeof);
  
+ #ifndef _LARGEFILE64_SOURCE
+ 	if (b64)
+ 	    file = mkstemp64(fname);
+ 	else
+ #endif
  	    file = mkstemp(fname);
+ 
+ 	/* Fixme : what top do with b64 ? Unimplemented. */
  	if (file < -1) {
  	    eprintf1("**** Could not open temporary file %s\n", ofname);
***************
*** 101,105 ****
  #else
      mktemp(fname);
!     fp = gp_fopentemp(fname, mode);
  #endif
      if (fp == NULL)
--- 108,112 ----
  #else
      mktemp(fname);
!     fp = (b64 ? gp_fopentemp : gp_fopentemp_64)(fname, mode);
  #endif
      if (fp == NULL)
***************
*** 107,110 ****
--- 114,123 ----
      return fp;
  }
+ FILE *
+ gp_open_scratch_file(const char *prefix, char fname[gp_file_name_sizeof],
+ 		     const char *mode)
+ {
+     return gp_open_scratch_file_generic(prefix, fname, mode, false);
+ }
  
  /* Open a file with the given name, as a stream of uninterpreted bytes. */
***************
*** 463,464 ****
--- 476,519 ----
     (/t*?/?*.ps) {==} 100 string filenameforall
   */
+ 
+ /* --------- 64 bit file access ----------- */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+ #ifdef _LARGEFILE64_SOURCE
+     return fopen(filename, mode);
+ #else
+     return fopen64(filename, mode);
+ #endif
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file_generic(prefix, fname, mode, true);
+ }
+ 
+ /* gp_open_printer_64 is defined in gp_unix.h */
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+ #ifdef _LARGEFILE64_SOURCE
+     return ftello(stream);
+ #else
+     return ftello64(stream);
+ #endif
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+ #ifdef _LARGEFILE64_SOURCE
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseeko(stream, offset1, origin);
+ #else
+     return fseeko64(stream, offset, origin);
+ #endif
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_unix.c	Wed Mar 15 15:05:02 2006
--- files\gs\src\gp_unix.c	Thu Aug 31 21:34:44 2006
***************
*** 155,158 ****
--- 155,165 ----
      return (strlen(fname) == 0 ? 0 : fopen(fname, fmode));
  }
+ FILE *
+ gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     const char *fmode = (binary_mode ? "wb" : "w");
+ 
+     return (strlen(fname) == 0 ? 0 : gp_fopen_64(fname, fmode));
+ }
  
  /* Close the connection to the printer. */
 
 
 
*** F:\SVN-GS\HEAD\gs\src\gp_vms.c	Thu Jun  1 10:37:39 2006
--- files\gs\src\gp_vms.c	Thu Aug 31 21:07:42 2006
***************
*** 652,653 ****
--- 652,688 ----
  }
  
+ /* --------- 64 bit file access ----------- */
+ /* fixme: Not implemented yet.
+  * Currently we stub it with 32 bits access. 
+  */
+ 
+ FILE *gp_fopen_64(const char *filename, const char *mode)
+ {
+     return fopen(filename, mode);
+ }
+ 
+ FILE *gp_open_scratch_file_64(const char *prefix,
+ 			   char fname[gp_file_name_sizeof],
+ 			   const char *mode)
+ {
+     return gp_open_scratch_file(prefix, fname, mode);
+ }
+ 
+ FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
+ {
+     return gp_open_printer(fname, binary_mode);
+ }
+ 
+ int64_t gp_ftell_64(FILE *stream)
+ {
+     return ftell(stream);
+ }
+ 
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+     long offset1 = (long)offset;
+     
+     if (offset != offset1)
+ 	return -1;
+     return fseek(stream, offset1, origin);
+ }
 
 
 
*** F:\SVN-GS\HEAD\gs\src\lib.mak	Mon Sep  4 16:50:38 2006
--- files\gs\src\lib.mak	Thu Aug 31 15:40:10 2006
***************
*** 11,15 ****
  #  San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
  #
! # $Id: lib.mak 7021 2006-09-04 12:50:36Z leonardo $
  # (Platform-independent) makefile for Ghostscript graphics library
  # and other support code.
--- 11,15 ----
  #  San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
  #
! # $Id: lib.mak 7011 2006-08-30 00:24:55Z giles $
  # (Platform-independent) makefile for Ghostscript graphics library
  # and other support code.
***************
*** 50,53 ****
--- 50,54 ----
  stdpre_h=$(GLSRC)stdpre.h $(stdpn_h)
  std_h=$(GLSRC)std.h $(arch_h) $(stdpre_h)
+ stdint__h=$(GLSRC)stdint_.h $(std_h)
  
  $(GLGEN)arch.h : $(GENARCH_XE)
***************
*** 61,65 ****
  gpgetenv_h=$(GLSRC)gpgetenv.h
  gpmisc_h=$(GLSRC)gpmisc.h
! gp_h=$(GLSRC)gp.h $(gpgetenv_h) $(gstypes_h) $(srdline_h)
  gpcheck_h=$(GLSRC)gpcheck.h
  gpsync_h=$(GLSRC)gpsync.h
--- 62,66 ----
  gpgetenv_h=$(GLSRC)gpgetenv.h
  gpmisc_h=$(GLSRC)gpmisc.h
! gp_h=$(GLSRC)gp.h $(gpgetenv_h) $(gstypes_h) $(srdline_h) $(stdint__h)
  gpcheck_h=$(GLSRC)gpcheck.h
  gpsync_h=$(GLSRC)gpsync.h
***************
*** 91,95 ****
  setjmp__h=$(GLSRC)setjmp_.h
  stat__h=$(GLSRC)stat_.h $(std_h)
- stdint__h=$(GLSRC)stdint_.h $(std_h)
  stdio__h=$(GLSRC)stdio_.h $(std_h)
  string__h=$(GLSRC)string_.h $(std_h)
--- 92,95 ----
***************
*** 694,698 ****
  $(GLOBJ)gxpdash.$(OBJ) : $(GLSRC)gxpdash.c $(GX) $(math__h)\
   $(gscoord_h) $(gsline_h) $(gsmatrix_h)\
!  $(gxfixed_h) $(gxarith_h) $(gzline_h) $(gzpath_h)
  	$(GLCC) $(GLO_)gxpdash.$(OBJ) $(C_) $(GLSRC)gxpdash.c
  
--- 694,698 ----
  $(GLOBJ)gxpdash.$(OBJ) : $(GLSRC)gxpdash.c $(GX) $(math__h)\
   $(gscoord_h) $(gsline_h) $(gsmatrix_h)\
!  $(gxfixed_h) $(gzline_h) $(gzpath_h)
  	$(GLCC) $(GLO_)gxpdash.$(OBJ) $(C_) $(GLSRC)gxpdash.c
  
 
 
 
 
 
 
 


More information about the gs-code-review mailing list