in reply to Re^3: Poll: Is your $^X an absolute path? (argv[0])
in thread Poll: Is your $^X an absolute path?

No, Win32 Perl has never figured out $^X based on argv[0]

I freely admit to being very new to reading the Perl source (what's that line about 'a maze of twisty passages'?) but what about this excerpt from perllib.c around the line you quoted (for Perl 5.8.8 anyway):

EXTERN_C DllExport int RunPerl(int argc, char **argv, char **env) { int exitstatus; PerlInterpreter *my_perl, *new_perl = NULL; #ifndef __BORLANDC__ /* XXX this _may_ be a problem on some compilers (e.g. Borland) th +at * want to free() argv after main() returns. As luck would have i +t, * Borland's CRT does the right thing to argv[0] already. */ char szModuleName[MAX_PATH]; GetModuleFileName(NULL, szModuleName, sizeof(szModuleName)); (void)win32_longpath(szModuleName); argv[0] = szModuleName; #endif

It looks like win32 Perl fixes up argv[0] itself -- and that this is what is used later by S_set_caret_X (a new function as of 5.8.7).

However, that perllib.c line is a great find for Vanilla Perl -- it means we should be able to use relocatable perl pretty easily in most circumstances. (I'm not going to worry about mod_perl on win32 at first.)

The downside is that the expansion uses the full path -- including spaces if installed somewhere like "C:\Program Files\Perl". That will still be problematic for people who call system("$^X program.pl arg1 arg2 etc") as the shell is going to have problems as the program name is not quoted. Of course -- that's not really a portable call anyway, so maybe we tackle that problem with documentation.

-xdg

Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Replies are listed 'Best First'.
Re^5: Poll: Is your $^X an absolute path? (system @list)
by tye (Sage) on Aug 18, 2006 at 12:19 UTC

      I think the safe thing is to always surround the first argument with double-quotes if more than one argument is provided and it doesn't already seem to have double quotes. (If only one argument is provided, we have to assume the user provided a valid command line on the current platform.) So, ignoring error reporting, something like this:

      sub system { $_[0] = qq{"$_[0]"} if @_ > 1 && substr($_[0],0,1) ne q{"}; CORE::system( @_ ); }

      On reflection, that seems simple enough that maybe we can get some p5p person to patch it.

      Some references about how spaces are handled in program names:

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        assume the user provided a valid command line on the current platform

        Which translates to "avoid portability". I strongly disagree.

        Look at existing attempts to provide portability with command lines in Perl. Several Perl subsystems compose lists of which command to use to do which task and then expect system($command{copy},$from,$to) to work. That is quite reasonable. Too bad it doesn't work very well on Win32. But that is because system(@list) has always been broke on Win32, depriving an important tool for dealing with command lines portably in Perl.

        Unfortunately, we can't make system(@list) work portably for all Win32 commands but we can make it work portable for most commands, and we should do that.

        But you do remind me of a point that I had previous included in my proposal but that I didn't include in the one I linked to. We should probably not add quotes if there are already quotes around the argument. I can see advantages to either way so perhaps it should be an option, but the default should be to avoid adding quotes if they are already there.

        - tye