[gs-cvs] rev 8542 - trunk/gs/src
alexcher at ghostscript.com
alexcher at ghostscript.com
Sat Feb 23 18:58:35 PST 2008
Author: alexcher
Date: 2008-02-23 18:58:34 -0800 (Sat, 23 Feb 2008)
New Revision: 8542
Added:
trunk/gs/src/sfxcommon.c
Modified:
trunk/gs/src/lib.mak
trunk/gs/src/sfxstdio.c
Log:
Fix link errors in the file descriptor-based implementation of file streams.
Move function used by both fd and stdio implementations to a separate file
and compile it in both versions. Bug 688918.
DETAILS:
Although the patch fixes link errors, pdfwrite and other devices,
use stdio functions directly and generate incorrect documents in fd version.
DIFFERENCES:
None in stdio version.
Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak 2008-02-24 01:12:18 UTC (rev 8541)
+++ trunk/gs/src/lib.mak 2008-02-24 02:58:34 UTC (rev 8542)
@@ -1194,10 +1194,16 @@
# Currently only the high-level drivers use these, but more drivers will
# probably use them eventually.
-sfile_=$(GLOBJ)sfx$(FILE_IMPLEMENTATION).$(OBJ) $(GLOBJ)stream.$(OBJ)
+sfile_=$(GLOBJ)sfx$(FILE_IMPLEMENTATION).$(OBJ) $(GLOBJ)sfxcommon.$(OBJ)\
+ $(GLOBJ)stream.$(OBJ)
+
$(GLD)sfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(sfile_)
$(SETMOD) $(GLD)sfile $(sfile_)
+$(GLOBJ)sfxcommon.$(OBJ) : $(GLSRC)sfxcommon.c $(AK) $(stdio__h) $(memory__h)\
+ $(unistd__h) $(gsmemory_h) $(gp_h) $(stream_h) $(gserror_h) $(gserrors_h)
+ $(GLCC) $(GLO_)sfxcommon.$(OBJ) $(C_) $(GLSRC)sfxcommon.c
+
$(GLOBJ)sfxstdio.$(OBJ) : $(GLSRC)sfxstdio.c $(AK) $(stdio__h) $(memory__h)\
$(unistd__h) $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h)
$(GLCC) $(GLO_)sfxstdio.$(OBJ) $(C_) $(GLSRC)sfxstdio.c
Added: trunk/gs/src/sfxcommon.c
===================================================================
--- trunk/gs/src/sfxcommon.c 2008-02-24 01:12:18 UTC (rev 8541)
+++ trunk/gs/src/sfxcommon.c 2008-02-24 02:58:34 UTC (rev 8542)
@@ -0,0 +1,186 @@
+/* Copyright (C) 2008 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* $Id: sfxcommon.c 8250 2007-09-25 13:31:24Z giles $ */
+/* Common routines for stdio and fd file stream implementations. */
+#include "stdio_.h" /* includes std.h */
+#include "memory_.h"
+#include "unistd_.h"
+#include "gsmemory.h"
+#include "gp.h"
+#include "gserror.h"
+#include "gserrors.h"
+#include "stream.h"
+
+#define DEFAULT_BUFFER_SIZE 2048
+const uint file_default_buffer_size = DEFAULT_BUFFER_SIZE;
+
+/* Allocate and return a file stream. */
+/* Return 0 if the allocation failed. */
+/* The stream is initialized to an invalid state, so the caller need not */
+/* worry about cleaning up if a later step in opening the stream fails. */
+stream *
+file_alloc_stream(gs_memory_t * mem, client_name_t cname)
+{
+ stream *s;
+ s = s_alloc(mem, cname);
+ if (s == 0)
+ return 0;
+ s_init_ids(s);
+ s->is_temp = 0; /* not a temp stream */
+ s->foreign = 0;
+ /*
+ * Disable the stream now (in case we can't open the file,
+ * or a filter init procedure fails) so that `restore' won't
+ * crash when it tries to close open files.
+ */
+ s_disable(s);
+ s->prev = 0;
+ s->next = 0;
+ return s;
+}
+
+/* Open a file stream, optionally on an OS file. */
+/* Return 0 if successful, error code if not. */
+/* On a successful return, the C file name is in the stream buffer. */
+/* If fname==0, set up the file entry, stream, and buffer, */
+/* but don't open an OS file or initialize the stream. */
+int
+file_open_stream(const char *fname, uint len, const char *file_access,
+ uint buffer_size, stream ** ps, gx_io_device *iodev,
+ iodev_proc_fopen_t fopen_proc, gs_memory_t *mem)
+{
+ int code;
+ FILE *file;
+ char fmode[4]; /* r/w/a, [+], [b], null */
+
+ if (!iodev)
+ iodev = iodev_default;
+ code = file_prepare_stream(fname, len, file_access, buffer_size, ps, fmode, mem);
+ if (code < 0)
+ return code;
+ if (fname == 0)
+ return 0;
+ if (fname[0] == 0) /* fopen_proc gets NUL terminated string, not len */
+ return 0; /* so this is the same as len == 0, so return NULL */
+ code = (*fopen_proc)(iodev, (char *)(*ps)->cbuf, fmode, &file,
+ (char *)(*ps)->cbuf, (*ps)->bsize);
+ if (code < 0)
+ return code;
+ file_init_stream(*ps, file, fmode, (*ps)->cbuf, (*ps)->bsize);
+ return 0;
+}
+
+/* Close a file stream. This replaces the close procedure in the stream */
+/* for normal (OS) files and for filters. */
+int
+file_close_file(stream * s)
+{
+ stream *stemp = s->strm;
+ gs_memory_t *mem;
+ int code = file_close_disable(s);
+
+ if (code)
+ return code;
+ /*
+ * Check for temporary streams created for filters.
+ * There may be more than one in the case of a procedure-based filter,
+ * or if we created an intermediate stream to ensure
+ * a large enough buffer. Note that these streams may have been
+ * allocated by file_alloc_stream, so we mustn't free them.
+ */
+ while (stemp != 0 && stemp->is_temp != 0) {
+ stream *snext = stemp->strm;
+
+ mem = stemp->memory;
+ if (stemp->is_temp > 1)
+ gs_free_object(mem, stemp->cbuf,
+ "file_close(temp stream buffer)");
+ s_disable(stemp);
+ stemp = snext;
+ }
+ mem = s->memory;
+ gs_free_object(mem, s->cbuf, "file_close(buffer)");
+ if (s->close_strm && stemp != 0)
+ return sclose(stemp);
+ return 0;
+}
+
+/*
+ * Set up a file stream on an OS file. The caller has allocated the
+ * stream and buffer.
+ */
+void
+file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer,
+ uint buffer_size)
+{
+ switch (fmode[0]) {
+ case 'a':
+ sappend_file(s, file, buffer, buffer_size);
+ break;
+ case 'r':
+ /* Defeat buffering for terminals. */
+ {
+ struct stat rstat;
+
+ fstat(fileno(file), &rstat);
+ sread_file(s, file, buffer,
+ (S_ISCHR(rstat.st_mode) ? 1 : buffer_size));
+ }
+ break;
+ case 'w':
+ swrite_file(s, file, buffer, buffer_size);
+ }
+ if (fmode[1] == '+')
+ s->file_modes |= s_mode_read | s_mode_write;
+ s->save_close = s->procs.close;
+ s->procs.close = file_close_file;
+}
+
+/* Prepare a stream with a file name. */
+/* Return 0 if successful, error code if not. */
+/* On a successful return, the C file name is in the stream buffer. */
+/* If fname==0, set up stream, and buffer. */
+int
+file_prepare_stream(const char *fname, uint len, const char *file_access,
+ uint buffer_size, stream ** ps, char fmode[4], gs_memory_t *mem)
+{
+ byte *buffer;
+ register stream *s;
+
+ /* Open the file, always in binary mode. */
+ strcpy(fmode, file_access);
+ strcat(fmode, gp_fmode_binary_suffix);
+ if (buffer_size == 0)
+ buffer_size = file_default_buffer_size;
+ if (len >= buffer_size) /* we copy the file name into the buffer */
+ return_error(gs_error_limitcheck);
+ /* Allocate the stream first, since it persists */
+ /* even after the file has been closed. */
+ s = file_alloc_stream(mem, "file_prepare_stream");
+ if (s == 0)
+ return_error(gs_error_VMerror);
+ /* Allocate the buffer. */
+ buffer = gs_alloc_bytes(mem, buffer_size, "file_prepare_stream(buffer)");
+ if (buffer == 0)
+ return_error(gs_error_VMerror);
+ if (fname != 0) {
+ memcpy(buffer, fname, len);
+ buffer[len] = 0; /* terminate string */
+ } else
+ buffer[0] = 0; /* safety */
+ s->cbuf = buffer;
+ s->bsize = s->cbsize = buffer_size;
+ *ps = s;
+ return 0;
+}
Modified: trunk/gs/src/sfxstdio.c
===================================================================
--- trunk/gs/src/sfxstdio.c 2008-02-24 01:12:18 UTC (rev 8541)
+++ trunk/gs/src/sfxstdio.c 2008-02-24 02:58:34 UTC (rev 8542)
@@ -43,169 +43,6 @@
/* ------ File reading ------ */
-#define DEFAULT_BUFFER_SIZE 2048
-const uint file_default_buffer_size = DEFAULT_BUFFER_SIZE;
-
-/* Prepare a stream with a file name. */
-/* Return 0 if successful, error code if not. */
-/* On a successful return, the C file name is in the stream buffer. */
-/* If fname==0, set up stream, and buffer. */
-int
-file_prepare_stream(const char *fname, uint len, const char *file_access,
- uint buffer_size, stream ** ps, char fmode[4], gs_memory_t *mem)
-{
- byte *buffer;
- register stream *s;
-
- /* Open the file, always in binary mode. */
- strcpy(fmode, file_access);
- strcat(fmode, gp_fmode_binary_suffix);
- if (buffer_size == 0)
- buffer_size = file_default_buffer_size;
- if (len >= buffer_size) /* we copy the file name into the buffer */
- return_error(gs_error_limitcheck);
- /* Allocate the stream first, since it persists */
- /* even after the file has been closed. */
- s = file_alloc_stream(mem, "file_prepare_stream");
- if (s == 0)
- return_error(gs_error_VMerror);
- /* Allocate the buffer. */
- buffer = gs_alloc_bytes(mem, buffer_size, "file_prepare_stream(buffer)");
- if (buffer == 0)
- return_error(gs_error_VMerror);
- if (fname != 0) {
- memcpy(buffer, fname, len);
- buffer[len] = 0; /* terminate string */
- } else
- buffer[0] = 0; /* safety */
- s->cbuf = buffer;
- s->bsize = s->cbsize = buffer_size;
- *ps = s;
- return 0;
-}
-
-/*
- * Set up a file stream on an OS file. The caller has allocated the
- * stream and buffer.
- */
-void
-file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer,
- uint buffer_size)
-{
- switch (fmode[0]) {
- case 'a':
- sappend_file(s, file, buffer, buffer_size);
- break;
- case 'r':
- /* Defeat buffering for terminals. */
- {
- struct stat rstat;
-
- fstat(fileno(file), &rstat);
- sread_file(s, file, buffer,
- (S_ISCHR(rstat.st_mode) ? 1 : buffer_size));
- }
- break;
- case 'w':
- swrite_file(s, file, buffer, buffer_size);
- }
- if (fmode[1] == '+')
- s->file_modes |= s_mode_read | s_mode_write;
- s->save_close = s->procs.close;
- s->procs.close = file_close_file;
-}
-
-/* Open a file stream, optionally on an OS file. */
-/* Return 0 if successful, error code if not. */
-/* On a successful return, the C file name is in the stream buffer. */
-/* If fname==0, set up the file entry, stream, and buffer, */
-/* but don't open an OS file or initialize the stream. */
-int
-file_open_stream(const char *fname, uint len, const char *file_access,
- uint buffer_size, stream ** ps, gx_io_device *iodev,
- iodev_proc_fopen_t fopen_proc, gs_memory_t *mem)
-{
- int code;
- FILE *file;
- char fmode[4]; /* r/w/a, [+], [b], null */
-
- if (!iodev)
- iodev = iodev_default;
- code = file_prepare_stream(fname, len, file_access, buffer_size, ps, fmode, mem);
- if (code < 0)
- return code;
- if (fname == 0)
- return 0;
- if (fname[0] == 0) /* fopen_proc gets NUL terminated string, not len */
- return 0; /* so this is the same as len == 0, so return NULL */
- code = (*fopen_proc)(iodev, (char *)(*ps)->cbuf, fmode, &file,
- (char *)(*ps)->cbuf, (*ps)->bsize);
- if (code < 0)
- return code;
- file_init_stream(*ps, file, fmode, (*ps)->cbuf, (*ps)->bsize);
- return 0;
-}
-
-/* Allocate and return a file stream. */
-/* Return 0 if the allocation failed. */
-/* The stream is initialized to an invalid state, so the caller need not */
-/* worry about cleaning up if a later step in opening the stream fails. */
-stream *
-file_alloc_stream(gs_memory_t * mem, client_name_t cname)
-{
- stream *s;
- s = s_alloc(mem, cname);
- if (s == 0)
- return 0;
- s_init_ids(s);
- s->is_temp = 0; /* not a temp stream */
- s->foreign = 0;
- /*
- * Disable the stream now (in case we can't open the file,
- * or a filter init procedure fails) so that `restore' won't
- * crash when it tries to close open files.
- */
- s_disable(s);
- s->prev = 0;
- s->next = 0;
- return s;
-}
-
-/* Close a file stream. This replaces the close procedure in the stream */
-/* for normal (OS) files and for filters. */
-int
-file_close_file(stream * s)
-{
- stream *stemp = s->strm;
- gs_memory_t *mem;
- int code = file_close_disable(s);
-
- if (code)
- return code;
- /*
- * Check for temporary streams created for filters.
- * There may be more than one in the case of a procedure-based filter,
- * or if we created an intermediate stream to ensure
- * a large enough buffer. Note that these streams may have been
- * allocated by file_alloc_stream, so we mustn't free them.
- */
- while (stemp != 0 && stemp->is_temp != 0) {
- stream *snext = stemp->strm;
-
- mem = stemp->memory;
- if (stemp->is_temp > 1)
- gs_free_object(mem, stemp->cbuf,
- "file_close(temp stream buffer)");
- s_disable(stemp);
- stemp = snext;
- }
- mem = s->memory;
- gs_free_object(mem, s->cbuf, "file_close(buffer)");
- if (s->close_strm && stemp != 0)
- return sclose(stemp);
- return 0;
-}
-
/* Initialize a stream for reading an OS file. */
void
sread_file(register stream * s, FILE * file, byte * buf, uint len)
More information about the gs-cvs
mailing list