Esempio n. 1
0
int char_buffer::do_image(int argc, char *argv[])
{
  string s;

  alterDeviceTo(argc, argv, 1);
  argv += troff_arg;		// skip all arguments up to troff/groff
  argc -= troff_arg;
  argv = addRegDef(argc, argv, "-rps4html=1");
  argc++;

  s = "-dwww-image-template=";
  s += macroset_template;
  s += '\0';
  argv = addRegDef(argc, argv, s.contents());
  argc++;

  // override local settings and produce a page size letter postscript file
  argv = addRegDef(argc, argv, "-P-pletter");
  argc++;

#if defined(DEBUGGING)
# define IMAGE_DEBUG_STREAM  OUTPUT_STREAM(troffFileName)
  // slight security risk so only enabled if compiled with defined(DEBUGGING)
  if (debug) {
    int saved_stdout = save_and_redirect(STDOUT_FILENO, IMAGE_DEBUG_STREAM);
    emit_troff_output(DEVICE_FORMAT(IMAGE_OUTPUT_FILTER));
    set_redirection(STDOUT_FILENO, saved_stdout);
  }
#endif

  return run_output_filter(IMAGE_OUTPUT_FILTER, argc, argv);
}
Esempio n. 2
0
int char_buffer::do_html(int argc, char *argv[])
{
  string s;

  alterDeviceTo(argc, argv, 0);
  argv += troff_arg;		// skip all arguments up to groff
  argc -= troff_arg;
  argv = addZ(argc, argv);
  argc++;

  s = "-dwww-image-template=";
  s += macroset_template;	// do not combine these statements,
				// otherwise they will not work
  s += '\0';                	// the trailing `\0' is ignored
  argv = addRegDef(argc, argv, s.contents());
  argc++;

#if defined(DEBUGGING)
# define HTML_DEBUG_STREAM  OUTPUT_STREAM(htmlFileName)
  // slight security risk so only enabled if compiled with defined(DEBUGGING)
  if (debug) {
    int saved_stdout = save_and_redirect(STDOUT_FILENO, HTML_DEBUG_STREAM);
    emit_troff_output(DEVICE_FORMAT(HTML_OUTPUT_FILTER));
    set_redirection(STDOUT_FILENO, saved_stdout);
  }
#endif

  return run_output_filter(HTML_OUTPUT_FILTER, argc, argv);
}
Esempio n. 3
0
int char_buffer::run_output_filter(int filter, int argc, char **argv)
{
  int pipedes[2];
  PID_T child_pid;
  int status;

  print_args(argc, argv);
  if (pipe(pipedes) < 0)
    sys_fatal("pipe");

#if MAY_FORK_CHILD_PROCESS
  // This is the UNIX process model.  To invoke our post-processor,
  // we must `fork' the current process.

  if ((child_pid = fork()) < 0)
    sys_fatal("fork");

  else if (child_pid == 0) {
    // This is the child process fork.  We redirect its `stdin' stream
    // to read data emerging from our pipe.  There is no point in saving,
    // since we won't be able to restore later!

    set_redirection(STDIN_FILENO, pipedes[0]);

    // The parent process will be writing this data, so we should release
    // the child's writeable handle on the pipe, since we have no use for it.

    if (close(pipedes[1]) < 0)
      sys_fatal("close");

    // The IMAGE_OUTPUT_FILTER needs special output redirection...

    if (filter == IMAGE_OUTPUT_FILTER) {
      // with BOTH `stdout' AND `stderr' diverted to files.

      set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
      set_redirection(STDERR_FILENO, REGION_OUTPUT_STREAM);
    }

    // Now we are ready to launch the output filter.

    execvp(argv[0], argv);

    // If we get to here then the `exec...' request for the output filter
    // failed.  Diagnose it and bail out.

    error("couldn't exec %1: %2", argv[0], strerror(errno), ((char *)0));
    fflush(stderr);	// just in case error() didn't
    exit(1);
  }

  else {
    // This is the parent process fork.  We will be writing data to the
    // filter pipeline, and the child will be reading it.  We have no further
    // use for our read handle on the pipe, and should close it.

    if (close(pipedes[0]) < 0)
      sys_fatal("close");

    // Now we redirect the `stdout' stream to the inlet end of the pipe,
    // and push out the appropiately formatted data to the filter.

    pipedes[1] = save_and_redirect(STDOUT_FILENO, pipedes[1]);
    emit_troff_output(DEVICE_FORMAT(filter));

    // After emitting all the data we close our connection to the inlet
    // end of the pipe so the child process will detect end of data.

    set_redirection(STDOUT_FILENO, pipedes[1]);

    // Finally, we must wait for the child process to complete.

    if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
      sys_fatal("wait");
  }

#elif MAY_SPAWN_ASYNCHRONOUS_CHILD

  // We do not have `fork', (or we prefer not to use it),
  // but asynchronous processes are allowed, passing data through pipes.
  // This should be ok for most Win32 systems and is preferred to `fork'
  // for starting child processes under Cygwin.

  // Before we start the post-processor we bind its inherited `stdin'
  // stream to the readable end of our pipe, saving our own `stdin' stream
  // in `pipedes[0]'.

  pipedes[0] = save_and_redirect(STDIN_FILENO, pipedes[0]);

  // for the Win32 model,
  // we need special provision for saving BOTH `stdout' and `stderr'.

  int saved_stdout = dup(STDOUT_FILENO);
  int saved_stderr = STDERR_FILENO;

  // The IMAGE_OUTPUT_FILTER needs special output redirection...

  if (filter == IMAGE_OUTPUT_FILTER) {
    // with BOTH `stdout' AND `stderr' diverted to files while saving a
    // duplicate handle for `stderr'.

    set_redirection(STDOUT_FILENO, PS_OUTPUT_STREAM);
    saved_stderr = save_and_redirect(STDERR_FILENO, REGION_OUTPUT_STREAM);
  }

  // We then use an asynchronous spawn request to start the post-processor.

  if ((child_pid = spawnvp(_P_NOWAIT, argv[0], argv)) < 0) {
    // Should the spawn request fail we issue a diagnostic and bail out.

    error("cannot spawn %1: %2", argv[0], strerror(errno), ((char *)0));
    exit(1);
  }

  // Once the post-processor has been started we revert our `stdin'
  // to its original saved source, which also closes the readable handle
  // for the pipe.

  set_redirection(STDIN_FILENO, pipedes[0]);

  // if we redirected `stderr', for use by the image post-processor,
  // then we also need to reinstate its original assignment.

  if (filter == IMAGE_OUTPUT_FILTER)
    set_redirection(STDERR_FILENO, saved_stderr);

  // Now we redirect the `stdout' stream to the inlet end of the pipe,
  // and push out the appropiately formatted data to the filter.

  set_redirection(STDOUT_FILENO, pipedes[1]);
  emit_troff_output(DEVICE_FORMAT(filter));

  // After emitting all the data we close our connection to the inlet
  // end of the pipe so the child process will detect end of data.

  set_redirection(STDOUT_FILENO, saved_stdout);

  // And finally, we must wait for the child process to complete.

  if (WAIT(&status, child_pid, _WAIT_CHILD) != child_pid)
    sys_fatal("wait");

#else /* can't do asynchronous pipes! */

  // TODO: code to support an MS-DOS style process model
  //        should go here

#endif /* MAY_FORK_CHILD_PROCESS or MAY_SPAWN_ASYNCHRONOUS_CHILD */

  return 0;
}