Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/gs/src/ziodevs.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: ziodevs.c,v 1.9 2004/08/04 19:36:13 stefan Exp $ */
18
/* %stdxxx IODevice implementation for PostScript interpreter */
19
#include "stdio_.h"
20
#include "ghost.h"
21
#include "gp.h"
22
#include "gpcheck.h"
23
#include "oper.h"
24
#include "stream.h"
25
#include "gxiodev.h"		/* must come after stream.h */
26
				/* and before files.h */
27
#include "files.h"
28
#include "store.h"
29
 
30
/* Define the special devices. */
31
const char iodev_dtype_stdio[] = "Special";
32
#define iodev_special(dname, init, open) {\
33
    dname, iodev_dtype_stdio,\
34
	{ init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
35
	  iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
36
	  iodev_no_enumerate_files, NULL, NULL,\
37
	  iodev_no_get_params, iodev_no_put_params\
38
	}\
39
}
40
 
41
/*
42
 * We need the current context pointer for accessing / opening the %std
43
 * IODevices.  However, this is not available to the open routine.
44
 * Therefore, we use the hack of storing this pointer in the IODevice state
45
 * pointer just before calling the open routines.  We clear the pointer
46
 * immediately afterwards so as not to wind up with dangling references.
47
 */
48
 
49
#define STDIN_BUF_SIZE 128
50
 
51
private iodev_proc_init(stdin_init);
52
private iodev_proc_open_device(stdin_open);
53
const gx_io_device gs_iodev_stdin =
54
    iodev_special("%stdin%", stdin_init, stdin_open);
55
 
56
#define STDOUT_BUF_SIZE 128
57
private iodev_proc_open_device(stdout_open);
58
const gx_io_device gs_iodev_stdout =
59
    iodev_special("%stdout%", iodev_no_init, stdout_open);
60
 
61
#define STDERR_BUF_SIZE 128
62
private iodev_proc_open_device(stderr_open);
63
const gx_io_device gs_iodev_stderr =
64
    iodev_special("%stderr%", iodev_no_init, stderr_open);
65
 
66
/* ------- %stdin, %stdout, and %stderr ------ */
67
 
68
/*
69
 * According to Adobe, it is legal to close the %std... files and then
70
 * re-open them later.  However, the re-opened file object is not 'eq' to
71
 * the original file object (in our implementation, it has a different
72
 * read_id or write_id).
73
 */
74
 
75
private int
76
    s_stdin_read_process(stream_state *, stream_cursor_read *,
77
			 stream_cursor_write *, bool);
78
 
79
private int
80
stdin_init(gx_io_device * iodev, gs_memory_t * mem)
81
{
82
    mem->gs_lib_ctx->stdin_is_interactive = true;
83
    return 0;
84
}
85
 
86
/* Read from stdin into the buffer. */
87
/* If interactive, only read one character. */
88
private int
89
s_stdin_read_process(stream_state * st, stream_cursor_read * ignore_pr,
90
		     stream_cursor_write * pw, bool last)
91
{
92
    FILE *file = ((stream *) st)->file;		/* hack for file streams */
93
    int wcount = (int)(pw->limit - pw->ptr);
94
    int count;
95
 
96
    if (wcount <= 0)
97
	return 0;
98
    count = gp_stdin_read( (char*) pw->ptr + 1, wcount,
99
			   st->memory->gs_lib_ctx->stdin_is_interactive, file);
100
    pw->ptr += (count < 0) ? 0 : count;
101
    return ((count < 0) ? ERRC : (count == 0) ? EOFC : count);
102
}
103
 
104
private int
105
stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
106
	   gs_memory_t * mem)
107
{
108
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state;	/* see above */
109
    stream *s;
110
 
111
    if (!streq1(access, 'r'))
112
	return_error(e_invalidfileaccess);
113
    if (file_is_invalid(s, &ref_stdin)) {
114
	/****** stdin SHOULD NOT LINE-BUFFER ******/
115
	gs_memory_t *mem = imemory_system;
116
	byte *buf;
117
 
118
	s = file_alloc_stream(mem, "stdin_open(stream)");
119
	/* We want stdin to read only one character at a time, */
120
	/* but it must have a substantial buffer, in case it is used */
121
	/* by a stream that requires more than one input byte */
122
	/* to make progress. */
123
	buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)");
124
	if (s == 0 || buf == 0)
125
	    return_error(e_VMerror);
126
	sread_file(s, gs_stdin, buf, STDIN_BUF_SIZE);
127
	s->procs.process = s_stdin_read_process;
128
	s->save_close = s_std_null;
129
	s->procs.close = file_close_file;
130
	make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s);
131
	*ps = s;
132
	return 1;
133
    }
134
    *ps = s;
135
    return 0;
136
}
137
/* This is the public routine for getting the stdin stream. */
138
int
139
zget_stdin(i_ctx_t *i_ctx_p, stream ** ps)
140
{
141
    stream *s;
142
    gx_io_device *iodev;
143
    int code;
144
 
145
    if (file_is_valid(s, &ref_stdin)) {
146
	*ps = s;
147
	return 0;
148
    }
149
    iodev = gs_findiodevice((const byte *)"%stdin", 6);
150
    iodev->state = i_ctx_p;
151
    code = (*iodev->procs.open_device)(iodev, "r", ps, imemory_system);
152
    iodev->state = NULL;
153
    return min(code, 0);
154
}
155
/* Test whether a stream is stdin. */
156
bool
157
zis_stdin(const stream *s)
158
{
159
    return (s_is_valid(s) && s->procs.process == s_stdin_read_process);
160
}
161
 
162
private int
163
stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
164
	    gs_memory_t * mem)
165
{
166
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state;	/* see above */
167
    stream *s;
168
 
169
    if (!streq1(access, 'w'))
170
	return_error(e_invalidfileaccess);
171
    if (file_is_invalid(s, &ref_stdout)) {
172
	gs_memory_t *mem = imemory_system;
173
	byte *buf;
174
 
175
	s = file_alloc_stream(mem, "stdout_open(stream)");
176
	buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)");
177
	if (s == 0 || buf == 0)
178
	    return_error(e_VMerror);
179
	swrite_file(s, gs_stdout, buf, STDOUT_BUF_SIZE);
180
	s->save_close = s->procs.flush;
181
	s->procs.close = file_close_file;
182
	make_file(&ref_stdout, a_write | avm_system, s->write_id, s);
183
	*ps = s;
184
	return 1;
185
    }
186
    *ps = s;
187
    return 0;
188
}
189
/* This is the public routine for getting the stdout stream. */
190
int
191
zget_stdout(i_ctx_t *i_ctx_p, stream ** ps)
192
{
193
    stream *s;
194
    gx_io_device *iodev;
195
    int code;
196
 
197
    if (file_is_valid(s, &ref_stdout)) {
198
	*ps = s;
199
	return 0;
200
    }
201
    iodev = gs_findiodevice((const byte *)"%stdout", 7);
202
    iodev->state = i_ctx_p;
203
    code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
204
    iodev->state = NULL;
205
    return min(code, 0);
206
}
207
 
208
private int
209
stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
210
	    gs_memory_t * mem)
211
{
212
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state;	/* see above */
213
    stream *s;
214
 
215
    if (!streq1(access, 'w'))
216
	return_error(e_invalidfileaccess);
217
    if (file_is_invalid(s, &ref_stderr)) {
218
	gs_memory_t *mem = imemory_system;
219
	byte *buf;
220
 
221
	s = file_alloc_stream(mem, "stderr_open(stream)");
222
	buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)");
223
	if (s == 0 || buf == 0)
224
	    return_error(e_VMerror);
225
	swrite_file(s, gs_stderr, buf, STDERR_BUF_SIZE);
226
	s->save_close = s->procs.flush;
227
	s->procs.close = file_close_file;
228
	make_file(&ref_stderr, a_write | avm_system, s->write_id, s);
229
	*ps = s;
230
	return 1;
231
    }
232
    *ps = s;
233
    return 0;
234
}
235
/* This is the public routine for getting the stderr stream. */
236
int
237
zget_stderr(i_ctx_t *i_ctx_p, stream ** ps)
238
{
239
    stream *s;
240
    gx_io_device *iodev;
241
    int code;
242
 
243
    if (file_is_valid(s, &ref_stderr)) {
244
	*ps = s;
245
	return 0;
246
    }
247
    iodev = gs_findiodevice((const byte *)"%stderr", 7);
248
    iodev->state = i_ctx_p;
249
    code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
250
    iodev->state = NULL;
251
    return min(code, 0);
252
}