Paolo Bonzini wrote: > On 07/22/2009 12:27 AM, Paolo Bonzini wrote: >>> Your proposal is more general, but still assumes that >>> - the control structure of the reader is simple. >> >> This is what Bison requires. Actually Bison's reader is complex, but >> the output is fed to a Flex scanner, which takes care of the complexity. > > Here is some code with an example, the Win32 part I'll do in the next > few days. If I had to choose one of the three cases you mentioned, I'd > include this one in gnulib. It shouldn't be too bad to adapt msgfilter > to this API; for Bison it is overkill. > > Paolo
Hi Guys, I was going to chime in with my patch for chaining filters. The interfaces seemed easy enough: /* Open a pipe for input from a child process. * The child's stdin comes from the file descriptor in fd[0]. * This descriptor is closed for the calling process. * * read system write read * parent <- out_fd[0] <- STDOUT_FILENO <- child <- in_fd[0] * */ extern pid_t create_pipe_fdin (const char *progname, const char *prog_path, char **prog_argv, bool null_stderr, bool slave_process, bool exit_on_error, int fd[1]); /* Start or continue a chain of filter processes. Arguments are as above, except that "prev_filter" must be the returned result of a previous call to filter_create() or chain_filter_create(). */ extern struct filter * chain_filter_create (const char *progname, const char *prog_path, const char **prog_argv, bool null_stderr, bool exit_on_error, char *read_buf, size_t read_bufsize, done_read_fn done_read, void *private_data, struct filter * prev_filter); but when I got to the underlying pipe code, I found it too obtuse to disentangle easliy: if (slave_process) { sigprocmask (SIG_SETMASK, NULL, &blocked_signals); block_fatal_signals (); } actions_allocated = false; attrs_allocated = false; if ((err = posix_spawn_file_actions_init (&actions)) != 0 || (actions_allocated = true, (pipe_stdin && (err = posix_spawn_file_actions_adddup2 (&actions, ofd[0], STDIN_FILENO)) != 0) || (pipe_stdout && (err = posix_spawn_file_actions_adddup2 (&actions, ifd[1], STDOUT_FILENO)) != 0) || (pipe_stdin && (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0) || (pipe_stdout && (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0) || (pipe_stdin && (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0) || (pipe_stdout && (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0) || (null_stderr && (err = posix_spawn_file_actions_addopen (&actions, STDERR_FILENO, "/dev/null", O_RDWR, 0)) != 0) || (!pipe_stdin && prog_stdin != NULL && (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, prog_stdin, O_RDONLY, 0)) != 0) || (!pipe_stdout && prog_stdout != NULL && (err = posix_spawn_file_actions_addopen (&actions, STDOUT_FILENO, prog_stdout, O_WRONLY, 0)) != 0) || (slave_process && ((err = posix_spawnattr_init (&attrs)) != 0 || (attrs_allocated = true, (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0 || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0))) || (err = posix_spawnp (&child, prog_path, &actions, attrs_allocated ? &attrs : NULL, prog_argv, environ)) != 0)) {