At 11:57 AM +0100 5/24/01, BAZLEY, Sebastian wrote:
>
>-e "NL:" and -z "NL:" are true, however
>
>-r "NL:" is false, as is -w "NL:"
>
>though NL: is both writable and readable ...

It turns out there were two problems with checking access on a bare
device name.  One, as Richard Brodie pointed out, is that we were
telling sys$check_access that such gadgets are files when in fact
they are not.  But upstream from there I found another problem.  We
were calling do_filefy_dirspec() on these things (the routine that
translates [.foo] into sys$disk:[]foo.dir) which in turn calls
sys$search, but sys$search blows up when passed a bare device name,
so we were saying access of any kind was impossible without even
checking.

The patch below seems to bring Perl_cando_by_name() up to snuff.  For
example, these writability tests returned false before the patch:

$ mcr []miniperl -e "print -w 'nl:';"
1
$ mcr []miniperl -e "print -w 'tt:';"
1
$ mcr []miniperl -e "print -w 'wsa1:';"
1

This is some rather twisty business in a section of code that is
quite heavily used, so I think I'll bang on it some more before
officially submitting it and I invite others to do so as well.
Thanks to Sebastian for flagging the problem and to Richard for the
insight that got me on my way.

--- vms.c_old    Mon May 21 22:48:08 2001
+++ vms.c       Fri May 25 17:04:09 2001
@@ -6079,7 +6079,7 @@
   static struct dsc$descriptor_s usrdsc =
          {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, usrname};
   char vmsname[NAM$C_MAXRSS+1], fileified[NAM$C_MAXRSS+1];
-  unsigned long int objtyp = ACL$C_FILE, access, retsts, privused, iosb[2];
+  unsigned long int objtyp, access, retsts, privused, iosb[2];
   unsigned short int retlen;
   struct dsc$descriptor_s namdsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
   union prvdef curprv;
@@ -6087,6 +6087,7 @@
          {sizeof privused, CHP$_PRIVUSED, &privused, &retlen},{0,0,0,0}};
   struct itmlst_3 jpilst[2] = {{sizeof curprv, JPI$_CURPRIV, &curprv, &retlen},
          {0,0,0,0}};
+  unsigned long int dviitm = DVI$_DEVCHAR, devchar_mask = 0;

   if (!fname || !*fname) return FALSE;
   /* Make sure we expand logical names, since sys$check_access doesn't */
@@ -6098,8 +6099,21 @@
   if (!do_tovmsspec(fname,vmsname,1)) return FALSE;
   retlen = namdsc.dsc$w_length = strlen(vmsname);
   namdsc.dsc$a_pointer = vmsname;
-  if (vmsname[retlen-1] == ']' || vmsname[retlen-1] == '>' ||
-      vmsname[retlen-1] == ':') {
+
+  /* See whether this is a file-oriented device or not. */
+
+  retsts = lib$getdvi(&dviitm, 0, &namdsc, &devchar_mask, 0, 0);
+
+  if ( (devchar_mask & DEV$M_FOD) ||  retsts == SS$_IVDEVNAM ||
+       retsts == SS$_IVLOGNAM || retsts == SS$_NOSUCHDEV ) {
+    objtyp = ACL$C_FILE;       /* assume file */
+    retsts = SS$_NORMAL;
+  } else {
+    objtyp = ACL$C_DEVICE;
+  }
+
+  if ( (objtyp == ACL$C_FILE) && (vmsname[retlen-1] == ']'
+      || vmsname[retlen-1] == '>' || vmsname[retlen-1] == ':') ) {
     if (!do_fileify_dirspec(vmsname,fileified,1)) return FALSE;
     namdsc.dsc$w_length = strlen(fileified);
     namdsc.dsc$a_pointer = fileified;
@@ -6123,7 +6137,9 @@
       return FALSE;
   }

-  retsts = sys$check_access(&objtyp,&namdsc,&usrdsc,armlst);
+  if (retsts & 1) {
+    retsts = sys$check_access(&objtyp,&namdsc,&usrdsc,armlst);
+  }
   if (retsts == SS$_NOPRIV      || retsts == SS$_NOSUCHOBJECT ||
       retsts == SS$_INVFILFOROP || retsts == RMS$_FNF || retsts == RMS$_SYN ||
       retsts == RMS$_DIR        || retsts == RMS$_DEV || retsts == RMS$_DNF) {
[end of patch]


-- 
____________________________________________
Craig A. Berry                  
mailto:[EMAIL PROTECTED]

"Literary critics usually know what they're
talking about. Even if they're wrong."
        -- Perl creator Larry Wall

Reply via email to