[gs-cvs] rev 7040 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Wed Sep 13 04:57:47 PDT 2006


Author: leonardo
Date: 2006-09-13 04:57:46 -0700 (Wed, 13 Sep 2006)
New Revision: 7040

Modified:
   trunk/gs/src/gp.h
   trunk/gs/src/gp_iwatc.c
   trunk/gs/src/gp_macio.c
   trunk/gs/src/gp_mswin.c
   trunk/gs/src/gp_os2.c
   trunk/gs/src/gp_unifs.c
   trunk/gs/src/gp_unix.c
   trunk/gs/src/gp_vms.c
   trunk/gs/src/gpmisc.c
   trunk/gs/src/gpmisc.h
   trunk/gs/src/lib.mak
Log:
Implementing a 64 bits file access.

DETAILS :

This is a preparation for a fix for 
bug 688394 "clist playback of large pdf image segfaults".

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

This patch requires to define  -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
compiler options on Linux in Makefile .

We could not figure out why Cygwin/gcc defines fopen64, ftello64, fseeko64,
and then cannot link them. We didn't find imlementations of those functions 
in C libraries.
 
EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gp.h
===================================================================
--- trunk/gs/src/gp.h	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp.h	2006-09-13 11:57:46 UTC (rev 7040)
@@ -36,6 +36,11 @@
  */
 #include "srdline.h"
 
+/*
+ * int64_t is used in the 64 bits file access.
+ */
+#include "stdint_.h"
+
 /* ------ Initialization/termination ------ */
 
 /*
@@ -404,4 +409,51 @@
 /* clean up and deallocate the iterator */
 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 */

Modified: trunk/gs/src/gp_iwatc.c
===================================================================
--- trunk/gs/src/gp_iwatc.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_iwatc.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -193,4 +193,40 @@
                          
 void gp_enumerate_fonts_free(void *enum_state)
 {
-}           
+}  
+
+/* --------- 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);
+}

Modified: trunk/gs/src/gp_macio.c
===================================================================
--- trunk/gs/src/gp_macio.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_macio.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -1014,3 +1014,38 @@
 	return 1;
 }
                                                                                 
+/* --------- 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);
+}

Modified: trunk/gs/src/gp_mswin.c
===================================================================
--- trunk/gs/src/gp_mswin.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_mswin.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -798,3 +798,56 @@
 void gp_enumerate_fonts_free(void *enum_state)
 {
 }           
+
+/* --------- 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
+}

Modified: trunk/gs/src/gp_os2.c
===================================================================
--- trunk/gs/src/gp_os2.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_os2.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -858,3 +858,39 @@
 void gp_enumerate_fonts_free(void *enum_state)
 {
 }           
+
+/* --------- 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);
+}

Modified: trunk/gs/src/gp_unifs.c
===================================================================
--- trunk/gs/src/gp_unifs.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_unifs.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -14,9 +14,9 @@
 /* $Id$ */
 /* "Unix-like" file system platform routines for Ghostscript */
 
+#include "stdio_.h"		/* for FILENAME_MAX */
 #include "memory_.h"
 #include "string_.h"
-#include "stdio_.h"		/* for FILENAME_MAX */
 #include "gx.h"
 #include "gp.h"
 #include "gpmisc.h"
@@ -57,9 +57,9 @@
 
 /* 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)
+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);
     int len = gp_file_name_sizeof - prefix_length - 8;
@@ -83,29 +83,42 @@
 
 #ifdef HAVE_MKSTEMP
     {
-	    int file;
-	    char ofname[gp_file_name_sizeof];
+	int file;
+	char ofname[gp_file_name_sizeof];
 
-	    /* save the old filename template in case mkstemp fails */
-	    memcpy(ofname, fname, gp_file_name_sizeof);
+	/* save the old filename template in case mkstemp fails */
+	memcpy(ofname, fname, gp_file_name_sizeof);
 
+#ifndef _LARGEFILE64_SOURCE
+	if (b64)
+	    file = mkstemp64(fname);
+	else
+#endif
 	    file = mkstemp(fname);
-	    if (file < -1) {
-		    eprintf1("**** Could not open temporary file %s\n", ofname);
-		    return NULL;
-	    }
-	    fp = fdopen(file, mode);
- 	    if (fp == NULL)
- 		    close(file);
+
+	/* Fixme : what top do with b64 ? Unimplemented. */
+	if (file < -1) {
+	    eprintf1("**** Could not open temporary file %s\n", ofname);
+	    return NULL;
+	}
+	fp = fdopen(file, mode);
+	if (fp == NULL)
+	    close(file);
     }
 #else
     mktemp(fname);
-    fp = gp_fopentemp(fname, mode);
+    fp = (b64 ? gp_fopentemp : gp_fopentemp_64)(fname, mode);
 #endif
     if (fp == NULL)
 	eprintf1("**** Could not open temporary file %s\n", fname);
     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. */
 FILE *
@@ -462,3 +475,45 @@
    (../?*r*?/) {==} 100 string filenameforall
    (/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
+}

Modified: trunk/gs/src/gp_unix.c
===================================================================
--- trunk/gs/src/gp_unix.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_unix.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -154,7 +154,14 @@
 
     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. */
 void
 gp_close_printer(FILE * pfile, const char *fname)

Modified: trunk/gs/src/gp_vms.c
===================================================================
--- trunk/gs/src/gp_vms.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gp_vms.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -651,3 +651,38 @@
 {
 }
 
+/* --------- 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);
+}

Modified: trunk/gs/src/gpmisc.c
===================================================================
--- trunk/gs/src/gpmisc.c	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gpmisc.c	2006-09-13 11:57:46 UTC (rev 7040)
@@ -45,8 +45,8 @@
  * Open a temporary file, using O_EXCL and S_I*USR to prevent race
  * conditions and symlink attacks.
  */
-FILE *
-gp_fopentemp(const char *fname, const char *mode)
+private FILE *
+gp_fopentemp_generic(const char *fname, const char *mode, bool b64)
 {
     int flags = O_EXCL;
     /* Scan the mode to construct the flags. */
@@ -54,6 +54,14 @@
     int fildes;
     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++) {
 	case 'a':
@@ -85,12 +93,26 @@
      * fdopen as (char *), rather than following the POSIX.1 standard,
      * 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);
     return file;
 }
 
+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
 append(char **bp, const char *bpe, const char **ip, uint len)

Modified: trunk/gs/src/gpmisc.h
===================================================================
--- trunk/gs/src/gpmisc.h	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/gpmisc.h	2006-09-13 11:57:46 UTC (rev 7040)
@@ -34,6 +34,7 @@
  * conditions and symlink attacks.
  */
 FILE *gp_fopentemp(const char *fname, const char *mode);
+FILE *gp_fopentemp_64(const char *fname, const char *mode);
 
 /*
  * Combine a file name with a prefix.

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2006-09-13 11:56:34 UTC (rev 7039)
+++ trunk/gs/src/lib.mak	2006-09-13 11:57:46 UTC (rev 7040)
@@ -49,6 +49,7 @@
 stdpn_h=$(GLSRC)stdpn.h
 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)
 	$(EXP)$(GENARCH_XE) $(GLGEN)arch.h
@@ -60,7 +61,7 @@
 srdline_h=$(GLSRC)srdline.h
 gpgetenv_h=$(GLSRC)gpgetenv.h
 gpmisc_h=$(GLSRC)gpmisc.h
-gp_h=$(GLSRC)gp.h $(gpgetenv_h) $(gstypes_h) $(srdline_h)
+gp_h=$(GLSRC)gp.h $(gpgetenv_h) $(gstypes_h) $(srdline_h) $(stdint__h)
 gpcheck_h=$(GLSRC)gpcheck.h
 gpsync_h=$(GLSRC)gpsync.h
 
@@ -90,7 +91,6 @@
 memory__h=$(GLSRC)memory_.h $(std_h)
 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)
 time__h=$(GLSRC)time_.h $(std_h) $(gconfig__h)
@@ -693,7 +693,7 @@
 
 $(GLOBJ)gxpdash.$(OBJ) : $(GLSRC)gxpdash.c $(GX) $(math__h)\
  $(gscoord_h) $(gsline_h) $(gsmatrix_h)\
- $(gxfixed_h) $(gxarith_h) $(gzline_h) $(gzpath_h)
+ $(gxfixed_h) $(gzline_h) $(gzpath_h)
 	$(GLCC) $(GLO_)gxpdash.$(OBJ) $(C_) $(GLSRC)gxpdash.c
 
 $(GLOBJ)gxpflat.$(OBJ) : $(GLSRC)gxpflat.c $(GX)\



More information about the gs-cvs mailing list