summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Lang <gsview@ghostgum.com.au>2001-09-15 08:48:34 +0000
committerRussell Lang <gsview@ghostgum.com.au>2001-09-15 08:48:34 +0000
commitcf76faea902c4042e368daa1860728079499c9f9 (patch)
treeabc7eff34d8a15769463cdd172ece1e261fc6a86
parent08ad200003f241513307f7ab7d445b073151c487 (diff)
Speed up reading stdin when using callouts.
Add platform-specific functions for reading stdin, to allow non-blocking reading of stdin if supported. Fixes Sourceforge bug #416973. git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@1724 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/doc/Develop.htm2
-rw-r--r--gs/src/dpmain.c47
-rw-r--r--gs/src/dvx-tail.mak5
-rw-r--r--gs/src/dwmainc.c55
-rw-r--r--gs/src/gp.h15
-rw-r--r--gs/src/gp_stdia.c59
-rw-r--r--gs/src/gp_stdin.c38
-rw-r--r--gs/src/imain.c6
-rw-r--r--gs/src/macos-mcp.mak3
-rw-r--r--gs/src/openvms.mak5
-rw-r--r--gs/src/os2.mak7
-rw-r--r--gs/src/unistd_.h4
-rw-r--r--gs/src/unix-aux.mak8
-rw-r--r--gs/src/watc.mak8
-rw-r--r--gs/src/winlib.mak5
-rw-r--r--gs/src/ziodevs.c18
16 files changed, 237 insertions, 48 deletions
diff --git a/gs/doc/Develop.htm b/gs/doc/Develop.htm
index ebdcb67b6..9387e7a9c 100644
--- a/gs/doc/Develop.htm
+++ b/gs/doc/Develop.htm
@@ -3837,6 +3837,8 @@ Platform-specific implementation files:
<a href="../src/gp_ntfs.c">src/gp_ntfs.c</a>,
<a href="../src/gp_os2.c">src/gp_os2.c</a>,
<a href="../src/gp_os9.c">src/gp_os9.c</a>,
+<a href="../src/gp_stdia.c">src/gp_stdia.c</a>,
+<a href="../src/gp_stdin.c">src/gp_stdin.c</a>,
<a href="../src/gp_sysv.c">src/gp_sysv.c</a>,
<a href="../src/gp_unifn.c">src/gp_unifn.c</a>,
<a href="../src/gp_unifs.c">src/gp_unifs.c</a>,
diff --git a/gs/src/dpmain.c b/gs/src/dpmain.c
index d3626dd48..fcd646323 100644
--- a/gs/src/dpmain.c
+++ b/gs/src/dpmain.c
@@ -36,6 +36,10 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
+#include <io.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/select.h>
#include "gscdefs.h"
#define GS_REVISION gs_revision
#include "errors.h"
@@ -288,26 +292,44 @@ gs_load_dll(void)
/*********************************************************************/
/* stdio functions */
-static int
-gsdll_stdin(void *instance, char *buf, int len)
+
+/* Configure stdin for non-blocking reads if possible. */
+int gp_stdin_init(int fd)
+{
+ /* set file to non-blocking */
+ int flags = fcntl(fd, F_GETFL, 0);
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
+ return -1;
+ return 0;
+}
+
+/* Read bytes from stdin, using non-blocking if possible. */
+int gp_stdin_read(char *buf, int len, int interactive, int fd)
{
- int ch;
- int count = 0;
- while (count < len) {
- ch = fgetc(stdin);
- if (ch == EOF)
- return count;
- *buf++ = ch;
- count++;
- if (ch == '\r')
+ fd_set rfds;
+ int count;
+ for (;;) {
+ count = read(fd, buf, len);
+ if (count >= 0)
break;
- if (ch == '\n')
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ select(1, &rfds, NULL, NULL, NULL);
+ } else if (errno != EINTR) {
break;
+ }
}
return count;
}
static int
+gsdll_stdin(void *instance, char *buf, int len)
+{
+ return gp_stdin_read(buf, len, 1, fileno(stdin));
+}
+
+static int
gsdll_stdout(void *instance, const char *str, int len)
{
fwrite(str, 1, len, stdout);
@@ -1000,6 +1022,7 @@ main(int argc, char *argv[])
ULONG version[3];
gs_main_instance *instance;
+ gp_stdin_init(fileno(stdin));
if (DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_REVISION,
&version, sizeof(version)))
os_version = 201000; /* a guess */
diff --git a/gs/src/dvx-tail.mak b/gs/src/dvx-tail.mak
index 8e56c33c9..537cef126 100644
--- a/gs/src/dvx-tail.mak
+++ b/gs/src/dvx-tail.mak
@@ -29,7 +29,7 @@
## The Desqview/X platform
-dvx__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_dvx.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_dosfs.$(OBJ)
+dvx__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_dvx.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_dosfs.$(OBJ) gp_stdin.$(OBJ)
$(GLGEN)dvx_.dev: $(dvx__) nosync.dev
$(SETMOD) $(GLGEN)dvx_ $(dvx__) -include nosync
@@ -37,6 +37,9 @@ $(GLOBJ)gp_dvx.$(OBJ): $(GLSRC)gp_dvx.c $(AK) $(string__h) $(gx_h) $(gsexit_h) $
$(time__h) $(dos__h)
$(CC_) -D__DVX__ -c $(GLSRC)gp_dvx.c -o $(GLOBJ)gp_dvx.$(OBJ)
+$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c $(AK) $(stdio__h) $(unistd__h) $(fcntl__h) $(gx_h) $(gp_h) $(errors_h)
+ $(GLCC) $(GLO_)gp_stdin.$(OBJ) $(C_) $(GLSRC)gp_stdin.c
+
# -------------------------- Auxiliary programs --------------------------- #
$(ANSI2KNR_XE): ansi2knr.c $(stdio__h) $(string__h) $(malloc__h)
diff --git a/gs/src/dwmainc.c b/gs/src/dwmainc.c
index 61e70714f..a33b82aba 100644
--- a/gs/src/dwmainc.c
+++ b/gs/src/dwmainc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2000 Ghostgum Software Pty Ltd. All rights reserved.
+/* Copyright (C) 1996-2001 Ghostgum Software Pty Ltd. All rights reserved.
This file is part of AFPL Ghostscript.
@@ -42,23 +42,48 @@ char start_string[] = "systemdict /start get exec\n";
/*********************************************************************/
/* stdio functions */
-static int GSDLLCALL
-gsdll_stdin(void *instance, char *buf, int len)
+
+/* Read as many bytes as are available.
+ * Returns:
+ * number of bytes on success.
+ * 0 on EOF.
+ * < 0 on error.
+ */
+static int
+gp_read_stdin(char *buf, int len, int fd)
{
- int ch;
- int count = 0;
- while (count < len) {
- ch = fgetc(stdin);
- if (ch == EOF)
+ HANDLE hPipe = (HANDLE)_get_osfhandle(fd);
+ DWORD dwBytesAvailable;
+ if (isatty(fd)) {
+ /* Input is a character device (terminal, console,
+ * printer or serial port). Read one character at
+ * a time.
+ */
+ return _read(fd, buf, 1);
+ }
+ else {
+ /* Test if input is a pipe. */
+ if (PeekNamedPipe(hPipe, NULL, 0, NULL, &dwBytesAvailable, NULL)) {
+ int count = _read(fd, buf, min(len, dwBytesAvailable));
+ if (count == 0) /* pipe is empty */ {
+ count = _read(fd, buf, 1); /* block until 1 byte available */
+ /* Then see what else is also available */
+ if ((count == 1) &&
+ PeekNamedPipe(hPipe, NULL, 0, NULL,
+ &dwBytesAvailable, NULL)) {
+ count += _read(fd, buf+1, min(len-1, dwBytesAvailable));
+ }
+ }
return count;
- *buf++ = ch;
- count++;
- if (ch == '\r')
- break;
- if (ch == '\n')
- break;
+ }
}
- return count;
+ /* Input must be a file. */
+ return _read(fd, buf, len);
+}
+static int GSDLLCALL
+gsdll_stdin(void *instance, char *buf, int len)
+{
+ return gp_read_stdin(buf, len, fileno(stdin));
}
static int GSDLLCALL
diff --git a/gs/src/gp.h b/gs/src/gp.h
index eb54ed1fe..f0c814fa6 100644
--- a/gs/src/gp.h
+++ b/gs/src/gp.h
@@ -114,6 +114,21 @@ int gp_readline(P9(stream *s_in, stream *s_out, void *readline_data,
*/
void gp_readline_finit(P1(void *readline_data));
+/* ------ Reading from stdin, non-blocking if possible ------ */
+
+/* Configure stdin for non-blocking reads if possible. */
+int gp_stdin_init(P1(int fd));
+
+/* Read bytes from stdin, using non-blocking if possible.
+ * Store up to len bytes in buf.
+ * Returns number of bytes read, or 0 if EOF, or -ve if error.
+ * If non-blocking is NOT possible, fetch 1 byte is interactive
+ * is non-zero, or up to len bytes otherwise.
+ * If non-blocking is possible, fetch at least 1 byte (unless error or EOF)
+ * and any additional bytes that are available without blocking.
+ */
+int gp_stdin_read(P4(char *buf, int len, int interactive, int fd));
+
/* ------ Screen management ------ */
/*
diff --git a/gs/src/gp_stdia.c b/gs/src/gp_stdia.c
new file mode 100644
index 000000000..38d1ee212
--- /dev/null
+++ b/gs/src/gp_stdia.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 2001 artofcode LLC. All rights reserved.
+
+ This file is part of AFPL Ghostscript.
+
+ AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
+ distributor accepts any responsibility for the consequences of using it, or
+ for whether it serves any particular purpose or works at all, unless he or
+ she says so in writing. Refer to the Aladdin Free Public License (the
+ "License") for full details.
+
+ Every copy of AFPL Ghostscript must include a copy of the License, normally
+ in a plain ASCII text file named PUBLIC. The License grants you the right
+ to copy, modify and redistribute AFPL Ghostscript, but only under certain
+ conditions described in the License. Among other things, the License
+ requires that the copyright notice and this notice be preserved on all
+ copies.
+*/
+
+/*$Id$ */
+/* Read stdin on platforms that support select and non-blocking read */
+
+#include "stdio_.h"
+#include "unistd_.h"
+#include "fcntl_.h"
+#include "errno_.h"
+#include "gx.h"
+#include "gp.h"
+#include "errors.h"
+
+/* Configure stdin for non-blocking reads if possible. */
+int gp_stdin_init(int fd)
+{
+ /* set file to non-blocking */
+ int flags = fcntl(fd, F_GETFL, 0);
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
+ return e_ioerror;
+ return 0;
+}
+
+/* Read bytes from stdin, using non-blocking if possible. */
+int gp_stdin_read(char *buf, int len, int interactive, int fd)
+{
+ fd_set rfds;
+ int count;
+ for (;;) {
+ count = read(fd, buf, len);
+ if (count >= 0)
+ break;
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ select(1, &rfds, NULL, NULL, NULL);
+ } else if (errno != EINTR) {
+ break;
+ }
+ }
+ return count;
+}
+
diff --git a/gs/src/gp_stdin.c b/gs/src/gp_stdin.c
new file mode 100644
index 000000000..20ef78024
--- /dev/null
+++ b/gs/src/gp_stdin.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 2001 artofcode LLC. All rights reserved.
+
+ This file is part of AFPL Ghostscript.
+
+ AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
+ distributor accepts any responsibility for the consequences of using it, or
+ for whether it serves any particular purpose or works at all, unless he or
+ she says so in writing. Refer to the Aladdin Free Public License (the
+ "License") for full details.
+
+ Every copy of AFPL Ghostscript must include a copy of the License, normally
+ in a plain ASCII text file named PUBLIC. The License grants you the right
+ to copy, modify and redistribute AFPL Ghostscript, but only under certain
+ conditions described in the License. Among other things, the License
+ requires that the copyright notice and this notice be preserved on all
+ copies.
+*/
+
+/*$Id$ */
+/* Read stdin on platforms that do not support non-blocking reads */
+
+#include "stdio_.h"
+#include "gx.h"
+#include "gp.h"
+
+/* Configure stdin for non-blocking reads if possible. */
+int gp_stdin_init(int fd)
+{
+ /* do nothing */
+ return 0;
+}
+
+/* Read bytes from stdin, using non-blocking if possible. */
+int gp_stdin_read(char *buf, int len, int interactive, int fd)
+{
+ return read(buf, 1, interactive ? 1 : len, fd);
+}
+
diff --git a/gs/src/imain.c b/gs/src/imain.c
index 77f74b485..44591e93d 100644
--- a/gs/src/imain.c
+++ b/gs/src/imain.c
@@ -112,6 +112,7 @@ gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err,
/* because it detects attempts to run 80N86 executables (N>0) */
/* on incompatible processors. */
gp_init();
+ gp_stdin_init(fileno(in));
gp_get_usertime(minst->base_time);
/* Initialize the imager. */
heap = gs_lib_init0(gs_stdout);
@@ -273,13 +274,12 @@ gs_main_interpret(gs_main_instance *minst, ref * pref, int user_errors,
* esp[-1] = file, stdin stream
* We read from stdin then pop these 2 items.
*/
- if (gs_stdin_is_interactive)
- count = 1;
if (minst->stdin_fn)
count = (*minst->stdin_fn)(minst->caller_handle,
minst->stdin_buf, count);
else
- count = fread(minst->stdin_buf, 1, count, minst->fstdin);
+ count = gp_stdin_read(minst->stdin_buf, count,
+ minst->stdin_is_interactive, fileno(minst->fstdin));
if (count < 0)
return_error(e_ioerror);
diff --git a/gs/src/macos-mcp.mak b/gs/src/macos-mcp.mak
index 9dfc2c716..1fcc00221 100644
--- a/gs/src/macos-mcp.mak
+++ b/gs/src/macos-mcp.mak
@@ -330,6 +330,7 @@ sysstat_h=$(GLOBJ)sys\:stat.h
$(GLOBJ)gp_mac.$(OBJ): $(GLSRC)gp_mac.c
$(GLOBJ)gp_macio.$(OBJ): $(GLSRC)gp_macio.c
+$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c
# does not work for systime_h?!?!
#$(systypes_h):
@@ -341,7 +342,7 @@ $(GLOBJ)gp_macio.$(OBJ): $(GLSRC)gp_macio.c
# ------------------------------------------------------------------- #
-MAC1=$(GLOBJ)gp_macio.$(OBJ) $(GLOBJ)gp_mac.$(OBJ) $(GLOBJ)gdevmacxf.$(OBJ)
+MAC1=$(GLOBJ)gp_macio.$(OBJ) $(GLOBJ)gp_mac.$(OBJ) $(GLOBJ)gdevmacxf.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ)
MAC2=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_nsync.$(OBJ) $(GLOBJ)gdevemap.$(OBJ) $(GLOBJ)gsdll.$(OBJ)
$(GLD)macos_.dev: $(MAC1)
diff --git a/gs/src/openvms.mak b/gs/src/openvms.mak
index ce6124736..d82fe5f04 100644
--- a/gs/src/openvms.mak
+++ b/gs/src/openvms.mak
@@ -428,13 +428,16 @@ $(GS_XE) : openvms $(GLOBJDIR)gs.$(OBJ) $(INT_ALL) $(LIB_ALL)
# OpenVMS.dev
-openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_vms.$(OBJ)
+openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_vms.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ)
$(GLGEN)openvms_.dev : $(openvms__) $(GLGEN)nosync.dev
$(SETMOD) $(GLGEN)openvms_ $(openvms__) -include $(GLGEN)nosync
$(GLOBJ)gp_vms.$(OBJ) : $(GLSRC)gp_vms.c
$(CC_)/include=($(GLGENDIR),$(GLSRCDIR))/obj=$(GLOBJ)gp_vms.$(OBJ) $(GLSRC)gp_vms.c
+$(GLOBJ)gp_stdin.$(OBJ) : $(GLSRC)gp_stdin.c $(AK) $(stdio__h) $(unistd__h) $(fcntl__h) $(gx_h) $(gp_h) $(errors_h)
+ $(CC_)/obj=$(GLOBJ)gp_stdin.$(OBJ) $(GLSRC)gp_stdin.c
+
# Interpreter AUX programs
$(ECHOGS_XE) : $(GLOBJ)echogs.$(OBJ)
diff --git a/gs/src/os2.mak b/gs/src/os2.mak
index 9a5878d0a..bfaf92122 100644
--- a/gs/src/os2.mak
+++ b/gs/src/os2.mak
@@ -508,7 +508,7 @@ DEVICE_DEVS20=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev
# The GCC/EMX platform
-os2__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_os2.$(OBJ)
+os2__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_os2.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ)
$(GLGEN)os2_.dev: $(os2__) $(GLD)nosync.dev
$(SETMOD) $(GLGEN)os2_ $(os2__) -include $(GLD)nosync
@@ -517,6 +517,11 @@ $(GLOBJ)gp_os2.$(OBJ): $(GLSRC)gp_os2.c\
$(gsdll_h) $(gx_h) $(gsexit_h) $(gsutil_h) $(gp_h) $(gpmisc_h)
$(GLCC) $(GLO_)gp_os2.$(OBJ) $(C_) $(GLSRC)gp_os2.c
+$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c $(AK)\
+ $(stdio__h) $(unistd__h) $(fcntl__h) $(errno__h)\
+ $(gx_h) $(gp_h) $(errors_h)
+ $(GLCC) $(GLO_)gp_stdin.$(OBJ) $(C_) $(GLSRC)gp_stdin.c
+
# -------------------------- Auxiliary programs --------------------------- #
#CCAUX=$(COMPDIR)\$(COMP) $(CO)
diff --git a/gs/src/unistd_.h b/gs/src/unistd_.h
index 05c26826b..9701a6bed 100644
--- a/gs/src/unistd_.h
+++ b/gs/src/unistd_.h
@@ -31,6 +31,10 @@
* otherwise) for where to find these definitions.
*/
+#ifdef __OS2__
+# include <io.h>
+#endif
+
#if defined(_MSC_VER) && defined(__WIN32__)
# include <io.h>
# define fsync(handle) _commit(handle)
diff --git a/gs/src/unix-aux.mak b/gs/src/unix-aux.mak
index 4ead17087..cd0a564ed 100644
--- a/gs/src/unix-aux.mak
+++ b/gs/src/unix-aux.mak
@@ -32,7 +32,7 @@ UNIX_AUX_MAK=$(GLSRC)unix-aux.mak
# Unix platforms other than System V, and also System V Release 4
# (SVR4) platforms.
-unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ)
+unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ)
$(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev
$(SETMOD) $(GLGEN)unix_ $(unix__) -include $(GLD)nosync
@@ -41,6 +41,12 @@ $(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\
$(gx_h) $(gsexit_h) $(gp_h)
$(GLCC) $(GLO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c
+# assume all Unix platforms support async IO using read/select
+$(GLOBJ)gp_stdia.$(OBJ): $(GLSRC)gp_stdia.c $(AK)\
+ $(stdio__h) $(unistd__h) $(fcntl__h) $(errno__h)\
+ $(gx_h) $(gp_h) $(errors_h)
+ $(GLCC) $(GLO_)gp_stdia.$(OBJ) $(C_) $(GLSRC)gp_stdia.c
+
# System V platforms other than SVR4, which lack some system calls,
# but have pipes.
sysv__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_sysv.$(OBJ)
diff --git a/gs/src/watc.mak b/gs/src/watc.mak
index ea1f84eef..f7d0bb0f2 100644
--- a/gs/src/watc.mak
+++ b/gs/src/watc.mak
@@ -282,7 +282,7 @@ GLCCWIN=$(GLCC)
# The Watcom C platform
-watc_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ)
+watc_1=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_iwatc.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ)
watc_2=$(GLOBJ)gp_mktmp.$(OBJ)
!ifeq WAT32 0
watc_3=$(GLOBJ)gp_dosfs.$(OBJ) $(GLOBJ)gp_dosfe.$(OBJ) $(GLOBJ)gp_msdos.$(OBJ)
@@ -305,6 +305,12 @@ $(GLOBJ)gp_iwatc.$(OBJ): $(GLSRC)gp_iwatc.c $(stat__h) $(string__h)\
$(GLOBJ)gp_mktmp.$(OBJ): $(GLSRC)gp_mktmp.c $(stat__h) $(string__h)
$(GLCC) $(GLO_)gp_mktmp.$(OBJ) $(C_) $(GLSRC)gp_mktmp.c
+$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c $(AK)\
+ $(stdio__h) $(unistd__h) $(fcntl__h)\
+ $(gx_h) $(gp_h) $(errors_h)
+ $(GLCC) $(GLO_)gp_stdin.$(OBJ) $(C_) $(GLSRC)gp_stdin.c
+
+
# ----------------------------- Main program ------------------------------ #
BEGINFILES=*.err
diff --git a/gs/src/winlib.mak b/gs/src/winlib.mak
index 8969bafab..ed94438bf 100644
--- a/gs/src/winlib.mak
+++ b/gs/src/winlib.mak
@@ -129,7 +129,7 @@ $(gconfigv_h): $(TOP_MAKEFILES) $(ECHOGS_XE)
# The Windows Win32 platform
-mswin32__=$(GLOBJ)gp_mswin.$(OBJ) $(GLOBJ)gp_wgetv.$(OBJ)
+mswin32__=$(GLOBJ)gp_mswin.$(OBJ) $(GLOBJ)gp_wgetv.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ)
mswin32_inc=$(GLD)nosync.dev $(GLD)winplat.dev
$(GLGEN)mswin32_.dev: $(mswin32__) $(ECHOGS_XE) $(mswin32_inc)
@@ -144,6 +144,9 @@ $(GLOBJ)gp_mswin.$(OBJ): $(GLSRC)gp_mswin.c $(AK) $(gp_mswin_h) \
$(GLOBJ)gp_wgetv.$(OBJ): $(GLSRC)gp_wgetv.c $(AK) $(gscdefs_h)
$(GLCCWIN) $(GLO_)gp_wgetv.$(OBJ) $(C_) $(GLSRC)gp_wgetv.c
+$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c $(AK) $(gx_h) $(gp_h)
+ $(GLCCWIN) $(GLO_)gp_stdin.$(OBJ) $(C_) $(GLSRC)gp_stdin.c
+
# Define MS-Windows handles (file system) as a separable feature.
mshandle_=$(GLOBJ)gp_mshdl.$(OBJ)
diff --git a/gs/src/ziodevs.c b/gs/src/ziodevs.c
index 0586fccc3..42c2f7c98 100644
--- a/gs/src/ziodevs.c
+++ b/gs/src/ziodevs.c
@@ -20,6 +20,7 @@
/* %stdxxx IODevice implementation for PostScript interpreter */
#include "stdio_.h"
#include "ghost.h"
+#include "gp.h"
#include "gpcheck.h"
#include "oper.h"
#include "stream.h"
@@ -97,17 +98,12 @@ s_stdin_read_process(stream_state * st, stream_cursor_read * ignore_pr,
int wcount = (int)(pw->limit - pw->ptr);
int count;
- if (wcount > 0) {
- if (gs_stdin_is_interactive)
- wcount = 1;
- count = fread(pw->ptr + 1, 1, wcount, file);
- if (count < 0)
- count = 0;
- pw->ptr += count;
- } else
- count = 0; /* return 1 if no error/EOF */
- process_interrupts();
- return (ferror(file) ? ERRC : feof(file) ? EOFC : count == wcount ? 1 : 0);
+ if (wcount <= 0)
+ return 0;
+ count = gp_stdin_read(pw->ptr + 1, wcount, gs_stdin_is_interactive,
+ fileno(file));
+ pw->ptr += (count < 0) ? 0 : count;
+ return ((count < 0) ? ERRC : (count == 0) ? EOFC : count);
}
private int