Good comments, David.
David Green wrote:
<snip>
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
Similarly, I think it very reasonable that for OS's like Windows where it is
commonplace for paths to start with a particular disk volume, then
$IO::DOI::Windows would automatically load a DOI for each mounted disk; eg that
$C or $E etc would be pre-defined.
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).
"Trash" wouldn't be so simple since there are multiple ".trash" directories; for
starters, at least one for each logical disk volume, and also one inside each
home folder under Users. If we had a "Trash", it would have to pick one of
those. Anyway, this is a minor issue that doesn't need to be worried about now.
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};
I would say that by design a "$dir/.." or $dir.parent should simply be
impossible; if someone tried to write that, they would get a subdir named
"parent" or "..", or a fatal warning if that isn't possible.
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.
What I had in mind was that every canonical DOI just lives as a member of a
single hash, and deleting the hash key is how you remove one. If you have a
separate variable for a single one then any use of it would be semantically
equivalent to substituting a hash access in its place, and the variable would be
undefined if the corresponding DOI doesn't exist, like a Perl 5 weakref when its
target is garbage-collected.
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".
-- Darren Duncan