exec's portability

Pop quiz! What does this perl 5 program prints when executed with no arguments?

#!/usr/bin/perl

use strict;
use warnings;

if (! @ARGV)
{
exec($^X, $0, "hello world");
}
else
{
my $arg = shift(@ARGV);
print "Got <$arg>\n";
if (@ARGV)
{
print "Other args are <@ARGV>\n";
}
}

The answer is "it depends.". On my Linux system it prints "Got <hello world>", while on Windows, using Strawberry Perl, it prints "Got <hello>" and later on that the other args are "world".

I would expect the Linux behaviour were every argument passed to the list exec arrives as one argument to @ARGV regardless of whitespace as the correct. It also the behaviour exhibited on both operating systems using system. Is this a bug?

perlport only has this to say about whitespace: Whitespace in filenames is tolerated on most systems, but not all, and even on systems where it might be tolerated, some utilities might become confused by such whitespace..

I discovered this strange mis-behaviour when working on a commission for a client who is Windows-based.

2 Comments

On Unixoid systems, there is a real argv. On Windows, harking back to the days of CP/M, there is a only a command line string and the called program has to parse the string itself to get a vector out of it. On Unixoid systems, the shell gets the job of parsing program invocations encoded as a single string and this happens before the program is invoked – when programs call each other, they can pass a real vector and do not need to encode a command line. And if you do have a string and need to parse it, mostly you follow the rules established by shell. On Windows, there is no such luck (read: consistency): the invoking program has to know which rules exactly are used by the invoked program for parsing its command line, and each invoked program can have different ones.

In practice, of course, it is not impossible to pass arguments to a program on Windows because almost all of them use the argv emulation provided by MS C runtime library, so there is something like a standard. But there have been subtle differences in its parsing over time, and you cannot even rely on every program on the system using the same CRT version.

So maybe perl can do better on Windows. But it will never be able to do this right, because on Windows that means knowing how to do it specifically for each and every individual program you invoke.

I ♥ Windows.

It seems to me that under Mac OS Classic (meaning Mac OS 9 and below) exec gave you an error like "We're not that kind of system"

Leave a comment

About Shlomi Fish

user-pic An Israeli software developer, essayist, and writer, and an enthusiast of open/free software and cultural works. I've been working with Perl since 1996.