Date: Wed, 10 Sep 1997 17:19:10 +0300 (IDT) From: Eli Zaretskii To: Molnar Laszlo cc: DJGPP workers Subject: Re: a patch for system() In-Reply-To: <34167F53.5623095F@cdata.tvnet.hu> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Precedence: bulk On Wed, 10 Sep 1997, Molnar Laszlo wrote: > OK. Then I can't use libc's system(). In fact, when a perl script says > system("something"), Perl won't call the system() in libc on UNIX > platforms either. It just uses fork/exec (or spawn on OS2), if it > doesn't see a suspicious character. Else it will call 'sh' (or CSH if > the builder(!) of the executable had csh). So using builtin shell > commands can fail. The proper vehicle to port fork/exec is spawn, it has the same parameter list and the same way of handling the arguments as exec, so making it work is easy. In the case that Perl calls the shell, you need to call `system' instead, that is how Make works, and experience shows that most of the time, this produces desired results. I don't suggest to invoke any special shell. Just let `system' do its thing (when Perl thinks the shell should be called). You will probably need to review the code in Perl that decides whether the shell is required and see that it works correctly when SHELL or COMSPEC point to COMMAND.COM or [4N]DOS. One of the problems is that % is a special character for these two, whereas I think sh doesn't treat it specially. Another problem is that in DJGPP "..." is a wildcard, so you need to call `system' when you see it. > I just tried to use djgpp's system() because I didn't want to play with > spawn() when your system() would make most of the job for me. When Perl calls `exec', you don't need all the features of `system', because `exec' doesn't support redirection, pipes, quoting etc. anyway. > > ANSI requires that `system' should know how to run any command that > > the command processor (i.e., the shell) understands. > > But the programmer can't know what kind of shell the user will use. And > as we saw system("dir") can fail! There isn't much you can do with that. The only way to handle this so that it works for everybody is to invoke COMMAND.COM explicitly: system ("command.com /c dir > dir.lst"); (Note the .com extension: it MUST be there because in Bash, for example, "command" is a built-in command.) In essence, Unix does just that, because its `system' calls /bin/sh. Otherwise, you could have the same situation on Unix where a user could say e.g. ``system("ls-F")'' and expect it to work ("ls-F" is a built-in command in tcsh). But calling the default shell is a bad idea on MS-DOS, because COMMAND.COM is so dumb. It is evidently not so good even on Unix, which is why Perl calls the shell that the user uses interactively. But on DOS you can't do that because many people won't build Perl on their machines, they will just get the binaries. So I think that the best compromise is to just call `system' when Perl would call the shell on Unix, and let `system' do its job. > Ok, that would solve the problem with this particular script. But it was > just an example, there can be more scripts with the same problem out > there. And this ".exe" suffix is a little unportable. People expect to > use their script unchanged on different platforms. If there are cases, such as the perldoc script, where you must have reliable exit code, you don't have any choice but to change the script so it works. perldoc is not just any script, it is how users should read the docs, so it must work reliably. People indeed expect the scripts to work independently of the platforms, but when a script assumes too much about the underlying OS, it must be either changed so that it works on both platforms, or ported to DOS. DOS and Unix just aren't alike enough, sorry.