예제 #1
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);
}
예제 #2
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);
}
예제 #3
0
int get_new_command(char *mes)
{
    int		redir = 0, i, res;
    char		*name;
    term_def_t	*term;

    if (debug_flag) printf("get_new_command:\n");
    term = get_next_term();
    if ((term == NULL) || (term->term_type != CMD_TERM))
        cmd_parser(mes, 0, 1, &redir);
    else {
        unget_term();
        redir = check_cmd_for_redirect();
    };
    if (redir != 0) {
        for (i = 0; i < term_count; i++) {
            if (terms[i].term_type == CMD_REDIR_TERM)
                break;
        };
        if (i >= term_count - 1) {
            printf("Syntax error:\n%s\n", cmd_line);
            go_to_dialog();
            return(3);
        };
        if (terms[i + 1].term_type != ITEM_TERM) {
            printf("Syntax error:\n%s\n", cmd_line);
            go_to_dialog();
            return(3);
        };
        name = terms[i + 1].term;
        res = set_redirection(name, redir);
        if (res != 0) {
            printf("Command failed:\n%s\n", cmd_line);
            go_to_dialog();
            return(3);
        };
        res = run_command();
        remove_reditection();
        return(res);
    };
    res = run_command();
    return(res);
}
예제 #4
0
static int save_and_redirect(int was, int willbe)
{
  if (was == willbe)
    // No redirection specified so don't do anything but silently bailing out.
    return (was);

  // Proceeding with redirection so first save and verify our duplicate
  // handle for `was'.
  int saved = dup(was);
  if (saved < 0) {
    fprintf(stderr, "unable to get duplicate handle for %d\n", was);
    sys_fatal("dup");
  }

  // Duplicate handle safely established so complete redirection.
  set_redirection(was, willbe);

  // Finally return the saved duplicate descriptor for the
  // original `was' stream.
  return saved;
}
예제 #5
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;
}