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