[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