28
28
const char iodev_dtype_stdio[] = "Special";
29
29
#define iodev_special(dname, init, open) {\
30
30
dname, iodev_dtype_stdio,\
31
{ init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
32
iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
33
iodev_no_enumerate_files, NULL, NULL,\
34
iodev_no_get_params, iodev_no_put_params\
31
{ init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
32
iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
33
iodev_no_enumerate_files, NULL, NULL,\
34
iodev_no_get_params, iodev_no_put_params\
84
84
/* If interactive, only read one character. */
86
86
s_stdin_read_process(stream_state * st, stream_cursor_read * ignore_pr,
87
stream_cursor_write * pw, bool last)
87
stream_cursor_write * pw, bool last)
89
89
FILE *file = ((stream *) st)->file; /* hack for file streams */
90
90
int wcount = (int)(pw->limit - pw->ptr);
95
95
count = gp_stdin_read( (char*) pw->ptr + 1, wcount,
96
st->memory->gs_lib_ctx->stdin_is_interactive, file);
96
st->memory->gs_lib_ctx->stdin_is_interactive, file);
97
97
pw->ptr += (count < 0) ? 0 : count;
98
98
return ((count < 0) ? ERRC : (count == 0) ? EOFC : count);
102
102
stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
105
105
i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
108
108
if (!streq1(access, 'r'))
109
return_error(e_invalidfileaccess);
109
return_error(e_invalidfileaccess);
110
110
if (file_is_invalid(s, &ref_stdin)) {
111
/****** stdin SHOULD NOT LINE-BUFFER ******/
112
gs_memory_t *mem = imemory_system;
111
/****** stdin SHOULD NOT LINE-BUFFER ******/
112
gs_memory_t *mem = imemory_system;
115
s = file_alloc_stream(mem, "stdin_open(stream)");
116
/* We want stdin to read only one character at a time, */
117
/* but it must have a substantial buffer, in case it is used */
118
/* by a stream that requires more than one input byte */
119
/* to make progress. */
120
buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)");
121
if (s == 0 || buf == 0)
122
return_error(e_VMerror);
123
sread_file(s, gs_stdin, buf, STDIN_BUF_SIZE);
124
s->procs.process = s_stdin_read_process;
125
s->save_close = s_std_null;
126
s->procs.close = file_close_file;
127
make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s);
115
s = file_alloc_stream(mem, "stdin_open(stream)");
116
/* We want stdin to read only one character at a time, */
117
/* but it must have a substantial buffer, in case it is used */
118
/* by a stream that requires more than one input byte */
119
/* to make progress. */
120
buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)");
121
if (s == 0 || buf == 0)
122
return_error(e_VMerror);
123
sread_file(s, gs_stdin, buf, STDIN_BUF_SIZE);
124
s->procs.process = s_stdin_read_process;
125
s->save_close = s_std_null;
126
s->procs.close = file_close_file;
127
make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s);
160
160
s_stdout_swrite_process(stream_state *, stream_cursor_read *,
161
stream_cursor_write *, bool);
161
stream_cursor_write *, bool);
163
163
/* Write a buffer to stdout, potentially writing to callback */
165
165
s_stdout_write_process(stream_state * st, stream_cursor_read * ignore_pr,
166
stream_cursor_write * pw, bool last)
166
stream_cursor_write * pw, bool last)
168
168
uint count = pr->limit - pr->ptr;
173
173
written = outwrite(st->memory, pr->ptr + 1, count);
174
174
if (written < count) {
176
176
pr->ptr += written;
181
181
stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
184
184
i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
187
187
if (!streq1(access, 'w'))
188
return_error(e_invalidfileaccess);
188
return_error(e_invalidfileaccess);
189
189
if (file_is_invalid(s, &ref_stdout)) {
190
gs_memory_t *mem = imemory_system;
190
gs_memory_t *mem = imemory_system;
193
s = file_alloc_stream(mem, "stdout_open(stream)");
194
buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)");
195
if (s == 0 || buf == 0)
196
return_error(e_VMerror);
197
swrite_file(s, gs_stdout, buf, STDOUT_BUF_SIZE);
198
s->save_close = s->procs.flush;
199
s->procs.close = file_close_file;
200
s->procs.process = s_stdout_write_process;
201
make_file(&ref_stdout, a_write | avm_system, s->write_id, s);
193
s = file_alloc_stream(mem, "stdout_open(stream)");
194
buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)");
195
if (s == 0 || buf == 0)
196
return_error(e_VMerror);
197
swrite_file(s, gs_stdout, buf, STDOUT_BUF_SIZE);
198
s->save_close = s->procs.flush;
199
s->procs.close = file_close_file;
200
s->procs.process = s_stdout_write_process;
201
make_file(&ref_stdout, a_write | avm_system, s->write_id, s);
228
228
stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
231
231
i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
234
234
if (!streq1(access, 'w'))
235
return_error(e_invalidfileaccess);
235
return_error(e_invalidfileaccess);
236
236
if (file_is_invalid(s, &ref_stderr)) {
237
gs_memory_t *mem = imemory_system;
237
gs_memory_t *mem = imemory_system;
240
s = file_alloc_stream(mem, "stderr_open(stream)");
241
buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)");
242
if (s == 0 || buf == 0)
243
return_error(e_VMerror);
244
swrite_file(s, gs_stderr, buf, STDERR_BUF_SIZE);
245
s->save_close = s->procs.flush;
246
s->procs.close = file_close_file;
247
make_file(&ref_stderr, a_write | avm_system, s->write_id, s);
240
s = file_alloc_stream(mem, "stderr_open(stream)");
241
buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)");
242
if (s == 0 || buf == 0)
243
return_error(e_VMerror);
244
swrite_file(s, gs_stderr, buf, STDERR_BUF_SIZE);
245
s->save_close = s->procs.flush;
246
s->procs.close = file_close_file;
247
make_file(&ref_stderr, a_write | avm_system, s->write_id, s);