$?, system() and win32

pjf on 2007-07-08T02:27:38

$?, system() and win32
Warning: Technical post ahead.

I've been working on improvements to IPC::System::Simple, and discovered a tricky problem while writing more test cases. Put very simply, when using system() under Windows I'm unable to tell the difference between a command that we can't find, and one that we can find, but returns an exit value of 1.

The problem is two-fold. Firstly, whenever we invoke a shell to spawn a process, we can't ever tell the difference between the shell returning a "can't start" value, and a command that runs successfully and returns the same value. This isn't a problem that's unique to Windows; the "can't start" value is 1 under Windows, and 127 under Unix.

The second problem is Windows-Perl specific. If it fails to start the command successfully, it tries to invoke it using the shell, even if the multi-argument version of system() is used. This means that under Windows we can never tell the difference between a failed command and a completed command returning -1.

I suspect that Perl invoking the shell when using a multi-arg system call is a bug. If not, then it needs to be explicitly documented. Time for me to fire up perlbug again.

In the meantime, I can get around most of these things problems in IPC::System::Simple by falling back on the Win32::Process module. This is almost certainly the correct solution regardless of what happens with Windows system(), since it allows us to access the full 16-bit return value, something that system() will never do. Unfortunately it means that I need to do a lot of the work by hand that would normally be handled in Perl's win32.c, and I'm not really looking forward to that.

For further reading, see $? set to strange values under Win32.