diff options
Diffstat (limited to 'base/gslibctx.c')
-rw-r--r-- | base/gslibctx.c | 238 |
1 files changed, 203 insertions, 35 deletions
diff --git a/base/gslibctx.c b/base/gslibctx.c index fbfd9143..63dfbe2e 100644 --- a/base/gslibctx.c +++ b/base/gslibctx.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2019 Artifex Software, Inc. +/* Copyright (C) 2001-2020 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -86,7 +86,7 @@ gs_lib_ctx_set_icc_directory(const gs_memory_t *mem_gc, const char* pname, result = (char*) gs_alloc_bytes(p_ctx_mem, dir_namelen+1, "gs_lib_ctx_set_icc_directory"); if (result == NULL) { - return -1; + return gs_error_VMerror; } strcpy(result, pname); p_ctx->profiledir = result; @@ -388,6 +388,7 @@ void gs_lib_ctx_fin(gs_memory_t *mem) gs_memory_t *ctx_mem; int refs, i; gs_fs_list_t *fs; + gs_callout_list_t *entry; if (!mem || !mem->gs_lib_ctx) return; @@ -419,6 +420,7 @@ void gs_lib_ctx_fin(gs_memory_t *mem) #ifdef WITH_CAL cal_fin(ctx->core->cal_ctx, ctx->core->memory); #endif + gs_purge_scratch_files(ctx->core->memory); gs_purge_control_paths(ctx->core->memory, gs_permit_file_reading); gs_purge_control_paths(ctx->core->memory, gs_permit_file_writing); gs_purge_control_paths(ctx->core->memory, gs_permit_file_control); @@ -430,6 +432,13 @@ void gs_lib_ctx_fin(gs_memory_t *mem) fs = next; } + entry = ctx->core->callouts; + while (entry) { + gs_callout_list_t *next = entry->next; + gs_free_object(mem->non_gc_memory, entry, "gs_callout_list_t"); + entry = next; + } + for (i = 0; i < ctx->core->argc; i++) gs_free_object(ctx->core->memory, ctx->core->argv[i], "gs_lib_ctx_arg"); gs_free_object(ctx->core->memory, ctx->core->argv, "gs_lib_ctx_args"); @@ -486,7 +495,7 @@ int outwrite(const gs_memory_t *mem, const char *str, int len) code = gp_fwrite(str, 1, len, core->fstdout2); gp_fflush(core->fstdout2); } else if (core->stdout_fn) { - return (*core->stdout_fn)(core->caller_handle, str, len); + return (*core->stdout_fn)(core->std_caller_handle, str, len); } else { code = fwrite(str, 1, len, core->fstdout); fflush(core->fstdout); @@ -522,7 +531,7 @@ int errwrite(const gs_memory_t *mem, const char *str, int len) return 0; core = ctx->core; if (core->stderr_fn) - return (*core->stderr_fn)(core->caller_handle, str, len); + return (*core->stderr_fn)(core->std_caller_handle, str, len); code = fwrite(str, 1, len, core->fstderr); fflush(core->fstderr); @@ -638,7 +647,7 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) char *fp, f[gp_file_name_sizeof]; const int pipe = 124; /* ASCII code for '|' */ const int len = strlen(fname); - int i; + int i, code; /* Be sure the string copy will fit */ if (len >= gp_file_name_sizeof) @@ -649,8 +658,6 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) rewrite_percent_specifiers(f); for (i = 0; i < len; i++) { if (f[i] == pipe) { - int code; - fp = &f[i + 1]; /* Because we potentially have to check file permissions at two levels for the output file (gx_device_open_output_file and the low level @@ -661,11 +668,17 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) code = gs_add_control_path(mem, gs_permit_file_writing, f); if (code < 0) return code; + code = gs_add_control_path(mem, gs_permit_file_control, f); + if (code < 0) + return code; break; } if (!IS_WHITESPACE(f[i])) break; } + code = gs_add_control_path(mem, gs_permit_file_control, fp); + if (code < 0) + return code; return gs_add_control_path(mem, gs_permit_file_writing, fp); } @@ -675,7 +688,7 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) char *fp, f[gp_file_name_sizeof]; const int pipe = 124; /* ASCII code for '|' */ const int len = strlen(fname); - int i; + int i, code; /* Be sure the string copy will fit */ if (len >= gp_file_name_sizeof) @@ -685,8 +698,6 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) /* Try to rewrite any %d (or similar) in the string */ for (i = 0; i < len; i++) { if (f[i] == pipe) { - int code; - fp = &f[i + 1]; /* Because we potentially have to check file permissions at two levels for the output file (gx_device_open_output_file and the low level @@ -697,11 +708,17 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) code = gs_remove_control_path(mem, gs_permit_file_writing, f); if (code < 0) return code; + code = gs_remove_control_path(mem, gs_permit_file_control, f); + if (code < 0) + return code; break; } if (!IS_WHITESPACE(f[i])) break; } + code = gs_remove_control_path(mem, gs_permit_file_control, fp); + if (code < 0) + return code; return gs_remove_control_path(mem, gs_permit_file_writing, fp); } @@ -727,6 +744,12 @@ gs_add_explicit_control_path(gs_memory_t *mem, const char *arg, gs_path_control_ int gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const char *path, size_t len) { + return gs_add_control_path_len_flags(mem, type, path, len, 0); +} + +int +gs_add_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type, const char *path, size_t len, int flags) +{ gs_path_control_set_t *control; unsigned int n, i; gs_lib_ctx_core_t *core; @@ -766,33 +789,34 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch n = control->num; for (i = 0; i < n; i++) { - if (strncmp(control->paths[i], buffer, rlen) == 0 && - control->paths[i][rlen] == 0) { + if (strncmp(control->entry[i].path, buffer, rlen) == 0 && + control->entry[i].path[rlen] == 0) { gs_free_object(core->memory, buffer, "gs_add_control_path_len"); return 0; /* Already there! */ } } if (control->num == control->max) { - char **p; + gs_path_control_entry_t *p; n = control->max * 2; if (n == 0) { n = 4; - p = (char **)gs_alloc_bytes(core->memory, sizeof(*p)*n, "gs_lib_ctx(paths)"); + p = (gs_path_control_entry_t *)gs_alloc_bytes(core->memory, sizeof(*p)*n, "gs_lib_ctx(entries)"); } else - p = (char **)gs_resize_object(core->memory, control->paths, sizeof(*p)*n, "gs_lib_ctx(paths)"); + p = (gs_path_control_entry_t *)gs_resize_object(core->memory, control->entry, sizeof(*p)*n, "gs_lib_ctx(entries)"); if (p == NULL) { gs_free_object(core->memory, buffer, "gs_add_control_path_len"); return gs_error_VMerror; } - control->paths = p; + control->entry = p; control->max = n; } n = control->num; - control->paths[n] = buffer; - control->paths[n][len] = 0; + control->entry[n].path = buffer; + control->entry[n].path[len] = 0; + control->entry[n].flags = flags; control->num++; return 0; @@ -801,15 +825,24 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch int gs_add_control_path(const gs_memory_t *mem, gs_path_control_t type, const char *path) { - if (path == NULL) - return 0; + return gs_add_control_path_len_flags(mem, type, path, strlen(path), 0); +} - return gs_add_control_path_len(mem, type, path, strlen(path)); +int +gs_add_control_path_flags(const gs_memory_t *mem, gs_path_control_t type, const char *path, int flags) +{ + return gs_add_control_path_len_flags(mem, type, path, strlen(path), flags); } int gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const char *path, size_t len) { + return gs_remove_control_path_len_flags(mem, type, path, len, 0); +} + +int +gs_remove_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type, const char *path, size_t len, int flags) +{ gs_path_control_set_t *control; unsigned int n, i; gs_lib_ctx_core_t *core; @@ -848,17 +881,18 @@ gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const n = control->num; for (i = 0; i < n; i++) { - if (strncmp(control->paths[i], buffer, len) == 0 && - control->paths[i][len] == 0) + if (control->entry[i].flags == flags && + strncmp(control->entry[i].path, buffer, len) == 0 && + control->entry[i].path[len] == 0) break; } gs_free_object(core->memory, buffer, "gs_remove_control_path_len"); if (i == n) return 0; - gs_free_object(core->memory, control->paths[i], "gs_lib_ctx(path)"); + gs_free_object(core->memory, control->entry[i].path, "gs_lib_ctx(path)"); for (;i < n-1; i++) - control->paths[i] = control->paths[i+1]; + control->entry[i] = control->entry[i+1]; control->num = n-1; return 0; @@ -870,14 +904,23 @@ gs_remove_control_path(const gs_memory_t *mem, gs_path_control_t type, const cha if (path == NULL) return 0; - return gs_remove_control_path_len(mem, type, path, strlen(path)); + return gs_remove_control_path_len_flags(mem, type, path, strlen(path), 0); +} + +int +gs_remove_control_path_flags(const gs_memory_t *mem, gs_path_control_t type, const char *path, int flags) +{ + if (path == NULL) + return 0; + + return gs_remove_control_path_len_flags(mem, type, path, strlen(path), flags); } void gs_purge_control_paths(const gs_memory_t *mem, gs_path_control_t type) { gs_path_control_set_t *control; - unsigned int n, i; + unsigned int n, in, out; gs_lib_ctx_core_t *core; if (mem == NULL || mem->gs_lib_ctx == NULL || @@ -899,13 +942,70 @@ gs_purge_control_paths(const gs_memory_t *mem, gs_path_control_t type) } n = control->num; - for (i = 0; i < n; i++) { - gs_free_object(core->memory, control->paths[i], "gs_lib_ctx(path)"); + for (in = out = 0; in < n; in++) { + if (control->entry[in].flags & gs_path_control_flag_is_scratch_file) { + /* Don't purge scratch files! */ + control->entry[out++] = control->entry[in]; + } else + gs_free_object(core->memory, control->entry[in].path, "gs_lib_ctx(path)"); + } + control->num = out; + if (out == 0) { + gs_free_object(core->memory, control->entry, "gs_lib_ctx(paths)"); + control->entry = NULL; + control->max = 0; + } +} + +void +gs_purge_scratch_files(const gs_memory_t *mem) +{ + gs_path_control_set_t *control; + gs_path_control_t type; + int n, in, out; + gs_lib_ctx_core_t *core; + + if (mem == NULL || mem->gs_lib_ctx == NULL || + (core = mem->gs_lib_ctx->core) == NULL) + return; + + for (type = gs_permit_file_reading; type <= gs_permit_file_control; type++) + { + switch(type) { + default: + case gs_permit_file_reading: + control = &core->permit_reading; + break; + case gs_permit_file_writing: + control = &core->permit_writing; + break; + case gs_permit_file_control: + control = &core->permit_control; + break; + } + + n = control->num; + for (in = out = 0; in < n; in++) { + if ((control->entry[in].flags & gs_path_control_flag_is_scratch_file) == 0) { + /* Only purge scratch files! */ + control->entry[out++] = control->entry[in]; + } else { + if (type == gs_permit_file_reading) { + /* Call gp_unlink_impl, as we don't want gp_unlink + * to go looking in the lists we are currently + * manipulating! */ + gp_unlink_impl(core->memory, control->entry[in].path); + } + gs_free_object(core->memory, control->entry[in].path, "gs_lib_ctx(path)"); + } + } + control->num = out; + if (out == 0) { + gs_free_object(core->memory, control->entry, "gs_lib_ctx(paths)"); + control->entry = NULL; + control->max = 0; + } } - gs_free_object(core->memory, control->paths, "gs_lib_ctx(paths)"); - control->paths = NULL; - control->num = 0; - control->max = 0; } void @@ -971,7 +1071,7 @@ gs_remove_fs(const gs_memory_t *mem, return; pfs = &core->fs; - while (pfs) + while (*pfs) { gs_fs_list_t *fs = *pfs; if (fs->fs.open_file == rfs->open_file && @@ -1073,7 +1173,7 @@ gs_lib_ctx_stash_sanitized_arg(gs_lib_ctx_t *ctx, const char *arg) core = ctx->core; if (elide) len = p-arg; - else + else len = strlen(arg); if (core->arg_max == core->argc) { @@ -1179,3 +1279,71 @@ int gs_lib_ctx_get_args(gs_lib_ctx_t *ctx, const char * const **argv) *argv = (const char * const *)core->argv; return core->argc; } + +int gs_lib_ctx_register_callout(gs_memory_t *mem, gs_callout_fn fn, void *arg) +{ + gs_lib_ctx_core_t *core; + gs_callout_list_t *entry; + + if (mem == NULL || mem->gs_lib_ctx == NULL || + mem->gs_lib_ctx->core == NULL || fn == NULL) + return 0; + + core = mem->gs_lib_ctx->core; + entry = (gs_callout_list_t *)gs_alloc_bytes(core->memory, + sizeof(*entry), + "gs_callout_list_t"); + if (entry == NULL) + return_error(gs_error_VMerror); + entry->next = core->callouts; + entry->callout = fn; + entry->handle = arg; + core->callouts = entry; + + return 0; +} + +void gs_lib_ctx_deregister_callout(gs_memory_t *mem, gs_callout_fn fn, void *arg) +{ + gs_lib_ctx_core_t *core; + gs_callout_list_t **entry; + + if (mem == NULL || mem->gs_lib_ctx == NULL || + mem->gs_lib_ctx->core == NULL || fn == NULL) + return; + + core = mem->gs_lib_ctx->core; + entry = &core->callouts; + while (*entry) { + if ((*entry)->callout == fn && (*entry)->handle == arg) { + gs_callout_list_t *next = (*entry)->next; + gs_free_object(core->memory, *entry, "gs_callout_list_t"); + *entry = next; + } else { + entry = &(*entry)->next; + } + } +} + +int gs_lib_ctx_callout(gs_memory_t *mem, const char *dev_name, + int id, int size, void *data) +{ + gs_lib_ctx_core_t *core; + gs_callout_list_t *entry; + + if (mem == NULL || mem->gs_lib_ctx == NULL || mem->gs_lib_ctx->core == NULL) + return -1; + + core = mem->gs_lib_ctx->core; + entry = core->callouts; + while (entry) { + int code = entry->callout(mem->gs_lib_ctx->top_of_system, + entry->handle, dev_name, id, size, data); + if (code >= 0) + return code; + if (code != gs_error_unknownerror) + return code; + entry = entry->next; + } + return -1; +} |