On 2009-Aug-19, at 2:08 am, Darren Duncan wrote:
 %DOI{'mycwd'} = %DOI{'fscwd'};
 %DOI{'mycwd'} ~= 'subdir';
 # later
 my $fh = IO.open( 'mycwd/myfile.txt' );

For ease of use, we can still have vars like $*CWD, which might be an alias for a doi with a specific name.

I've been thinking of something similar, but you should be able to do this with any directory object.

my $dir = $*CWD; # returns an IO object, not merely a string my $dir ~= "subdir"; # $dir is now an object representing the subdir
    my $file = io "$dir/filename";

    {
        temp $*CWD = $dir;
        ...
    }


So the set of default standard dirs would just be a hash of IO objects: $IO::DOI{home}, $IO::DOI{docs}, etc. Actually, different OS's would provide different sets of standard named dirs, and you should be able to import them:

# Assume I'm running on a Mac, so $IO::DOI::MacOSX is automatically loaded use IO::DOI <Home Music Downloads>; # names that ::MacOSX makes available

    say $Home;         # /Users/david
    say $Music;        # /Users/david/Music
    say $Downloads;    # /Users/david/Junk drawer


There will be a few names that should be standard as much as possible across OS's, e.g. "Home" even though on a Mac the dir is actually called "Users". "Trash" might be another one (which will be undef if the OS doesn't handle it).


This doesn't address the security side of things; dir objects might have a flag you can set so that it will warn you (perhaps fatally) if you try to use $dir.parent or "$dir/..", etc., but you could always get to an outside dir some other way. I think a more explicit way to set a chroot is better, such as:

    $IO::Root = $*CWD;
    $IO::Root = $Home;
    temp $IO::Root = $IO::DOI{Docs};

Similarly, if a Perl thread does not see any DOI at all, then they effectively are denied access to the filesystem period.


Hm, undef $IO::Root?

Of course, that still doesn't cover everything your suggestion does, because your way allows for multiple roots. But you also weren't suggesting a specific syntax, and I'm leaning to something like my example above. Perhaps along the lines of:

    $IO::Root{"file"} = "/";         # default root (assumes "file://")
    $IO::Root{"http"} = "http://";;   # means any website
    $IO::Root{"ftp"} =  "ftp://";;    # etc.

Every time you use IO::Some_protocol_name, it would set a default $IO::Root{protocol-name}. But there's nothing special about the names; you can add or change $IO::Root as you wish.

    $IO::Root{"file"} = "/foo";
    $IO::Root{"more files"} = "/bar";
    # Now can access only files that come under /foo or /bar

    $IO::Root<$_>.delete for «file "more files"»;
    # Now there are no more file:// roots, cannot access any files

    $IO::Root<http> = "http://localhost/~david/";;
    # Now can access only URLs from my section of the local website


Hm, having just written that, it obviously should be the case that $IO::Root<file> should be a hash with all the available "file:" roots, i.e. $IO::Root is a hash-of-hashes where the keys are {protocol-name} {arbitrary-name}. And the default arbitrary-name might just be "default".



-David

Reply via email to