Mail Archives: djgpp-workers/1996/09/16/04:53:18
The changes below take care of a few minor problems:
- the test for unixy or dos shell is now done in one place, and
the functions which do that are exported, so these tests are consistent;
- invoking a v1.x program is always done through !proxy, to
prevent go32 from printing its copyright line;
- a couple of executable extensions were added;
- if the first character if the command line (ater removing the
redirection constructs) is a left paren `(', the shell is called
immediately (for the sake of those who use this feature of [4N]DOS);
- the semi-colon `;' escaping is handled better.
Don't be scared by the size of the diff: most of it is whitespace changes
(because a block of code was removed, causeing a change in the
indentation).
------------------------------------------------------------------------
*** src/libc/ansi/stdlib/system.c~8 Sat Sep 7 16:54:38 1996
--- src/libc/ansi/stdlib/system.c Sun Sep 15 16:38:42 1996
*************** _shell_command (const char *prog, const
*** 85,178 ****
the command interpreter and let the user type ``exit''. */
return _dos_exec (shell, "", environ);
}
! else
{
! char *p, *shellbase = shell;
!
! for (p = shell; *p; p++)
! if (*p == ':' || *p == '/' || *p == '\\')
! shellbase = p + 1;
! if (!stricmp (shellbase, "command.com")
! || !stricmp (shellbase, "4dos.com")
! || !stricmp (shellbase, "ndos.com"))
{
! char *cmd_tail = (char *)alloca (3 + strlen (prog) + 1
! + strlen (cmdline) + 1);
! const char *s = prog;
! char *d = cmd_tail + 3;
!
! strcpy (cmd_tail, "/c ");
! while ((*d = *s++) != 0)
! {
! if (*d == '/')
! *d = '\\';
! d++;
! }
! if (*cmdline)
! {
! if (*prog)
! *d++ = ' ';
! strcpy (d, cmdline);
! }
! /* [4N]DOS.COM can support upto 255 chars per command line.
! They lose that feature here, because there's no simple
! way to pass long command lines to DOS function 4Bh (Exec)
! which `_dos_exec' summons. */
! if (strlen (cmd_tail) > 126)
! {
! errno = E2BIG;
! return emiterror ("Command line too long.", 0);
! }
! else
! return _dos_exec (shell, cmd_tail, environ);
}
else
! {
! /* Assume this is a `sh' work-alike. What's below should
! work with `ms_sh'; others should be fine if they support
! the response file method (but I didn't test anything
! except `ms_sh'). */
! FILE *respf;
! int e = errno;
! char *atfile = (char *) alloca (L_tmpnam);
! char *cmd_tail = (char *)alloca (L_tmpnam + 5);
! errno = 0;
! respf = fopen (tmpnam (atfile), "wb");
! /* Note that the command line is written to the response file
! as a single (possibly long) line. The docs of `ms_sh' tells
! that when invoking other programs, it writes each argument
! on a separate line, but the shell itself doesn't seem to
! care when it gets everything as a single line. */
! if (respf)
! {
! int retval;
! errno = e;
! if (*prog)
! {
! fputs (prog, respf);
! fputc (' ', respf);
! }
! fputs (cmdline, respf);
! fputc ('\n', respf);
! fclose (respf);
! strcpy (cmd_tail, "-c @");
! strcat (cmd_tail, atfile);
! retval = _dos_exec (shell, cmd_tail, environ);
! remove (atfile);
! return retval;
}
! else
! return emiterror ("Cannot open response file for SH", errno);
}
}
}
--- 85,167 ----
the command interpreter and let the user type ``exit''. */
return _dos_exec (shell, "", environ);
}
! else if (_is_dos_shell (shell))
{
! char *cmd_tail = (char *)alloca (3 + strlen (prog) + 1
! + strlen (cmdline) + 1);
! const char *s = prog;
! char *d = cmd_tail + 3;
! strcpy (cmd_tail, "/c ");
! while ((*d = *s++) != 0)
{
! if (*d == '/')
! *d = '\\';
! d++;
! }
! if (*cmdline)
! {
! if (*prog)
! *d++ = ' ';
! strcpy (d, cmdline);
! }
! /* [4N]DOS.COM can support upto 255 chars per command line.
! They lose that feature here, because there's no simple
! way to pass long command lines to DOS function 4Bh (Exec)
! which `_dos_exec' summons. */
! if (strlen (cmd_tail) > 126)
! {
! errno = E2BIG;
! return emiterror ("Command line too long.", 0);
}
else
! return _dos_exec (shell, cmd_tail, environ);
! }
! else
! {
! /* Assume this is a `sh' work-alike. What's below should
! work with `ms_sh'; others should be fine if they support
! the response file method (but I didn't test anything
! except `ms_sh'). */
! FILE *respf;
! int e = errno;
! char *atfile = (char *) alloca (L_tmpnam);
! char *cmd_tail = (char *)alloca (L_tmpnam + 5);
! errno = 0;
! respf = fopen (tmpnam (atfile), "wb");
! /* Note that the command line is written to the response file
! as a single (possibly long) line. The docs of `ms_sh' tells
! that when invoking other programs, it writes each argument
! on a separate line, but the shell itself doesn't seem to
! care when it gets everything as a single line. */
! if (respf)
! {
! int retval;
! errno = e;
! if (*prog)
! {
! fputs (prog, respf);
! fputc (' ', respf);
}
! fputs (cmdline, respf);
! fputc ('\n', respf);
! fclose (respf);
! strcpy (cmd_tail, "-c @");
! strcat (cmd_tail, atfile);
! retval = _dos_exec (shell, cmd_tail, environ);
! remove (atfile);
! return retval;
}
+ else
+ return emiterror ("Cannot open response file for SH", errno);
}
}
*************** __unquote (char *to, const char *beg, co
*** 385,391 ****
s++;
break;
case '\\':
! if (s[1] == '"' || s[1] == '\'')
s++;
/* Fall-through. */
default:
--- 374,382 ----
s++;
break;
case '\\':
! if (s[1] == '"' || s[1] == '\''
! || (s[1] == ';'
! && (__system_flags & __system_allow_multiple_cmds)))
s++;
/* Fall-through. */
default:
*************** get_sym (char *s, char **beg, char **end
*** 456,462 ****
--*end;
return EOL;
case '\\':
! if (s[1] == '"' || s[1] == '\'')
s++;
in_a_word = 1;
break;
--- 447,454 ----
--*end;
return EOL;
case '\\':
! if (s[1] == '"' || s[1] == '\''
! || (s[1] == ';' && (sys_flags & __system_allow_multiple_cmds)))
s++;
in_a_word = 1;
break;
*************** system (const char *cmdline)
*** 579,584 ****
--- 571,580 ----
if (needcmd)
{
__unquote (prog, t, u); /* unquote and copy to prog */
+ /* We can't grok commands in parentheses, so assume they
+ use a shell that knows about these, like 4DOS or `sh'. */
+ if (prog[0] == '(')
+ return _shell_command ("", cmdline);
strcpy (s, u); /* remove program name from cmdline */
needcmd = 0;
}
*** src/libc/dos/process/dosexec.c~1 Wed Sep 4 18:54:28 1996
--- src/libc/dos/process/dosexec.c Sun Sep 15 11:53:34 1996
*************** direct_exec_tail(const char *program, co
*** 188,194 ****
} else
progname = program;
! if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 32))
return -1;
program_la = talloc(proglen);
arg_la = talloc(strlen(args)+3);
--- 188,194 ----
} else
progname = program;
! if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 48))
return -1;
program_la = talloc(proglen);
arg_la = talloc(strlen(args)+3);
*************** direct_exec_tail(const char *program, co
*** 252,259 ****
parm_la -= tbuf_beg;
program_la -= tbuf_beg;
#endif
- if (!check_talloc(0))
- return -1;
/* The environment. Replace the !proxy variable, if there is
one (for nested programs) if we are called from `system',
--- 252,257 ----
*************** static const char *unix_shells[] = {
*** 388,412 ****
0
};
static int direct_exec(const char *program, char **argv, char **envp)
{
int i, arglen;
char *args, *argp;
int need_quote = !__dosexec_in_system;
int unescape_quote = __dosexec_in_system;
- const char *ptail = program;
-
- {
- const char *p = ptail;
-
- while (*p)
- {
- if (*p == '/' || *p == ':' || *p == '\\')
- ptail = p + 1;
- p++;
- }
- }
-
/* PROGRAM can be a shell which expects a single argument
(beyond the /c or -c switch) that is the entire command
--- 386,429 ----
0
};
+ static int
+ list_member (const char *program, const char *program_list[])
+ {
+ const char *p = program, *ptail = program;
+ int i;
+
+ while (*p)
+ {
+ if (*p == '/' || *p == ':' || *p == '\\')
+ ptail = p + 1;
+ p++;
+ }
+
+ for (i = 0; program_list[i]; i++)
+ if (!stricmp (ptail, program_list[i]))
+ return 1;
+
+ return 0;
+ }
+
+ int
+ _is_unixy_shell (const char *shellpath)
+ {
+ return list_member (shellpath, unix_shells);
+ }
+
+ int
+ _is_dos_shell (const char *shellpath)
+ {
+ return list_member (shellpath, shell_brokets);
+ }
+
static int direct_exec(const char *program, char **argv, char **envp)
{
int i, arglen;
char *args, *argp;
int need_quote = !__dosexec_in_system;
int unescape_quote = __dosexec_in_system;
/* PROGRAM can be a shell which expects a single argument
(beyond the /c or -c switch) that is the entire command
*************** static int direct_exec(const char *progr
*** 416,444 ****
The hard problem is to know when PROGRAM names a shell
that doesn't like its command line quoted... */
! if (need_quote && argv[1] && !strcmp (argv[1], "/c") && argv[2] && !argv[3])
! {
! for (i = 0; shell_brokets[i]; i++)
! {
! if (!stricmp (ptail, shell_brokets[i]))
! {
! need_quote = 0;
! break;
! }
! }
! }
! if (unescape_quote)
! {
! for (i = 0; unix_shells[i]; i++)
! {
! if (!stricmp (ptail, unix_shells[i]))
! {
! unescape_quote = 0;
! break;
! }
! }
! }
arglen = 0;
for (i=1; argv[i]; i++)
--- 433,446 ----
The hard problem is to know when PROGRAM names a shell
that doesn't like its command line quoted... */
! if (need_quote
! && argv[1] && !strcmp (argv[1], "/c")
! && argv[2] && !argv[3]
! && _is_dos_shell (program))
! need_quote = 0;
! if (unescape_quote && _is_unixy_shell (program))
! unescape_quote = 0;
arglen = 0;
for (i=1; argv[i]; i++)
*************** static int go32_exec(const char *program
*** 631,640 ****
/* Construct the DOS command tail */
for (argc=0; argv[argc]; argc++);
! if (__dosexec_in_system)
{
! /* If PROGRAM is an un-stubbed COFF, it must be passed in the
! command tail as well, since we call GO32 to run it. */
for (i = (is_stubbed ? 1 : 0); i < argc; i++)
{
const char *p = argv[i];
--- 633,642 ----
/* Construct the DOS command tail */
for (argc=0; argv[argc]; argc++);
! if (__dosexec_in_system && v2_0)
{
! /* If PROGRAM is an un-stubbed COFF, its name must be passed
! in the command tail as well, since we call GO32 to run it. */
for (i = (is_stubbed ? 1 : 0); i < argc; i++)
{
const char *p = argv[i];
*************** static int go32_exec(const char *program
*** 660,667 ****
tbuf_end = tbuf_ptr + tbuf_len - 1;
/* If called from `system' and we have a command line shorter
! than the DOS limit, we don't need to use !proxy at all. */
! if (!__dosexec_in_system || cmdp - cmdline > CMDLEN_LIMIT)
{
if (!check_talloc(found_si ?
si.struct_length : 0
--- 662,671 ----
tbuf_end = tbuf_ptr + tbuf_len - 1;
/* If called from `system' and we have a command line shorter
! than the DOS limit, we don't need to use !proxy at all.
! Note that v1.x programs are always run through !proxy,
! to prevent go32.exe from printing its copyright line. */
! if (!__dosexec_in_system || !v2_0 || cmdp - cmdline > CMDLEN_LIMIT)
{
if (!check_talloc(found_si ?
si.struct_length : 0
*************** static struct {
*** 941,946 ****
--- 945,952 ----
{ ".btm", __dosexec_command_exec },
{ ".sh", script_exec }, /* for compatibility with ms_sh */
{ ".ksh", script_exec },
+ { ".pl", script_exec }, /* Perl */
+ { ".sed", script_exec },
{ "", go32_exec },
{ 0, script_exec }, /* every extension not mentioned above calls it */
{ 0, 0 },
*************** __dosexec_find_on_path(const char *progr
*** 1003,1009 ****
}
}
! if (haspath)
return 0;
*rp = 0;
--- 1009,1015 ----
}
}
! if (haspath || !envp)
return 0;
*rp = 0;
*** include/stdlib.h~2 Fri Aug 30 19:57:42 1996
--- include/stdlib.h Fri Sep 13 18:27:24 1996
*************** void * xrealloc(void *ptr, size_t _size
*** 108,114 ****
extern int __system_flags;
! extern int _shell_command (const char *_prog, const char *_cmdline);
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
--- 108,116 ----
extern int __system_flags;
! extern int _shell_command (const char *_prog, const char *_cmdline);
! extern int _is_unixy_shell (const char *_prog);
! extern int _is_dos_shell (const char *_prog);
#endif /* !_POSIX_SOURCE */
#endif /* !__STRICT_ANSI__ */
- Raw text -