[gs-code-review] Implementing a 64 bits file access, improved.
Igor V. Melichev
igor.melichev at artifex.com
Fri Sep 1 03:13:29 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 Fri Sep 1 14:07:51 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 __CYGWIN__
+ 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 __CYGWIN__
+ 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 __CYGWIN__
+ return ftello(stream);
+ #else
+ return ftello64(stream);
+ #endif
+ }
+
+ int gp_fseek_64(FILE *stream, int64_t offset, int origin)
+ {
+ #ifdef __CYGWIN__
+ long offset1 = (long)offset;
+
+ if (offset != offset1)
+ return -1;
+ return fseek(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 Thu Aug 31 13:40:41 2006
--- files\gs\src\lib.mak Thu Aug 31 15:40:10 2006
***************
*** 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 ----
More information about the gs-code-review
mailing list