Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

-e " " returns true

by PerlingTheUK (Hermit)
on Jul 05, 2004 at 15:41 UTC ( [id://371904]=perlquestion: print w/replies, xml ) Need Help??

PerlingTheUK has asked for the wisdom of the Perl Monks concerning the following question:

Hiya,

I have stumbled over a problem in my program. Trying to find the reason I have written the follwing test script::
my $pseudofile = " "; print "File exists.\n" if ( -e $pseudofile );
For the following pseudofile - names Perl claimed the file existed:
my $pseudofile = " "; my $pseudofile = " . . "; my $pseudofile = " .. "; my $pseudofile = " "; my $pseudofile = " . ";
I am not aware of the reason, is this on purpose? Or is this a bug?
I am using Active Perl 5.8.3 and WinXP (MSWin32-x86-multi-thread)

Hans

Replies are listed 'Best First'.
Re: -e " " returns true
by BrowserUk (Patriarch) on Jul 05, 2004 at 17:18 UTC

    Seems to be a long standing bug with Win32 perl. I get the same results going back to 5.6.1 and also with 5.8.4.

    I suggest you perlbug it.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      I found a 1996 article in "Microsoft Systems Journal" which indicates that Win32 does some very odd things with filenames with spaces in them.

        On this occasion, it appears that the problem is internal to Perl--with caveats.

        The problem occurs in these two lines from win32\win32.c (line numbers are approximate (5.8.4) because I've added debug code):

        1222: pwbuffer = PerlDir_mapW(wbuffer); ... 1228: path = PerlDir_mapA(path);

        Prior to these to lines the vars; path / wbuffer contain the bad paths being tested ( ' ', ' . . ' etc. ), but after they contain the fully expanded current working directory. They should not.

        So, the problem is in the routines PerlDir_mapW() / PerlDir_mapA(). The stat being returned for non-existant directory paths is that of the current working directory.

        But there, my trail grows cold. These functions are not functions, but #defines.

        One path through the #defines in iperlsys.h has these resolved to:

        #ifdef WIN32 #define PerlDir_mapA(dir) dir #define PerlDir_mapW(dir) dir #endif

        But that can't be right because then they would be unchanged and the problem wouldn't occur.

        The other branch of the #if defined(PERL_IMPLICIT_SYS) in iperlsys.h resolves them to entries in a vtable.

        #ifdef WIN32 #define PerlDir_mapA(dir) \ (*PL_Dir->pMapPathA)(PL_Dir, (dir)) #define PerlDir_mapW(dir) \ (*PL_Dir->pMapPathW)(PL_Dir, (dir)) #endif

        but search high'n'low, I cannot find out where these vtable entries are filled in?

        It appears to be related to PL_curinterp and embedvar.h, but I tracked it back through about 6 levels of indirection before getting completely lost. It will take someone much cleverer than me to resolve this further.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon

        To complete the picture, I finally tracked down the mysterious PerlDir_map(A|W) to win32\vdir.h. This appears to be a C++ Dir object class stolen from somewhere.

        The MapPath(A|W) methods are very strange indeed. They eventually call GetFullPathName(A|W) to convert relative paths to absolute paths, but go through a heap of pre-conditioning of the input path before doing so. This pre-conditioning appears to be intended to work around bugs in that API that existed back then.

        However, GetFullPathName still exibits some very peculiar bugs, including rendering various non-pathnames as the cwd as described earlier.

        This problem is an accumulation of OS bugs, a couple of perl implementation fopars, and too many layers. It's gonna be a bitch to fix.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
        I found a 1996 article in "Microsoft Systems Journal" which indicates that Win32 does some very odd things with filenames with spaces in them.

        This is no lie. I recommend against using any spaces in filenames on any system (because, they don't gain you anything underscores don't and they complicate things such as the command line unnecessarily), but _especially_ on Win32 (because the capability is retrofitted and imperfect). What gets especially icky is when you have spaces in directory names. Lots of software, including some Microsoft software and almost anything ported to Windows from the POSIX world, fails in some fairly weird ways in certain corner cases involving filenames with spaces. Among other things, the association mechanism in Explorer relies on the command line, but the quoting capabilities there (_especially_ in Win9x/Me) are sufficiently limited to create their own edge cases, so that even if you set up the association with quoted arguments there are still things that can go wrong. The best practice is to avoid putting spaces in any filenames or putting any files in directories with spaces in them. (On WinXP, it's okay to use your "My Documents" folder, but I don't even recommend that on 9x/Me; create your own C:\docs (or whatever) and use that, and you'll have fewer problems.)


        ;$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$;[-1]->();print
Re: -e " " returns true
by davorg (Chancellor) on Jul 05, 2004 at 15:50 UTC

    That's not what I'm seeing.

    $ cat test.pl #!/usr/bin/perl use strict; use warnings; my @files = (' ', ' . . ', ' .. ', ' ', ' . '); foreach (@files) { print "[$_] - ", -e $_ ? "yes\n" : "no\n"; } $ ./test.pl [ ] - no [ . . ] - no [ .. ] - no [ ] - no [ . ] - no $ perl -v This is perl, v5.8.3 built for i386-linux-thread-multi
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

        This is one of the times I really wish I was still on Linux.
        Thanks for trying as well and all those fast replies.

        Hans
      Same all-negative results here: This is perl, v5.6.0 built for darwin.

      Can we get a Windows ActivePerl user to run this as well?

        Using davorg's script I had 5 yes's.
        I have the same setup as PerlingTheUK.
        wfsp
Re: -e " " returns true
by pbeckingham (Parson) on Jul 05, 2004 at 15:48 UTC

    I get differing results - the following prints nothing on Panther, Perl 5.8.1:

    #! /usr/bin/perl -w use strict; print "File exists.\n" if -e ' '; print "File exists.\n" if -e ' . . '; print "File exists.\n" if -e ' .. '; print "File exists.\n" if -e ' '; print "File exists.\n" if -e '. ';
    Update: Clarified code.

Re: -e " " returns true
by traveler (Parson) on Jul 05, 2004 at 22:13 UTC
    I am pretty sure I learned this here, but I cannot find it with SS. Any combination of "." and " " returns true for -e on Windows. Even dir .. . gives a directory listing of the current directory (although dir ...... does not while dir . . . . . produces multiple listings of the current directory, but dir ". . . . ." doesn't). I thought someone here posted the reason, but I cannot find it.

    --traveler

Re: -e " " returns true (perlbug 30622)
by demerphq (Chancellor) on Jul 07, 2004 at 20:32 UTC

    I filed a bug report for this... Perlbug #30622


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://371904]
Approved by pbeckingham
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2024-04-25 23:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found