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

I have two Windows questions:
  1. Is there a simple file test I can use on Win32 for read, write, execute, etc.? I'm doing this as a check that the dependent scripts are executable before trying to run them. If I were on unix, I'd just use (-x $filename) to see if a file is executable. However, I tried that with the following code, and it didn't work -
    my $filename = 'ShowPerm.pl'; if ( -x $filename ) { print "Filename $filename is executable \n"; }
    ShowPerm.pl is a script that I know works, and is in the same directory as the script. It seems like I may have to read in the ACL of the file and see if I'm in a group that has the appropriate level of access to that file. However, it can be a catch-22, as if I don't even have the ability to list the file, I wouldn't be able to check the ACLs on it, either. Besides, it just seems like a clumsy process with a lot of overhead. What would you all suggest?

  2. It seems that in all the Win32 modules I've looked at, all the pathnames have an escaped backslash, i.e. \\\\servername\\sharename if the actual path is \\servername\sharename. I understand that is to have it work within quotes, but it makes the code harder to read, and makes the configuration files a little confusing. Since I'm aiming this to be used by users who don't know perl who can just edit the config file, I'd prefer not to have duplicate slashes. Has anybody ran into this and have suggestions?

-- Burvil

Replies are listed 'Best First'.
Re: Win32 File tests, pathnames
by GrandFather (Saint) on Apr 05, 2006 at 23:53 UTC

    You shouldn't need to quote \ in config files. It is only when Perl is parsing quoted strings in its source that the quoting is needed. Consider:

    use strict; use warnings; print "Quoted \\ required here, its in a string\n"; print <DATA>; __DATA__ This \ doesn't need to be quoted.

    Prints:

    Quoted \ required here, its in a string This \ doesn't need to be quoted.

    DWIM is Perl's answer to Gödel
      I realize I don't have to escape a \ in a config file, but it gets messy converting it back and forth when writing it to and reading it from the config file. In other words,

      • if I read in the value C:\filename from a config file, I have to add another \ when using it as $filename = "C:\\filename", and
      • when writing the value "C:\\filename" back to the config file, I need to take out the extra \ again.
      This, to me, adds extra bulk to the application and makes it less maintainable and robust, e.g. easy to break due to typos.

      -- Burvil

        That simply doesn't make sense to me. Show us some code that demonstrates the problem. Tip: see I know what I mean. Why don't you? for ways to make your sample code self contained.


        DWIM is Perl's answer to Gödel
      You shouldn't need to quote \ in config files

      well, it depends on the format of the configuration file. Some use the backslash as a way to introduce special sequences and characters (for instance Java property files).

Re: Win32 File tests, pathnames
by cdarke (Prior) on Apr 06, 2006 at 09:23 UTC
    Try using forward slashes (a la Unix)! Yes, the Windows API accept either a back or forward slash as a directory separator, it is only Windows Explorer and cmd.exe that insists on backslash. In fact you can have a Win32 pathname with both \ and / in it(messy though).
Re: Win32 File tests, pathnames
by bowei_99 (Friar) on Apr 06, 2006 at 01:57 UTC
    Sorry for re-posting... just in case people don't want to click down another level...

    Well, I put together some sample code, and OK, it reads a pathname with single slashes, and seems to run it ok, except for a 'Can't spawn "filename-here" No error" after executing the command.

    What I was getting at was that, since so many of the docs for Win32 modules have double slashes instead of single slashes, if I were to follow that convention, I'd have to convert back and forth between single and double slashes. An example, taken from from the Win32::AdminMisc FAQ:

    Win32::AdminMisc::ComputerAliasAdd( '\\\\Server1', 'fred' );
    and another example from the Win32::FileOp page:
    Substed 'A:' => ('','Floppy0') Substed 'B:' => undef Substed 'C:' => ('','Harddisk0\Partition1') Substed 'H:' => ('\\\\servername\homes\username','UNC') # set by subst H: \\servername\homes\username Substed 'S:' => ('\\\\servername\servis','LanmanRedirector') # set by net use S: \\servername\servis Substed 'X:' => () # not mapped to anything
    You will notice that these, and other cases, have four slashes, not two, at the beginning of a UNC path.

    So, basically, I'm worried that somewhere along the line, I'll get the two mixed up. A potential ramification here is that the config file could be written with four slashes and not two for a UNC path. Of course, there are other bugs that could pop up, too...

    -- Burvil

Re: Win32 File tests, pathnames
by cdarke (Prior) on Apr 06, 2006 at 11:32 UTC
    On the security side, for some reason the implementation does not use the ACL to check permissions, it uses the old style DOS permissions, which only has read-only. I think POSIX::access does the same, but I'm not sure and can't test it right now. It might be worth a look. Otherwise I'm afraid its Win32::FileSecurity.
    Please note that just because you have execute access on a Windows script it does not mean you can execute it, and the Windows does not support #! This means, for example, you run a perl script by prefixing 'perl -w'. See also Win32::FetchCommand.
Re: Win32 File tests, pathnames
by pKai (Priest) on Apr 06, 2006 at 07:03 UTC

    I still can't see your point here.

    As Grandfather mentioned escaping backslashes is only needed in code. Also your examples are code.

    That leaves the impression that your (user editable) "configuration" actually ist code, i. e. text that is eval-ed inside your program.

    That is a a bad idea by itself, with the additional observed consequence of having to be aware of perl's syntax rules in the "configuration"

    I have written a lot of perl programs under Windows and they regularly read file/path names from ini like configurations. There was never a case anything had to be quoted (the perl-code-way) in that configuration files.