diff options
author | wlemb <wlemb> | 2004-02-29 00:07:06 +0000 |
---|---|---|
committer | wlemb <wlemb> | 2004-02-29 00:07:06 +0000 |
commit | cf49e6d5f5c047f7c37c7fb09e3a06a5adbb696e (patch) | |
tree | a03f65f4af4967e7217a31a6ea3226f2a51582c2 /src/roff/groff/pipeline.c | |
parent | cf22bfa85b2e85b72bc2de8dc3353f7cec1e3828 (diff) | |
download | groff-cf49e6d5f5c047f7c37c7fb09e3a06a5adbb696e.tar.gz |
* src/include/nonposix.h (write, dup, dup2, close) [_MSC_VER]:
New macros.
* src/roff/groff/pipeline.c: Declare strcasecmp.
(run_pipeline) [_WIN32]: Use function name variants which don't
start with `_'.
Fix stream handling.
* src/include/nonposix.h: Fix declaration of `system_shell_name'.
Declare `spawnvp_wrapper' and macro definitions of spawnvp only
for platforms which use the native Win32 runtime libraries.
(FLUSH_INPUT_PIPE) [_UWIN]: Provide non-empty version.
* src/libs/libgroff/quotearg.c (QUOTE_ARG_MALLOC_ERROR,
QUOTE_ARG_REALLOC_ERROR): Fix string.
* src/preproc/html/pre-html.cpp: Remove declaration of
`spawnvp_wrapper'.
Don't use __MINGW32__.
s/DEBUG_FILE/DEBUG_FILE_DIR/.
(DEBUG_TEXT, DEBUG_NAME, DEBUG_FILE) [DEBUGGING]: New macros.
(OUTPUT_STREAM, PS_OUTPUT_STREAM, REGION_OUTPUT_STREAM): New macros.
(char_buffer::run_output_filter) [MAY_FORK_CHILD_PROCESS]: Fix
calls to `set_redirection' and `WAIT'.
[MAY_SPAWN_ASYNCHRONOUS_CHILD]: Remove unused variable `i' and `j'.
Fix calls to `set_redirection' and `save_and_redirect'.
(char_buffer::do_html, char_buffer::do_image) [DEBUGGING]: Fix calls
to `set_redirection' and `save_and_redirect'.
(usage): Fix message.
(makeTempFiles, main): Use `DEBUG_FILE'.
Diffstat (limited to 'src/roff/groff/pipeline.c')
-rw-r--r-- | src/roff/groff/pipeline.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/src/roff/groff/pipeline.c b/src/roff/groff/pipeline.c index 2d7ba362..b51ed50e 100644 --- a/src/roff/groff/pipeline.c +++ b/src/roff/groff/pipeline.c @@ -102,6 +102,8 @@ static const char *sh = "sh"; static const char *cmd = "cmd"; static const char *command = "command"; +extern int strcasecmp(const char *, const char *); + char *sbasename(const char *path) { char *base; @@ -189,13 +191,22 @@ int is_system_shell(const char *prog) #ifdef _WIN32 -/* Windows 32 doesn't have fork() */ +/* + Windows 32 doesn't have fork(), so we need to start asynchronous child + processes with spawn() rather than exec(). If there is more than one + command, i.e., a pipeline, the parent must set up each child's I/O + redirection prior to the spawn. The original stdout must be restored + before spawning the last process in the pipeline, and the original + stdin must be restored in the parent after spawning the last process + and before waiting for any of the children. +*/ int run_pipeline(int ncommands, char ***commands, int no_pipe) { - int save_stdin, save_stdout; int i; - int last_input = 0; + int last_input; + int save_stdin; + int save_stdout; int ret = 0; char err_str[BUFSIZ]; PID_T pids[MAX_COMMANDS]; @@ -209,18 +220,22 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) if (ncommands > 1 && !no_pipe) { /* last command doesn't need a new pipe */ if (i < ncommands - 1) { - if (_pipe(pdes, BUFSIZ, _O_BINARY | _O_NOINHERIT) < 0) { + if (pipe(pdes) < 0) { sprintf(err_str, "%s: pipe", commands[i][0]); sys_fatal(err_str); } } /* 1st command; writer */ if (i == 0) { + /* save stdin */ + if ((save_stdin = dup(STDIN_FILENO)) < 0) + sys_fatal("dup stdin"); /* save stdout */ - if ((save_stdout = _dup(STDOUT_FILENO)) < 0) + if ((save_stdout = dup(STDOUT_FILENO)) < 0) sys_fatal("dup stdout"); + /* connect stdout to write end of pipe */ - if (_dup2(pdes[1], STDOUT_FILENO) < 0) { + if (dup2(pdes[1], STDOUT_FILENO) < 0) { sprintf(err_str, "%s: dup2(stdout)", commands[i][0]); sys_fatal(err_str); } @@ -228,17 +243,26 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) sprintf(err_str, "%s: close(pipe[WRITE])", commands[i][0]); sys_fatal(err_str); } + /* + Save the read end of the pipe so that it can be connected to + stdin of the next program in the pipeline during the next + pass through the loop. + */ last_input = pdes[0]; } /* reader and writer */ else if (i < ncommands - 1) { /* connect stdin to read end of last pipe */ - if (_dup2(last_input, STDIN_FILENO) < 0) { + if (dup2(last_input, STDIN_FILENO) < 0) { sprintf(err_str, " %s: dup2(stdin)", commands[i][0]); sys_fatal(err_str); } + if (close(last_input) < 0) { + sprintf(err_str, "%s: close(last_input)", commands[i][0]); + sys_fatal(err_str); + } /* connect stdout to write end of new pipe */ - if (_dup2(pdes[1], STDOUT_FILENO) < 0) { + if (dup2(pdes[1], STDOUT_FILENO) < 0) { sprintf(err_str, "%s: dup2(stdout)", commands[i][0]); sys_fatal(err_str); } @@ -251,7 +275,7 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) /* last command; reader */ else { /* connect stdin to read end of last pipe */ - if (_dup2(last_input, STDIN_FILENO) < 0) { + if (dup2(last_input, STDIN_FILENO) < 0) { sprintf(err_str, "%s: dup2(stdin)", commands[i][0]); sys_fatal(err_str); } @@ -260,7 +284,7 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) sys_fatal(err_str); } /* restore original stdout */ - if (_dup2(save_stdout, STDOUT_FILENO) < 0) { + if (dup2(save_stdout, STDOUT_FILENO) < 0) { sprintf(err_str, "%s: dup2(save_stdout))", commands[i][0]); sys_fatal(err_str); } @@ -271,7 +295,7 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) } } } - if ((pid = _spawnvp(_P_NOWAIT, commands[i][0], commands[i])) < 0) { + if ((pid = spawnvp(_P_NOWAIT, commands[i][0], commands[i])) < 0) { error("couldn't exec %1: %2", commands[i][0], strerror(errno), (char *)0); fflush(stderr); /* just in case error() doesn't */ @@ -279,13 +303,27 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe) } pids[i] = pid; } + + if (ncommands > 1 && !no_pipe) { + /* restore original stdin if it was redirected */ + if (dup2(save_stdin, STDIN_FILENO) < 0) { + sprintf(err_str, "dup2(save_stdin))"); + sys_fatal(err_str); + } + /* close stdin copy */ + if (close(save_stdin) < 0) { + sprintf(err_str, "close(save_stdin)"); + sys_fatal(err_str); + } + } + for (i = 0; i < ncommands; i++) { int status; - int pid; + PID_T pid; pid = pids[i]; if ((pid = WAIT(&status, pid, _WAIT_CHILD)) < 0) { - sprintf(err_str, "%s: cwait", commands[i][0]); + sprintf(err_str, "%s: wait", commands[i][0]); sys_fatal(err_str); } else if (status != 0) |