- int std_in[2] = { -1, -1 }; /* pipe to interp stdin */
- int std_out[2]; /* pipe from interp stdout */
- int std_err[2]; /* pipe from interp stderr */
-
-#define NUM_ARGS 100
-#define NUM_GS_ARGS (NUM_ARGS - 20)
-#define NUM_ALPHA_ARGS 10
-
- char *argv[NUM_ARGS], *dir, *gv_env, *gs_path;
- char **gs_args, **alpha_args = NULL;
- char **gv_env_vars = NULL;
- int argc = 0, i;
-
- if(!gs->gs_filename)
- return 0;
-
- stop_interpreter(gs);
-
- /* set up the args... */
- gs_path = g_find_program_in_path ("gs");
- gs_args = g_strsplit (gs_path, " ", NUM_GS_ARGS);
- g_free (gs_path);
- for(i = 0; i < NUM_GS_ARGS && gs_args[i]; i++, argc++) {
- argv[argc] = gs_args[i];
- }
-
- alpha_args = g_strsplit (ALPHA_PARAMS, " ", NUM_ALPHA_ARGS);
- for(i = 0; i < NUM_ALPHA_ARGS && alpha_args[i]; i++, argc++) {
- argv[argc] = alpha_args[i];
- }
-
- argv[argc++] = "-dNOPAUSE";
- argv[argc++] = "-dQUIET";
- argv[argc++] = "-dSAFER";
-
- /* set up the pipes */
- if (gs->send_filename_to_gs) {
- argv[argc++] = PS_DOCUMENT_GET_PS_FILE (gs);
- argv[argc++] = "-c";
- argv[argc++] = "quit";
- } else {
- argv[argc++] = "-";
- }
-
- argv[argc++] = NULL;
-
- if (!gs->reading_from_pipe && !gs->send_filename_to_gs) {
- if (pipe (std_in) == -1) {
- g_critical ("Unable to open pipe to Ghostscript.");
- return -1;
- }
- }
-
- if (pipe (std_out) == -1) {
- close_pipe (std_in);
- return -1;
- }
-
- if (pipe(std_err) == -1) {
- close_pipe (std_in);
- close_pipe (std_out);
- return -1;
- }
-
- gv_env = g_strdup_printf ("GHOSTVIEW=%ld %ld;DISPLAY=%s",
- gdk_x11_drawable_get_xid (gs->pstarget),
- gdk_x11_drawable_get_xid (gs->bpixmap),
- gdk_display_get_name (gdk_drawable_get_display (gs->pstarget)));
-
- gs->interpreter_pid = fork ();
- switch (gs->interpreter_pid) {
- case -1: /* error */
- close_pipe (std_in);
- close_pipe (std_out);
- close_pipe (std_err);
- return -2;
- break;
- case 0: /* child */
- close (std_out[0]);
- dup2 (std_out[1], 1);
- close (std_out[1]);
-
- close (std_err[0]);
- dup2 (std_err[1], 2);
- close (std_err[1]);
-
- if (!gs->reading_from_pipe) {
- if (gs->send_filename_to_gs) {
- int stdinfd;
- /* just in case gs tries to read from stdin */
- stdinfd = open("/dev/null", O_RDONLY);
- if (stdinfd != 0) {
- dup2(stdinfd, 0);
- close(stdinfd);
- }
- } else {
- close (std_in[1]);
- dup2 (std_in[0], 0);
- close (std_in[0]);
- }
- }
-
- gv_env_vars = g_strsplit (gv_env, ";", -1);
- g_free (gv_env);
- for (i = 0; gv_env_vars[i]; i++) {
- putenv (gv_env_vars[i]);
- }
-
- /* change to directory where the input file is. This helps
- * with postscript-files which include other files using
- * a relative path */
- dir = g_path_get_dirname (gs->gs_filename);
- chdir (dir);
- g_free (dir);
-
- execvp (argv[0], argv);
-
- /* Notify error */
- g_critical ("Unable to execute [%s]\n", argv[0]);
- g_strfreev (gs_args);
- g_strfreev (alpha_args);
- g_strfreev (gv_env_vars);
- _exit (1);
- break;
- default: /* parent */
- if (!gs->send_filename_to_gs && !gs->reading_from_pipe) {
- int result;
- close (std_in[0]);
- /* use non-blocking IO for pipe to ghostscript */
- result = fcntl (std_in[1], F_GETFL, 0);
- fcntl (std_in[1], F_SETFL, result | O_NONBLOCK);
- gs->interpreter_input = std_in[1];
- } else {
- gs->interpreter_input = -1;
- }
- close (std_out[1]);
-
- gs->interpreter_output = std_out[0];
- close (std_err[1]);
- gs->interpreter_err = std_err[0];
- gs->interpreter_output_id =
- gdk_input_add (std_out[0], GDK_INPUT_READ, output, gs);
- gs->interpreter_error_id =
- gdk_input_add (std_err[0], GDK_INPUT_READ, output, gs);
-
- g_free (gv_env);
- g_free (gs_args);
- g_free (alpha_args);
- break;
- }
-
- return TRUE;
-}
-
-static void
-stop_interpreter(PSDocument * gs)
-{
- if (gs->interpreter_pid > 0) {
- int status = 0;
- kill (gs->interpreter_pid, SIGTERM);
- while ((wait(&status) == -1) && (errno == EINTR));
- gs->interpreter_pid = -1;
- if (status == 1) {
- gs->gs_status = _("Interpreter failed.");
- }
- }
-
- if (gs->interpreter_input >= 0) {
- close (gs->interpreter_input);
- gs->interpreter_input = -1;
- if (gs->interpreter_input_id != 0) {
- gdk_input_remove(gs->interpreter_input_id);
- gs->interpreter_input_id = 0;
- }
- while (gs->ps_input) {
- struct record_list *ps_old = gs->ps_input;
- gs->ps_input = gs->ps_input->next;
- if (ps_old->close && NULL != ps_old->fp)
- fclose (ps_old->fp);
- g_free (ps_old);
- }
- }
-
- if (gs->interpreter_output >= 0) {
- close (gs->interpreter_output);
- gs->interpreter_output = -1;
- if (gs->interpreter_output_id) {
- gdk_input_remove (gs->interpreter_output_id);
- gs->interpreter_output_id = 0;
- }
- }
-
- if (gs->interpreter_err >= 0) {
- close (gs->interpreter_err);
- gs->interpreter_err = -1;
- if (gs->interpreter_error_id) {
- gdk_input_remove (gs->interpreter_error_id);
- gs->interpreter_error_id = 0;
- }
- }
-
- gs->busy = FALSE;
-}