This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make PerlIOUnix_open honor default permissions on VMS.
authorCraig A. Berry <craigberry@mac.com>
Sat, 28 Aug 2010 16:37:33 +0000 (11:37 -0500)
committerCraig A. Berry <craigberry@mac.com>
Sat, 28 Aug 2010 17:28:04 +0000 (12:28 -0500)
When perlio became the default and unixio became the default bottom
layer, the most common path for creating files from Perl became
PerlIOUnix_open, which has always explicitly used 0666 as the
permission mask.  This has the following undesireable effects on
VMS:

1.) The execute bit is lost regardless of whether it's in the default
    permissions.

2.) Delete permission (which doesn't exist in the Unix permission mask) is
    copied from write permission, so granting write permission also grants
    delete even if it's not in the default permission mask.  This can result
    in an inadvertent widening of permissions.

3.) System permissions (which don't exist in the Unix permission mask) are
    copied from owner permissions, so any distinction between system and
    owner is lost.

4.) ACLs are not inherited.  For example, setting a default_protection ACE
    on a directory such that all world access is disallowed will be ignored;
    world will have the intersection of RWD (the final 6 in 0666) and whatever
    the default permissions are regardless of what the ACL says.  Thus not
    inheriting ACLs can result in the inadvertent widening of permissions.

The way to avoid all of this is to pass 0777 as the permissions to open().
In the VMS CRTL, 0777 has a special meaning over and above intersecting
with the current umask; specifically, it allows Unix syscalls to preserve
native default permissions.  Details currently documented at:

http://h71000.www7.hp.com/doc/732final/5763/5763pro_060.html#umask_routine

perlio.c

index ab08bec..5df704e 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -2598,7 +2598,11 @@ PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
            mode++;
        else {
            imode = PerlIOUnix_oflags(mode);
            mode++;
        else {
            imode = PerlIOUnix_oflags(mode);
+#ifdef VMS
+           perm = 0777; /* preserve RMS defaults, ACL inheritance, etc. */
+#else
            perm = 0666;
            perm = 0666;
+#endif
        }
        if (imode != -1) {
            const char *path = SvPV_nolen_const(*args);
        }
        if (imode != -1) {
            const char *path = SvPV_nolen_const(*args);