summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwlemb <wlemb>2004-02-21 06:46:18 +0000
committerwlemb <wlemb>2004-02-21 06:46:18 +0000
commitd63903bb009a281dc1379733417c5cc0ce658446 (patch)
tree4e762fad611d64b38b385f6608d2a35e5920cdfa
parent070480fa13842074c15eaad937bf19e0da328b22 (diff)
downloadgroff-d63903bb009a281dc1379733417c5cc0ce658446.tar.gz
* src/roff/groff/pipeline.c (cmd) [__MSDOS__ || ...]: New global
variable. (sbasename) [__MSDOS__ || ...]: New function. (system_shell_name) [__MSDOS__ || ...]: Use a different, more generic algorithm. (system_shell_dash_c, is_system_shell) [__MSDOS__ || ...]: Updated. (run_pipeline) [_WIN32]: Use _XXX variants for some macros instead of XXX. Use STDOUT_FILENO instead of hardcoded file handle. (signal_catcher) [__MSDOS__]: Moved to non-_WIN32 section.
-rw-r--r--ChangeLog13
-rw-r--r--src/roff/groff/pipeline.c146
2 files changed, 102 insertions, 57 deletions
diff --git a/ChangeLog b/ChangeLog
index 1dae4d55..645d7e86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2004-02-21 Jeff Conrad <jeff_conrad@msn.com>
+
+ * src/roff/groff/pipeline.c (cmd) [__MSDOS__ || ...]: New global
+ variable.
+ (sbasename) [__MSDOS__ || ...]: New function.
+ (system_shell_name) [__MSDOS__ || ...]: Use a different, more
+ generic algorithm.
+ (system_shell_dash_c, is_system_shell) [__MSDOS__ || ...]: Updated.
+ (run_pipeline) [_WIN32]: Use _XXX variants for some macros instead
+ of XXX.
+ Use STDOUT_FILENO instead of hardcoded file handle.
+ (signal_catcher) [__MSDOS__]: Moved to non-_WIN32 section.
+
2004-02-19 Werner LEMBERG <wl@gnu.org>
* src/roff/troff/div.cpp: Include nonposix.h after troff.h to
diff --git a/src/roff/groff/pipeline.c b/src/roff/groff/pipeline.c
index c9e37715..2d7ba362 100644
--- a/src/roff/groff/pipeline.c
+++ b/src/roff/groff/pipeline.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003
+/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -85,10 +85,6 @@ static void sys_fatal(const char *);
static const char *xstrsignal(int);
const char *i_to_a(int); // from libgroff
-/* MSVC can support asynchronous processes, but it's unlikely to have
- fork(). So, until someone writes an emulation, let them at least
- have a workable groff by using the good-ole DOS pipe simulation
- via temporary files... */
#if defined(__MSDOS__) \
|| (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)) \
@@ -102,66 +98,93 @@ const char *i_to_a(int); // from libgroff
#include "nonposix.h"
-/* A signal handler that just records that a signal has happened. */
-static int child_interrupted;
+static const char *sh = "sh";
+static const char *cmd = "cmd";
+static const char *command = "command";
-static RETSIGTYPE signal_catcher(int signo)
+char *sbasename(const char *path)
{
- child_interrupted++;
-}
+ char *base;
+ const char *p1, *p2;
+
+ p1 = path;
+ if ((p2 = strrchr(p1, '\\'))
+ || (p2 = strrchr(p1, '/'))
+ || (p2 = strrchr(p1, ':')))
+ p1 = p2 + 1;
+ if ((p2 = strrchr(p1, '.'))
+ && ((strcasecmp(p2, ".exe") == 0)
+ || (strcasecmp(p2, ".com") == 0)))
+ ;
+ else
+ p2 = p1 + strlen(p1);
-static const char *sh = "sh";
-static const char *command = "command";
+ base = malloc((size_t)(p2 - p1));
+ strncpy(base, p1, p2 - p1);
+ *(base + (p2 - p1)) = '\0';
+
+ return(base);
+}
-const char *system_shell_name(void)
+/* Get the name of the system shell */
+char *system_shell_name(void)
{
- static const char *shell_name;
-
- /* We want them to be able to use a Unixy shell if they have it
- installed. Let spawnlp try to find it, but if it fails, default
- to COMMAND.COM. */
- if (shell_name == NULL) {
- int sh_found = spawnlp(P_WAIT, sh, sh, "-c", ":", NULL) == 0;
-
- if (sh_found)
- shell_name = sh;
- else
- shell_name = command;
- }
- return shell_name;
+ const char *shell_name;
+
+ /*
+ Use a Unixy shell if it's installed. Use SHELL if set; otherwise,
+ let spawnlp try to find sh; if that fails, use COMSPEC if set; if
+ not, try cmd.exe; if that fails, default to command.com.
+ */
+
+ if ((shell_name = getenv("SHELL")) != NULL)
+ ;
+ else if (spawnlp(_P_WAIT, sh, sh, "-c", ":", NULL) == 0)
+ shell_name = sh;
+ else if ((shell_name = getenv("COMSPEC")) != NULL)
+ ;
+ else if (spawnlp(_P_WAIT, cmd, cmd, "/c", ";", NULL) == 0)
+ shell_name = cmd;
+ else
+ shell_name = command;
+
+ return sbasename(shell_name);
}
const char *system_shell_dash_c(void)
{
- if (strcmp(system_shell_name(), sh) == 0)
- return "-c";
+ char *shell_name;
+ const char *dash_c;
+
+ shell_name = system_shell_name();
+
+ /* Assume that if the shell name ends in "sh", it's Unixy */
+ if (strcasecmp(shell_name + strlen(shell_name) - strlen("sh"), "sh") == 0)
+ dash_c = "-c";
else
- return "/c";
+ dash_c = "/c";
+
+ free(shell_name);
+ return dash_c;
}
-int is_system_shell(const char *shell)
+int is_system_shell(const char *prog)
{
- size_t shlen;
- size_t ibase = 0, idot, i;
+ int result;
+ char *this_prog, *system_shell;
- if (!shell) /* paranoia */
+ if (!prog) /* paranoia */
return 0;
- idot = shlen = strlen(shell);
-
- for (i = 0; i < shlen; i++) {
- if (shell[i] == '.')
- idot = i;
- else if (shell[i] == '/' || shell[i] == '\\' || shell[i] == ':') {
- ibase = i + 1;
- idot = shlen;
- }
- }
- /* "sh" and "sh.exe" should compare equal. */
- return (strncasecmp(shell + ibase, system_shell_name(), idot - ibase) == 0
- && (idot == shlen
- || strcasecmp(shell + idot, ".exe") == 0
- || strcasecmp(shell + idot, ".com") == 0));
+ this_prog = sbasename(prog);
+ system_shell = system_shell_name();
+
+ result = strcasecmp(this_prog, system_shell) == 0;
+
+ free(this_prog);
+ free(system_shell);
+
+ return result;
}
#ifdef _WIN32
@@ -186,7 +209,7 @@ 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, BUFSIZ, _O_BINARY | _O_NOINHERIT) < 0) {
sprintf(err_str, "%s: pipe", commands[i][0]);
sys_fatal(err_str);
}
@@ -194,10 +217,10 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe)
/* 1st command; writer */
if (i == 0) {
/* save stdout */
- if ((save_stdout = _dup(1)) < 0)
+ if ((save_stdout = _dup(STDOUT_FILENO)) < 0)
sys_fatal("dup stdout");
/* connect stdout to write end of pipe */
- if (_dup2(pdes[1], 1) < 0) {
+ if (_dup2(pdes[1], STDOUT_FILENO) < 0) {
sprintf(err_str, "%s: dup2(stdout)", commands[i][0]);
sys_fatal(err_str);
}
@@ -210,12 +233,12 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe)
/* reader and writer */
else if (i < ncommands - 1) {
/* connect stdin to read end of last pipe */
- if (_dup2(last_input, 0) < 0) {
+ if (_dup2(last_input, STDIN_FILENO) < 0) {
sprintf(err_str, " %s: dup2(stdin)", commands[i][0]);
sys_fatal(err_str);
}
/* connect stdout to write end of new pipe */
- if (_dup2(pdes[1], 1) < 0) {
+ if (_dup2(pdes[1], STDOUT_FILENO) < 0) {
sprintf(err_str, "%s: dup2(stdout)", commands[i][0]);
sys_fatal(err_str);
}
@@ -228,7 +251,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, 0) < 0) {
+ if (_dup2(last_input, STDIN_FILENO) < 0) {
sprintf(err_str, "%s: dup2(stdin)", commands[i][0]);
sys_fatal(err_str);
}
@@ -237,7 +260,7 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe)
sys_fatal(err_str);
}
/* restore original stdout */
- if (_dup2(save_stdout, 1) < 0) {
+ if (_dup2(save_stdout, STDOUT_FILENO) < 0) {
sprintf(err_str, "%s: dup2(save_stdout))", commands[i][0]);
sys_fatal(err_str);
}
@@ -274,10 +297,19 @@ int run_pipeline(int ncommands, char ***commands, int no_pipe)
#else /* not _WIN32 */
/* MSDOS doesn't have `fork', so we need to simulate the pipe by running
- the programs in sequence with standard streams redirected fot and
+ the programs in sequence with standard streams redirected to and
from temporary files.
*/
+
+/* A signal handler that just records that a signal has happened. */
+static int child_interrupted;
+
+static RETSIGTYPE signal_catcher(int signo)
+{
+ child_interrupted++;
+}
+
int run_pipeline(int ncommands, char ***commands, int no_pipe)
{
int save_stdin = dup(0);