Date: Sun, 19 Apr 1998 14:47:44 +0300 (IDT) From: Eli Zaretskii To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Patch for `system' to be ANSI-compliant Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk The following patch make `system' comply to ANSI specifications when passed a NULL pointer: *** src/libc/ansi/stdlib/system.c~0 Sun Aug 31 19:40:56 1997 --- src/libc/ansi/stdlib/system.c Sat Apr 18 17:10:38 1998 *************** system (const char *cmdline) *** 487,492 **** --- 487,493 ---- const char *envflags = getenv ("DJSYSFLAGS"); const char *comspec = getenv ("COMSPEC"); const char *shell = 0; + int call_shell; sys_flags = __system_flags; if (envflags && *envflags) *************** system (const char *cmdline) *** 505,513 **** if (!shell) shell = command_com; ! /* Special case: NULL means just exec the command interpreter. */ if (cmdline == 0) ! cmdline = ""; /* Strip initial spaces (so that if the command is empty, we know it right here). */ --- 506,533 ---- if (!shell) shell = command_com; ! call_shell = ! (sys_flags & __system_call_cmdproc) ! || (!(sys_flags & __system_emulate_command) && _is_unixy_shell (shell)); ! ! /* Special case: NULL means return non-zero if the command ! interpreter is available. This is ANSI C requirement. ! ! If we will call the shell to do everything, we need to see ! whether it exists. But if most of the work will be done by us ! anyway (like it usually is with stock DOS shell), return non-zero ! without checking, since our emulation is always ``available''. */ if (cmdline == 0) ! { ! if (!call_shell) ! return 1; ! else ! { ! char full_path[FILENAME_MAX]; ! ! return __dosexec_find_on_path (shell, (char **)0, full_path) ? 1 : 0; ! } ! } /* Strip initial spaces (so that if the command is empty, we know it right here). */ *************** system (const char *cmdline) *** 521,529 **** they want to always do it via command processor or $SHELL or $COMSPEC point to a unixy shell */ ! if (!*cmdline ! || (sys_flags & __system_call_cmdproc) ! || (!(sys_flags & __system_emulate_command) && _is_unixy_shell (shell))) return _shell_command ("", cmdline); else { --- 541,547 ---- they want to always do it via command processor or $SHELL or $COMSPEC point to a unixy shell */ ! if (!*cmdline || call_shell) return _shell_command ("", cmdline); else { *************** int main (int argc, char *argv[]) *** 787,793 **** puts (""); return 0; } ! return 1; } #endif --- 805,822 ---- puts (""); return 0; } ! else ! { ! int i; ! printf ("if system (NULL) returns non-zero, a shell is available:"); ! printf ("\n\nsystem() returned %d", (errno = 0, i = system ((char *)0))); ! fflush (stdout); ! if (errno) ! perror (""); ! else ! puts (""); ! return 1; ! } } #endif *** src/libc/ansi/stdlib/system.t~0 Fri Sep 27 02:24:50 1996 --- src/libc/ansi/stdlib/system.txh Sat Apr 18 17:19:10 1998 *************** *** 9,16 **** @subheading Description ! This function runs the command or program specified by @var{cmd}. When ! calling programs compiled by DJGPP this function will not use @file{command.com} and so will not be subject to its 126 character limit on command lines. --- 9,24 ---- @subheading Description ! This function runs the command or program specified by @var{cmd}. If ! @var{cmd} is a null pointer, @code{system} returns non-zero only if a ! shell is available. If @var{cmd} is an empty string, the command ! processor pointed to by @samp{SHELL} or @samp{COMSPEC} variables in the ! environment will be invoked interactively; type @kbd{exit @key{RET}} to ! return to the program which called @code{system}. (Note that some other ! DOS compilers treat a null pointer like an empty command line, contrary ! to ANSI C requirements.) ! ! When calling programs compiled by DJGPP this function will not use @file{command.com} and so will not be subject to its 126 character limit on command lines. *************** *** 42,50 **** thus found is one of the DOS shells (@file{command.com}, @file{4DOS} or @file{NDOS}), they are called with the @samp{/c} switch prepended to the command line. Otherwise, @code{system} assumes that the shell is a ! Unix-style shell and invokes it with a @samp{-c} switch, passing the ! entire command line via a response file (this should work with any shell ! compiled with DJGPP, and with the @code{ms_sh} shell). Shell scripts and batch files are invoked by calling either the program whose name appears on the first line (like in @w{@samp{#! /bin/sh}}), or --- 50,58 ---- thus found is one of the DOS shells (@file{command.com}, @file{4DOS} or @file{NDOS}), they are called with the @samp{/c} switch prepended to the command line. Otherwise, @code{system} assumes that the shell is a ! Unix-style shell and passes it the entire command line via a temporary ! file, invoking the shell with a single argument which is the name of ! that file. Shell scripts and batch files are invoked by calling either the program whose name appears on the first line (like in @w{@samp{#! /bin/sh}}), or *************** *** 143,151 **** @subheading Return Value ! The exit status of the child process in the lower 8 bits of the return ! value; bits 8-17 of the return value will hold @code{SIGINT} or ! @code{SIGABRT} if the child process was aborted by @kbd{Ctrl-C} or Critical Device Error, respectively; otherwise it will be zero. If the child couldn't be run, @code{system} will return -1 and set @code{errno} to an appropriate value. Note that if @file{COMMAND.COM} was used to --- 151,167 ---- @subheading Return Value ! If @var{cmd} is a null pointer, @code{system} returns non-zero if a ! shell is available. The actual test for the existence of an executable ! file pointed to by @samp{SHELL} or @samp{COMSPEC} is only performed if ! the shell is to be invoked to process the entire command line; if most ! of the work is to be done by @code{system} itself, passing a null ! pointer always yields a non-zero return value, since the internal ! emulation is always ``available''. ! ! Otherwise, the return value is the exit status of the child process in ! its lower 8 bits; bits 8-17 of the return value will hold @code{SIGINT} ! or @code{SIGABRT} if the child process was aborted by @kbd{Ctrl-C} or Critical Device Error, respectively; otherwise it will be zero. If the child couldn't be run, @code{system} will return -1 and set @code{errno} to an appropriate value. Note that if @file{COMMAND.COM} was used to *** src/docs/kb/wc202.t~8 Sat Mar 14 19:30:38 1998 --- src/docs/kb/wc202.txi Sat Apr 18 17:09:08 1998 *************** *** 358,360 **** --- 358,364 ---- but can allocate up to 254 handles (which is the maximum number allowed by DOS). @findex __FSEXT_alloc_fd + + @code{system} is now compliant with ANSI C Standard when its argument is + a NULL pointer. + @findex system