~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/ziodevsc.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
  
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
7
 
   This software is distributed under license and may not be copied, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/* $Id: ziodevsc.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* %stdxxx IODevice implementation using callouts for PostScript interpreter */
16
 
#include "stdio_.h"
17
 
#include "ghost.h"
18
 
#include "gpcheck.h"
19
 
#include "gp.h"
20
 
#include "oper.h"
21
 
#include "stream.h"
22
 
#include "gxiodev.h"            /* must come after stream.h */
23
 
                                /* and before files.h */
24
 
#include "istream.h"
25
 
#include "files.h"
26
 
#include "ifilter.h"
27
 
#include "store.h"
28
 
 
29
 
/* Define the special devices. */
30
 
const char iodev_dtype_stdio[] = "Special";
31
 
#define iodev_special(dname, init, open) {\
32
 
    dname, iodev_dtype_stdio,\
33
 
        { init, open, iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,\
34
 
          iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\
35
 
          iodev_no_enumerate_files, NULL, NULL,\
36
 
          iodev_no_get_params, iodev_no_put_params\
37
 
        }\
38
 
}
39
 
 
40
 
/*
41
 
 * We need the current context pointer for accessing / opening the %std
42
 
 * IODevices.  However, this is not available to the open routine.
43
 
 * Therefore, we use the hack of storing this pointer in the IODevice state
44
 
 * pointer just before calling the open routines.  We clear the pointer
45
 
 * immediately afterwards so as not to wind up with dangling references.
46
 
 */
47
 
 
48
 
#define STDIN_BUF_SIZE 1024
49
 
static iodev_proc_init(stdin_init);
50
 
static iodev_proc_open_device(stdin_open);
51
 
const gx_io_device gs_iodev_stdin =
52
 
    iodev_special("%stdin%", stdin_init, stdin_open);
53
 
 
54
 
#define STDOUT_BUF_SIZE 128
55
 
static iodev_proc_open_device(stdout_open);
56
 
const gx_io_device gs_iodev_stdout =
57
 
    iodev_special("%stdout%", iodev_no_init, stdout_open);
58
 
 
59
 
#define STDERR_BUF_SIZE 128
60
 
static iodev_proc_open_device(stderr_open);
61
 
const gx_io_device gs_iodev_stderr =
62
 
    iodev_special("%stderr%", iodev_no_init, stderr_open);
63
 
 
64
 
/* ------- %stdin, %stdout, and %stderr ------ */
65
 
 
66
 
/*
67
 
 * According to Adobe, it is legal to close the %std... files and then
68
 
 * re-open them later.  However, the re-opened file object is not 'eq' to
69
 
 * the original file object (in our implementation, it has a different
70
 
 * read_id or write_id). This is performed in 'file_close_file' by the
71
 
 * call to file_close_disable.
72
 
 */
73
 
 
74
 
static int
75
 
    s_stdin_read_process(stream_state *, stream_cursor_read *,
76
 
                         stream_cursor_write *, bool);
77
 
 
78
 
static int
79
 
stdin_init(gx_io_device * iodev, gs_memory_t * mem)
80
 
{
81
 
    mem->gs_lib_ctx->stdin_is_interactive = true;
82
 
    return 0;
83
 
}
84
 
 
85
 
/* Read from stdin into the buffer. */
86
 
/* If interactive, only read one character. */
87
 
static int
88
 
s_stdin_read_process(stream_state * st, stream_cursor_read * ignore_pr,
89
 
                     stream_cursor_write * pw, bool last)
90
 
{
91
 
    int wcount = (int)(pw->limit - pw->ptr);
92
 
    int count;
93
 
    gs_memory_t *mem = st->memory;
94
 
 
95
 
    if (wcount <= 0)
96
 
        return 0;
97
 
 
98
 
    /* do the callout */
99
 
    if (mem->gs_lib_ctx->stdin_fn)
100
 
        count = (*mem->gs_lib_ctx->stdin_fn)
101
 
            (mem->gs_lib_ctx->caller_handle, (char *)pw->ptr + 1,
102
 
             mem->gs_lib_ctx->stdin_is_interactive ? 1 : wcount);
103
 
    else
104
 
        count = gp_stdin_read((char *)pw->ptr + 1, wcount,
105
 
                      mem->gs_lib_ctx->stdin_is_interactive,
106
 
                      mem->gs_lib_ctx->fstdin);
107
 
 
108
 
    pw->ptr += (count < 0) ? 0 : count;
109
 
    return ((count < 0) ? ERRC : (count == 0) ? EOFC : count);
110
 
}
111
 
 
112
 
static int
113
 
stdin_open(gx_io_device * iodev, const char *access, stream ** ps,
114
 
           gs_memory_t * mem)
115
 
{
116
 
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
117
 
    stream *s;
118
 
 
119
 
    if (!streq1(access, 'r'))
120
 
        return_error(e_invalidfileaccess);
121
 
    if (file_is_invalid(s, &ref_stdin)) {
122
 
        /****** stdin SHOULD NOT LINE-BUFFER ******/
123
 
        gs_memory_t *mem = imemory_system;
124
 
        byte *buf;
125
 
        static const stream_procs p = {
126
 
            s_std_noavailable, s_std_noseek, s_std_read_reset,
127
 
            s_std_read_flush, file_close_file, s_stdin_read_process
128
 
        };
129
 
 
130
 
        s = file_alloc_stream(mem, "stdin_open(stream)");
131
 
 
132
 
        /* We want stdin to read only one character at a time, */
133
 
        /* but it must have a substantial buffer, in case it is used */
134
 
        /* by a stream that requires more than one input byte */
135
 
        /* to make progress. */
136
 
        buf = gs_alloc_bytes(mem, STDIN_BUF_SIZE, "stdin_open(buffer)");
137
 
        if (s == 0 || buf == 0)
138
 
            return_error(e_VMerror);
139
 
 
140
 
        s_std_init(s, buf, STDIN_BUF_SIZE, &p, s_mode_read);
141
 
        s->file = 0;
142
 
        s->file_modes = s->modes;
143
 
        s->file_offset = 0;
144
 
        s->file_limit = max_long;
145
 
        s->save_close = s_std_null;
146
 
        make_file(&ref_stdin, a_readonly | avm_system, s->read_id, s);
147
 
        *ps = s;
148
 
        return 1;
149
 
    }
150
 
    *ps = s;
151
 
    return 0;
152
 
}
153
 
/* This is the public routine for getting the stdin stream. */
154
 
int
155
 
zget_stdin(i_ctx_t *i_ctx_p, stream ** ps)
156
 
{
157
 
    stream *s;
158
 
    gx_io_device *iodev;
159
 
    int code;
160
 
 
161
 
    if (file_is_valid(s, &ref_stdin)) {
162
 
        *ps = s;
163
 
        return 0;
164
 
    }
165
 
    iodev = gs_findiodevice((const byte *)"%stdin", 6);
166
 
    iodev->state = i_ctx_p;
167
 
    code = (*iodev->procs.open_device)(iodev, "r", ps, imemory_system);
168
 
    iodev->state = NULL;
169
 
    return min(code, 0);
170
 
}
171
 
 
172
 
/* Test whether a stream is stdin. */
173
 
bool
174
 
zis_stdin(const stream *s)
175
 
{
176
 
    return (s_is_valid(s) && s->procs.process == s_stdin_read_process);
177
 
}
178
 
 
179
 
/* Write a buffer to stdout, potentially writing to callback */
180
 
static int
181
 
s_stdout_write_process(stream_state * st, stream_cursor_read *pr,
182
 
                     stream_cursor_write *ignore_pw, bool last)
183
 
{
184
 
    uint count = pr->limit - pr->ptr;
185
 
    int written;
186
 
 
187
 
    if (count == 0) 
188
 
        return 0;
189
 
    written = outwrite(st->memory, (const char *)pr->ptr + 1, count);
190
 
    if (written < count)
191
 
        return ERRC;
192
 
    pr->ptr += written;
193
 
    return 0;
194
 
}
195
 
 
196
 
static int
197
 
stdout_open(gx_io_device * iodev, const char *access, stream ** ps,
198
 
            gs_memory_t * mem)
199
 
{
200
 
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
201
 
    stream *s;
202
 
 
203
 
    if (!streq1(access, 'w'))
204
 
        return_error(e_invalidfileaccess);
205
 
    if (file_is_invalid(s, &ref_stdout)) {
206
 
        gs_memory_t *mem = imemory_system;
207
 
        byte *buf;
208
 
        static const stream_procs p = {
209
 
            s_std_noavailable, s_std_noseek, s_std_write_reset,
210
 
            s_std_write_flush, file_close_file, s_stdout_write_process
211
 
        };
212
 
 
213
 
        s = file_alloc_stream(mem, "stdout_open(stream)");
214
 
        buf = gs_alloc_bytes(mem, STDOUT_BUF_SIZE, "stdout_open(buffer)");
215
 
        if (s == 0 || buf == 0)
216
 
            return_error(e_VMerror);
217
 
        s_std_init(s, buf, STDOUT_BUF_SIZE, &p, s_mode_write);
218
 
        s->file = 0;
219
 
        s->file_modes = s->modes;
220
 
        s->file_offset = 0;             /* in case we switch to reading later */
221
 
        s->file_limit = max_long;       /* ibid. */
222
 
        s->save_close = s->procs.flush;
223
 
        make_file(&ref_stdout, a_write | avm_system, s->write_id, s);
224
 
        *ps = s;
225
 
        return 1;
226
 
    }
227
 
    *ps = s;
228
 
    return 0;
229
 
}
230
 
 
231
 
/* This is the public routine for getting the stdout stream. */
232
 
int
233
 
zget_stdout(i_ctx_t *i_ctx_p, stream ** ps)
234
 
{
235
 
    stream *s;
236
 
    gx_io_device *iodev;
237
 
    int code;
238
 
 
239
 
    if (file_is_valid(s, &ref_stdout)) {
240
 
        *ps = s;
241
 
        return 0;
242
 
    }
243
 
    iodev = gs_findiodevice((const byte *)"%stdout", 7);
244
 
    iodev->state = i_ctx_p;
245
 
    code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
246
 
    iodev->state = NULL;
247
 
    return min(code, 0);
248
 
}
249
 
 
250
 
/* Write a buffer to stderr, potentially writing to callback */
251
 
static int
252
 
s_stderr_write_process(stream_state * st, stream_cursor_read *pr,
253
 
                     stream_cursor_write *ignore_pw, bool last)
254
 
{
255
 
    uint count = pr->limit - pr->ptr;
256
 
    int written;
257
 
 
258
 
    if (count == 0) 
259
 
        return 0;
260
 
    written = errwrite((const char *)(pr->ptr + 1), count);
261
 
    if (written < count) 
262
 
        return ERRC;
263
 
    pr->ptr += written;
264
 
    return 0;
265
 
}
266
 
 
267
 
static int
268
 
stderr_open(gx_io_device * iodev, const char *access, stream ** ps,
269
 
            gs_memory_t * mem)
270
 
{
271
 
    i_ctx_t *i_ctx_p = (i_ctx_t *)iodev->state; /* see above */
272
 
    stream *s;
273
 
 
274
 
    if (!streq1(access, 'w'))
275
 
        return_error(e_invalidfileaccess);
276
 
    if (file_is_invalid(s, &ref_stderr)) {
277
 
        gs_memory_t *mem = imemory_system;
278
 
        byte *buf;
279
 
        static const stream_procs p = {
280
 
            s_std_noavailable, s_std_noseek, s_std_write_reset,
281
 
            s_std_write_flush, file_close_file, s_stderr_write_process
282
 
        };
283
 
 
284
 
        s = file_alloc_stream(mem, "stderr_open(stream)");
285
 
        buf = gs_alloc_bytes(mem, STDERR_BUF_SIZE, "stderr_open(buffer)");
286
 
        if (s == 0 || buf == 0)
287
 
            return_error(e_VMerror);
288
 
        s_std_init(s, buf, STDERR_BUF_SIZE, &p, s_mode_write);
289
 
        s->file = 0;
290
 
        s->file_modes = s->modes;
291
 
        s->file_offset = 0;             /* in case we switch to reading later */
292
 
        s->file_limit = max_long;       /* ibid. */
293
 
        s->save_close = s->procs.flush;
294
 
        make_file(&ref_stderr, a_write | avm_system, s->write_id, s);
295
 
        *ps = s;
296
 
        return 1;
297
 
    }
298
 
    *ps = s;
299
 
    return 0;
300
 
}
301
 
 
302
 
/* This is the public routine for getting the stderr stream. */
303
 
int
304
 
zget_stderr(i_ctx_t *i_ctx_p, stream ** ps)
305
 
{
306
 
    stream *s;
307
 
    gx_io_device *iodev;
308
 
    int code;
309
 
 
310
 
    if (file_is_valid(s, &ref_stderr)) {
311
 
        *ps = s;
312
 
        return 0;
313
 
    }
314
 
    iodev = gs_findiodevice((const byte *)"%stderr", 7);
315
 
    iodev->state = i_ctx_p;
316
 
    code = (*iodev->procs.open_device)(iodev, "w", ps, imemory_system);
317
 
    iodev->state = NULL;
318
 
    return min(code, 0);
319
 
}