Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

"executable suffixes" for -x on win32 (perlport)

by pryrt (Curate)
on Apr 25, 2017 at 21:27 UTC ( #1188911=perlquestion: print w/replies, xml ) Need Help??
pryrt has asked for the wisdom of the Perl Monks concerning the following question:

Regarding the executable-test -x, perlport says:

-x (or -X) determine if a file ends in one of the executable suffixes. -S is meaningless. (Win32)

Where are the "executable suffixes" defined for Win32 perl (strawberry, in my case)? If anything, I would have expected $ENV{PATHEXT}, because that's the closest related idea to "executable" on windows (or possibly the assoc and ftype and their underlying registry entries -- though that's more complicated). However, I've got ".pl" in my PATHEXT variable and properly associated in the registry, but -x "$0" results in a false value (undef). I also tried with a .js file, which is in the Windows-default PATHEXT, but it shows up as non-executable as well. I've experimentally found that .com, .exe, .bat, and .cmd all show up as executable... but none of the others in the default PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

--

context: after reading Re^2: how do i run a shell command without waiting for the output, I looked at Proc::Background, and saw that commands were "checked by appending `.exe' to the name in case the name was passed without the `.exe' suffix". Since ".exe" isn't the only extension dropped on Win32 (PATHEXT defines the extension-omission properties for Win32, and .bat is frequently untyped as well), I wanted to suggest a bugfix to allow any extension from PATHEXT: change the hardcoded push(@extensions, '.exe'); to push @extensions, split(/;/, $ENV{PATHEXT} || '.exe');. However, while testing my change against various extensions (explicit or omitted-but-implied), I found that Proc::Background wasn't getting as far as using the @extensions array, since -x was failing. I found the quoted perlport description that Win32 -x has a list of extensions, but I haven't found the official documentation for what that list is (and really, if there's any hardcoded list embedded in the perl ports to Win32, I disagree with them on the same grounds that I disagree with Proc::Background)

#!/usr/bin/env perl use warnings; use strict; use Proc::Background; print "$0 => ", (-x $0 || 0), $/; foreach ( qw(./com-hello.com ./com-hello ./c-hello.exe ./c-hello ./bat +-hello.bat ./bat-hello ./cmd-hello.cmd ./cmd-hello ./js-hello.js ./js +-hello C:/path-to/cpan-bugs/proc-bg/js-hello.js) ) { local $\ = $/; local $, = "\t"; print STDERR $_; my $p = Proc::Background->new($_); if(!defined $p) { print STDERR $_, "didn't run"; next; } print STDERR '-x: ', ( (-x $_) || 0); print STDERR 'pid: ', $p->pid; print STDERR 'alive: ', $p->alive; print STDERR 'wait: ', $p->wait; print STDERR 'start: ', $p->start_time; print STDERR 'end: ', $p->end_time; print STDERR ''; } foreach my $ext (split /;/, $ENV{PATHEXT}) { local $\ = $/; local $, = "\t"; open my $fh, '>', "x$ext" or die "x$ext $!"; close $fh; print STDERR "x$ext", ( (-x "x$ext") || 0); unlink $fh; } __END__
C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl => 0 ./com-hello.com -x: 1 pid: 7164 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./com-hello -x: 0 pid: 3488 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./c-hello.exe -x: 1 pid: 3576 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./c-hello -x: 0 pid: 5312 alive: 1 Hello, world wait: 0 start: 1493154171 end: 1493154171 ./bat-hello.bat -x: 1 pid: 4816 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./bat-hello -x: 0 pid: 7972 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./cmd-hello.cmd -x: 1 pid: 668 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./cmd-hello -x: 0 pid: 6692 alive: 1 hello world wait: 0 start: 1493154171 end: 1493154171 ./js-hello.js C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: cannot find absolute lo +cation of ./js-hello.js ./js-hello.js didn't run ./js-hello C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: cannot find absolute lo +cation of ./js-hello ./js-hello didn't run C:/path-to/cpan-bugs/proc-bg/js-hello.js looking for absolute: C:/path-to/cpan-bugs/proc-bg/js-hello.js C:\path-to\cpan-bugs\proc-bg\hello-pathext.pl: no executable program l +ocated at C:/path-to/cpan-bugs/proc-bg/js-hello.js C:/path-to/cpan-bugs/proc-bg/js-hello.js didn't run x.com 1 x.exe 1 x.bat 1 x.cmd 1 x.vbs 0 x.vbe 0 x.js 0 x.jse 0 x.wsf 0 x.wsh 0 x.msc 0 x.pl 0 x.COM 1 x.EXE 1 x.BAT 1 x.CMD 1 x.VBS 0 x.VBE 0 x.JS 0 x.JSE 0 x.WSF 0 x.WSH 0 x.MSC 0 C:\path-to\cpan-bugs\proc-bg\>echo %pathext% .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc;.pl;.COM;.EXE;.B +AT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

edit: add <readmore> tags...

Replies are listed 'Best First'.
Re: "executable suffixes" for -x on win32 (perlport)
by Anonymous Monk on Apr 25, 2017 at 22:30 UTC

      Interesting. Reading the context behind those SEARCH_EXTS definitions, it's in the Perl_find_script() function (aliased to macro find_script), and (to my reading) doesn't seem to be in the context of the -x ftest, that I can tell

      Your .cmd search found (among others) the EU::MM instance where the four qw(.com .exe .bat .cmd) are shown, but that's in the EU::MM module, not in the -x ftest.

      Some more searching for the ftest led me to pp_sys.c:PP(pp_ftrread) and the associated S_try_amagic_ftest() a few lines up. I eventually found the win32_fstat(), which I think calls the MSVCRT fstat(), so I don't think I can blame the port of perl for this: it looks like that might be due to the underlying library.

      I've also verified that it is really just the four extensions (at least up to 3character extensions) that are considered "executable" to win32 perl:

      I made an equivalent program in c using the sys/stat.h's _stat(), and it was the same four extensions, only. I guess this one really can be blamed on Microsoft. :-)

        I guess this one really can be blamed on Microsoft. :-)

        That's one take on it. Here's another.

        Under POSIX, -x determines if the file tested can be passed to exec(3) in order to load a new executable image into the current process.

        By that criteria, only two of the four extensions you list ought to test as executable, because .cmd & .bat aren't binary image files, thus cannot be loaded directly as executable images. The other two are equivalent to (b|c|z)sh scripts which require execl("/bin/sh", "sh", "-c", command, (char *) 0) or similar to be run; ie. system.

        The MSVCRT 'extension' of the POSIX definition of -x is a (perhaps silly) convenience from days of yore that's never been seen as important enough to rescind.

        But then, the entire idea of the -x test on windows doesn't make a whole heap of sense as there is no such thing as the "executable" bit in Windows -- the permissions system is far more fine grained and extensive.

        And, the concept of a files executability being defined by its extension a throwback to dos. An executable file can have any extension and it will still run:

        C:\test>junk.exe as int: 9218868437227405313 as dbl: 1.#SNAN0 as dbl: 1.#QNAN0 as int: 9221120237041090561 C:\test>ren junk.exe junk.garbage C:\test>junk.garbage as int: 9218868437227405313 as dbl: 1.#SNAN0 as dbl: 1.#QNAN0 as int: 9221120237041090561

        In reality, the mistake is that .cmd & .bat test as executable, not that .pl/.js/.whatever do not. It is the equivalent of *nix allowing you to pass a shell script filename to exec() and have it start the shell and then pass the script filename to it. (Ie. what system does.) And if you pass .pl/.js/.whatever (anything in pathext) to system on windows, it will execute them.

        The bottom line is that you do not have to mark .cmd or .bat (or .exe or .com or .garbage) files executable, so there is no executable bit to test; so MSVCRT attempts to do something vaguely sensible as a substitute; but what was vaguely sensible all those years ago, perhaps looks less sensible now.

        The bottom line is that where the two different worlds collide, there is no right solution; and whatever compromise is implemented it will be useful and convenient in one scenario and broken in another.

        Similarly with the users/groups/network stuff. It isn't possible to map them transparently between OSs.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
        In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
Re: "executable suffixes" for -x on win32 (perlport)
by BrowserUk (Pope) on Apr 25, 2017 at 22:41 UTC
    I disagree with them on the same grounds that I disagree with Proc::Background)

    You're right, but it's par for the course. None of the user and group info functions, nor most of the network info functions work either.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1188911]
Approved by kcott
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2017-12-17 00:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (459 votes). Check out past polls.

    Notices?