/* Make a reusable file stream. */ static int make_rfs(i_ctx_t *i_ctx_p, os_ptr op, stream *fs, long offset, long length) { uint save_space = icurrent_space; uint stream_space = imemory_space((const gs_ref_memory_t *)fs->memory); gs_const_string fname; gs_parsed_file_name_t pname; stream *s; int code; if (sfilename(fs, &fname) < 0) return_error(e_ioerror); code = gs_parse_file_name(&pname, (const char *)fname.data, fname.size, imemory); if (code < 0) return code; if (pname.len == 0) /* %stdin% etc. won't have a filename */ return_error(e_invalidfileaccess); /* can't reopen */ if (pname.iodev == NULL) pname.iodev = iodev_default(imemory); /* Open the file again, to be independent of the source. */ ialloc_set_space(idmemory, stream_space); code = zopen_file(i_ctx_p, &pname, "r", &s, imemory); ialloc_set_space(idmemory, save_space); if (code < 0) return code; if (sread_subfile(s, offset, length) < 0) { sclose(s); return_error(e_ioerror); } s->close_at_eod = false; make_stream_file(op, s, "r"); return 0; }
/* <string> .libfile <string> false */ int /* exported for zsysvm.c */ zlibfile(i_ctx_t *i_ctx_p) { os_ptr op = osp; int code; byte cname[DEFAULT_BUFFER_SIZE]; uint clen; gs_parsed_file_name_t pname; stream *s; gx_io_device *iodev_dflt; check_ostack(2); code = parse_file_name(op, &pname, i_ctx_p->LockFilePermissions, imemory); if (code < 0) return code; iodev_dflt = iodev_default(imemory); if (pname.iodev == NULL) pname.iodev = iodev_dflt; if (pname.iodev != iodev_dflt) { /* Non-OS devices don't have search paths (yet). */ code = zopen_file(i_ctx_p, &pname, "r", &s, imemory); if (code >= 0) { code = ssetfilename(s, op->value.const_bytes, r_size(op)); if (code < 0) { sclose(s); return_error(e_VMerror); } } if (code < 0) { push(1); make_false(op); return 0; } make_stream_file(op, s, "r"); } else { ref fref; code = lib_file_open(i_ctx_p->lib_path, imemory, i_ctx_p, pname.fname, pname.len, (char *)cname, sizeof(cname), &clen, &fref); if (code >= 0) { s = fptr(&fref); code = ssetfilename(s, cname, clen); if (code < 0) { sclose(s); return_error(e_VMerror); } } if (code < 0) { if (code == e_VMerror || code == e_invalidfileaccess) return code; push(1); make_false(op); return 0; } ref_assign(op, &fref); } push(1); make_true(op); return 0; }
/* <name_string> <access_string> file <file> */ int /* exported for zsysvm.c */ zfile(i_ctx_t *i_ctx_p) { os_ptr op = osp; char file_access[4]; gs_parsed_file_name_t pname; int code = parse_file_access_string(op, file_access); stream *s; if (code < 0) return code; code = parse_file_name(op - 1, &pname, i_ctx_p->LockFilePermissions); if (code < 0) return code; /* * HACK: temporarily patch the current context pointer into the * state pointer for stdio-related devices. See ziodev.c for * more information. */ if (pname.iodev && pname.iodev->dtype == iodev_dtype_stdio) { bool statement = (strcmp(pname.iodev->dname, "%statementedit%") == 0); bool lineedit = (strcmp(pname.iodev->dname, "%lineedit%") == 0); if (pname.fname) return_error(e_invalidfileaccess); if (statement || lineedit) { /* These need special code to support callouts */ gx_io_device *indev = gs_findiodevice((const byte *)"%stdin", 6); stream *ins; if (strcmp(file_access, "r")) return_error(e_invalidfileaccess); indev->state = i_ctx_p; code = (indev->procs.open_device)(indev, file_access, &ins, imemory); indev->state = 0; if (code < 0) return code; check_ostack(2); push(2); make_stream_file(op - 3, ins, file_access); make_bool(op-2, statement); make_int(op-1, 0); make_string(op, icurrent_space, 0, NULL); return zfilelineedit(i_ctx_p); } pname.iodev->state = i_ctx_p; code = (*pname.iodev->procs.open_device)(pname.iodev, file_access, &s, imemory); pname.iodev->state = NULL; } else { if (pname.iodev == NULL) pname.iodev = iodev_default; code = zopen_file(i_ctx_p, &pname, file_access, &s, imemory); } if (code < 0) return code; code = ssetfilename(s, op[-1].value.const_bytes, r_size(op - 1)); if (code < 0) { sclose(s); return_error(e_VMerror); } make_stream_file(op - 1, s, file_access); pop(1); return code; }