On Tue, Jan 17, 2012 at 10:07 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-01-17, at 3:01 AM, REPLeffect wrote:
All of these tests were run against the current prebuilt versions of Gambit 4.6.0 and 4.6.2 downloaded from Gambit's web site.
I'll be happy to test any patches or other changes needed to fix this problem.
The implementation of the shell-command procedure is tricky. On Unix, the tradition of using /bin/sh is maintained. On Windows there are options: CMD.EXE, COMMAND.COM and sh (when MSYS or CYGWIN are installed). If MSYS or CYGWIN are installed and Gambit was launched from a shell in those environments, then it is reasonable to think that the user is executing shell-commands which make sense for those environments (for example, using "ls" instead of "dir"). Other users might expect or prefer the default Windows shell.
The implementation of shell-command tries to figure this out to start the correct shell to process the command. The logic is a bit brittle, and as you have experienced, it guessed the wrong shell.
I'm attaching below a new implementation of shell-command which does a better job. Can you try it out and let me know if it works for you? If you know of better heuristics, let me know!
Marc
(define ##shell-program #f)
(define (##get-shell-program)
(define unix-shell-program '("/bin/sh" . "-c")) (define windows-shell-program '("CMD.EXE" . "/C")) (define default-shell-program '("sh" . "-c"))
(or ##shell-program (let ((sp (if (##file-exists? (##car unix-shell-program)) unix-shell-program (if (##getenv "HOME" #f) default-shell-program (let ((comspec (##getenv "COMSPEC" #f))) (if comspec (##cons comspec "/C") windows-shell-program)))))) (set! ##shell-program sp) sp)))
(define (shell-command cmd) (let* ((shell-prog (##get-shell-program)) (path-or-settings (##list path: (##car shell-prog) arguments: (##list (##cdr shell-prog) cmd) stdin-redirection: #f stdout-redirection: #f stderr-redirection: #f))) (##open-process-generic 3;(macro-direction-inout) #t (lambda (port) (##close-port port) (##process-status port)) open-process path-or-settings)))
Marc,
That implemenation fixes the problem where running gsi in the standard cmd.exe shell had failed before, and I get the results I would expect when running (shell-command "dir 1 2 3").
However, when I run gsi from the MinGW Msys shell, and then run (shell-command "ls 1 2 3"), I still get the results you would expect from running (shell-command "ls") -- that is, there is no error, and it displays the contents of the current directory, rather than trying to list the files named "1" "2" and "3". Running under gdb again, I see that the command string returned from argv_to_cmd is "sh -c ls 1 2 3" -- just as it was in my previous testing.
So, next I ran gdb in the cmd.exe shell, and debugged gsi from there (setting the same breakpoint in argv_to_cmd):
Breakpoint 1, argv_to_ccmd (argv=0x1281648) at os_io.c:6817 6817 return ccmd; (gdb) p ccmd $1 = 0x1281740 "C:\WINDOWS\system32\cmd.exe /C dir 1 2 3"
Here again, the command being executed does not have quotes around it. It just so happens that under cmd.exe, that doesn't matter. You get the same results if you execute this:
cmd.exe /c dir 1 2 3
that you get if you execute this:
cmd.exe /c "dir 1 2 3"
However, if from the MinGW Msys shell you execute this:
sh -c ls 1 2 3
You will *not* get a listing of the files named "1" "2" and "3". You will get a listing of the current directory, just as if you had executed "sh -c ls".
However, executing this:
sh -c "ls 1 2 3"
gives the results you would expect:
ls: 1: No such file or directory ls: 2: No such file or directory ls: 3: No such file or directory