Change 34997 by [EMAIL PROTECTED] on 2008/12/03 21:39:10

        Integrate:
        [ 33993]
        Make Perl_vms_start_glob() decline politely when passed an empty
        argument.
        
        [ 34052]
        Subject: [EMAIL PROTECTED] Enable getgrgid on VMS
        From: "John E. Malmberg" <[EMAIL PROTECTED]>
        Date: Thu, 12 Jun 2008 19:50:01 -0500
        Message-id: <[EMAIL PROTECTED]>
        
        With some revisions.
        
        [ 34562]
        When testing the case sensitivity settings of the process
        on VMS, be a little more sensitive to older versions that
        don't have the capability.
        
        [ 34666]
        Subject: [EMAIL PROTECTED] vms.c setup_cmddsc
        From: "John E. Malmberg" <[EMAIL PROTECTED]>
        Message-id: <[EMAIL PROTECTED]>
        Date: Wed, 29 Oct 2008 22:02:43 -0500
        
        Remove trailing dot when efs_charset is in effect.
        
        [ 34667]
        Subject: Re: [EMAIL PROTECTED] VMS exec handling / cwd realpath fixes
        From: "John E. Malmberg" <[EMAIL PROTECTED]>
        Date: Wed, 29 Oct 2008 22:21:38 -0500
        Message-id: <[EMAIL PROTECTED]>
        
        Convert symlink target to UNIX format on VMS. (Cwd changes not
        included here.)
        
        [ 34668]
        Try to demangle the mess created by 34667 (the "resubmittal" was 
actually
        not at all like the original patch I tested).
        
        [ 34790]
        Subject: [EMAIL PROTECTED] Get posix exit mode working/tested on VMS
        From: "John E. Malmberg" <[EMAIL PROTECTED]>
        Date: Sun, 09 Nov 2008 00:46:03 -0600
        Message-id: <[EMAIL PROTECTED]>
        
        [ 34901]
        Subject: [EMAIL PROTECTED] vms readdir() fixes for UNIX/EFS mode
        From: "John E. Malmberg" <[EMAIL PROTECTED]>
        Date: Sat, 22 Nov 2008 11:31:58 -0600
        Message-id: <[EMAIL PROTECTED]>

Affected files ...

... //depot/maint-5.10/perl/perl.h#18 integrate
... //depot/maint-5.10/perl/t/op/groups.t#3 integrate
... //depot/maint-5.10/perl/t/run/exit.t#3 integrate
... //depot/maint-5.10/perl/vms/vms.c#7 integrate
... //depot/maint-5.10/perl/vms/vmsish.h#2 integrate

Differences ...

==== //depot/maint-5.10/perl/perl.h#18 (text) ====
Index: perl/perl.h
--- perl/perl.h#17~34989~       2008-12-03 02:48:40.000000000 -0800
+++ perl/perl.h 2008-12-03 13:39:10.000000000 -0800
@@ -2937,9 +2937,9 @@
                  PL_statusvalue_vms == SS$_NORMAL;     \
                else                                    \
                  if (MY_POSIX_EXIT)                    \
-                   PL_statusvalue_vms =        \
-                      (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \
-                       (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \
+                   PL_statusvalue_vms =                \
+                      (C_FAC_POSIX | (evalue << 3 ) |  \
+                      ((evalue == 1) ? (STS$K_ERROR | STS$M_INHIB_MSG) : 1)); \
                  else                                  \
                    PL_statusvalue_vms = SS$_ABORT; \
              } else { /* forgive them Perl, for they have sinned */ \
@@ -2965,6 +2965,9 @@
    * actual exit code will can be retrieved by the calling program or
    * shell.
    *
+   * A POSIX exit code is from 0 to 255.  If the exit code is higher
+   * than this, it needs to be assumed that it is a VMS exit code and
+   * passed through.
    */
 
 #   define STATUS_EXIT_SET(n)                          \
@@ -2972,9 +2975,10 @@
            I32 evalue = (I32)n;                        \
            PL_statusvalue = evalue;                    \
            if (MY_POSIX_EXIT)                          \
-               PL_statusvalue_vms =                    \
-                 (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \
-                  (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \
+               if (evalue > 255) PL_statusvalue_vms = evalue; else {   \
+                 PL_statusvalue_vms = \
+                   (C_FAC_POSIX | (evalue << 3 ) |     \
+                    ((evalue == 1) ? (STS$K_ERROR | STS$M_INHIB_MSG) : 1));} \
            else                                        \
                PL_statusvalue_vms = evalue ? evalue : SS$_NORMAL; \
            set_vaxc_errno(PL_statusvalue_vms);         \

==== //depot/maint-5.10/perl/t/op/groups.t#3 (xtext) ====
Index: perl/t/op/groups.t
--- perl/t/op/groups.t#2~33823~ 2008-05-12 03:24:27.000000000 -0700
+++ perl/t/op/groups.t  2008-12-03 13:39:10.000000000 -0800
@@ -1,7 +1,7 @@
 #!./perl
 
 $ENV{PATH} ="/bin:/usr/bin:/usr/xpg4/bin:/usr/ucb" .
-    exists $ENV{PATH} ? ":$ENV{PATH}" : "";
+    exists $ENV{PATH} ? ":$ENV{PATH}" : "" unless $^O eq 'VMS';
 $ENV{LC_ALL} = "C"; # so that external utilities speak English
 $ENV{LANGUAGE} = 'C'; # GNU locale extension
 
@@ -27,7 +27,8 @@
     exit 0;
 }
 
-quit() if (($^O eq 'MSWin32' || $^O eq 'NetWare') or $^O =~ /lynxos/i);
+quit() if (($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS')
+           or $^O =~ /lynxos/i);
 
 # We have to find a command that prints all (effective
 # and real) group names (not ids).  The known commands are:

==== //depot/maint-5.10/perl/t/run/exit.t#3 (text) ====
Index: perl/t/run/exit.t
--- perl/t/run/exit.t#2~34065~  2008-06-16 08:41:01.000000000 -0700
+++ perl/t/run/exit.t   2008-12-03 13:39:10.000000000 -0800
@@ -20,6 +20,24 @@
     $numtests = ($^O eq 'VMS') ? 16 : ($^O eq 'MacOS') ? 0 : 17;
 }
 
+
+my $vms_exit_mode = 0;
+
+if ($^O eq 'VMS') {
+    if (eval 'require VMS::Feature') {
+        $vms_exit_mode = !(VMS::Feature::current("posix_exit"));
+    } else {
+        my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} =~ /^[ET1]/i; 
+        my $posix_ex = $ENV{'PERL_VMS_POSIX_EXIT'} =~ /^[ET1]/i;
+        if (($unix_rpt || $posix_ex) ) {
+            $vms_exit_mode = 0;
+        } else {
+            $vms_exit_mode = 1;
+        }
+    }
+    $numtests = 29 unless $vms_exit_mode;
+}
+
 require "test.pl";
 plan(tests => $numtests);
 
@@ -34,7 +52,7 @@
 is( $exit, $?,                  'Normal exit $?' );
 is( ${^CHILD_ERROR_NATIVE}, $native_success,  'Normal exit 
${^CHILD_ERROR_NATIVE}' );
 
-if ($^O ne 'VMS') {
+if (!$vms_exit_mode) {
   my $posix_ok = eval { require POSIX; };
   my $wait_macros_ok = defined &POSIX::WIFEXITED;
   eval { POSIX::WIFEXITED() };
@@ -52,7 +70,11 @@
   }
 
   SKIP: {
-    skip("Skip signals and core dump tests on Win32", 7) if $^O eq 'MSWin32';
+    skip("Skip signals and core dump tests on Win32 and VMS", 7) 
+        if ($^O eq 'MSWin32' || $^O eq 'VMS');
+
+    #TODO VMS will backtrace on this test and exits with code of 0
+    #instead of 15.
 
     $exit = run('kill 15, $$; sleep(1);');
 
@@ -69,7 +91,9 @@
     }
   }
 
-} else {
+}
+
+if ($^O eq 'VMS') {
 
 # On VMS, successful returns from system() are reported 0,  VMS errors that
 # can not be translated to UNIX are reported as EVMSERR, which has a value
@@ -139,7 +163,7 @@
 # status codes to SS$_ABORT on exit, but passes through unmodified UNIX
 # status codes that exit() is called with by scripts.
 
-$exit_arg = (44 & 7) if $^O eq 'VMS';  
+$exit_arg = (44 & 7) if $vms_exit_mode;
 
 is( $exit >> 8, $exit_arg,             'Changing $? in END block' );
 }

==== //depot/maint-5.10/perl/vms/vms.c#7 (text) ====
Index: perl/vms/vms.c
--- perl/vms/vms.c#6~34477~     2008-10-14 00:11:27.000000000 -0700
+++ perl/vms/vms.c      2008-12-03 13:39:10.000000000 -0800
@@ -352,6 +352,7 @@
 int vms_vtf7_filenames = 0;
 int gnv_unix_shell = 0;
 static int vms_unlink_all_versions = 0;
+static int vms_posix_exit = 0;
 
 /* bug workarounds if needed */
 int decc_bug_readdir_efs1 = 0;
@@ -9629,11 +9630,32 @@
        &vs_spec,
        &vs_len);
 
-    /* Drop NULL extensions on UNIX file specification */
-    if ((dd->flags & PERL_VMSDIR_M_UNIXSPECS &&
-       (e_len == 1) && decc_readdir_dropdotnotype)) {
-       e_len = 0;
-       e_spec[0] = '\0';
+    if (dd->flags & PERL_VMSDIR_M_UNIXSPECS) {
+
+        /* In Unix report mode, remove the ".dir;1" from the name */
+        /* if it is a real directory. */
+        if (decc_filename_unix_report || decc_efs_charset) {
+            if ((e_len == 4) && (vs_len == 2) && (vs_spec[1] == '1')) {
+                if ((toupper(e_spec[1]) == 'D') &&
+                    (toupper(e_spec[2]) == 'I') &&
+                    (toupper(e_spec[3]) == 'R')) {
+                    Stat_t statbuf;
+                    int ret_sts;
+
+                    ret_sts = stat(buff, (stat_t *)&statbuf);
+                    if ((ret_sts == 0) && S_ISDIR(statbuf.st_mode)) {
+                        e_len = 0;
+                        e_spec[0] = 0;
+                    }
+                }
+            }
+        }
+
+        /* Drop NULL extensions on UNIX file specification */
+       if ((e_len == 1) && decc_readdir_dropdotnotype) {
+           e_len = 0;
+           e_spec[0] = '\0';
+        }
     }
 
     strncpy(dd->entry.d_name, n_spec, n_len + e_len);
@@ -9892,6 +9914,19 @@
     *cp2 = '\0';
     if (do_tovmsspec(resspec,cp,0,NULL)) { 
       s = vmsspec;
+
+      /* When a UNIX spec with no file type is translated to VMS, */
+      /* A trailing '.' is appended under ODS-5 rules.            */
+      /* Here we do not want that trailing "." as it prevents     */
+      /* Looking for a implied ".exe" type. */
+      if (decc_efs_charset) {
+          int i;
+          i = strlen(vmsspec);
+          if (vmsspec[i-1] == '.') {
+              vmsspec[i-1] = '\0';
+          }
+      }
+
       if (*rest) {
         for (cp2 = vmsspec + strlen(vmsspec);
              *rest && cp2 - vmsspec < sizeof vmsspec;
@@ -12758,6 +12793,11 @@
     unsigned long int lff_flags = 0;
     int rms_sts;
 
+    if (!SvOK(tmpglob)) {
+        SETERRNO(ENOENT,RMS$_FNF);
+        return NULL;
+    }
+
 #ifdef VMS_LONGNAME_SUPPORT
     lff_flags = LIB$M_FIL_LONG_NAMES;
 #endif
@@ -12975,14 +13015,41 @@
 /*
  * A thin wrapper around decc$symlink to make sure we follow the 
  * standard and do not create a symlink with a zero-length name.
+ *
+ * Also in ODS-2 mode, existing tests assume that the link target
+ * will be converted to UNIX format.
  */
-/*{{{ int my_symlink(const char *path1, const char *path2)*/
-int my_symlink(const char *path1, const char *path2) {
-  if (!path2 || !*path2) {
+/*{{{ int my_symlink(pTHX_ const char *contents, const char *link_name)*/
+int Perl_my_symlink(pTHX_ const char *contents, const char *link_name) {
+  if (!link_name || !*link_name) {
     SETERRNO(ENOENT, SS$_NOSUCHFILE);
     return -1;
   }
-  return symlink(path1, path2);
+
+  if (decc_efs_charset) {
+      return symlink(contents, link_name);
+  } else {
+      int sts;
+      char * utarget;
+
+      /* Unless we are in ODS-5 mode, convert the symlink target to UNIX */
+      /* because in order to work, the symlink target must be in UNIX format */
+
+      /* As symbolic links can hold things other than files, we will only do */
+      /* the conversion in in ODS-2 mode */
+
+      Newx(utarget, VMS_MAXRSS + 1, char);
+      if (do_tounixspec(contents, utarget, 0, NULL) == NULL) {
+
+          /* This should not fail, as an untranslatable filename */
+          /* should be passed through */
+          utarget = (char *)contents;
+      }
+      sts = symlink(utarget, link_name);
+      Safefree(utarget);
+      return sts;
+  }
+
 }
 /*}}}*/
 
@@ -13018,9 +13085,7 @@
 
     VMSISH_HUSHED = 0;
 
-    /* fix me later to track running under GNV */
-    /* this allows some limited testing */
-    MY_POSIX_EXIT = decc_filename_unix_report;
+    MY_POSIX_EXIT = vms_posix_exit;
 
     x = (float)ix;
     MY_INV_RAND_MAX = 1./x;
@@ -13182,8 +13247,101 @@
                        if (haslower) __mystrtolower(rslt);
                    }
                }
-       }
+       } else {
+
+           /* Now for some hacks to deal with backwards and forward */
+           /* compatibilty */
+           if (!decc_efs_charset) {
+
+               /* 1. ODS-2 mode wants to do a syntax only translation */
+               rslt = do_rmsexpand(filespec, outbuf,
+                                   0, NULL, 0, NULL, utf8_fl);
 
+           } else {
+               if (decc_filename_unix_report) {
+                   char * dir_name;
+                   char * vms_dir_name;
+                   char * file_name;
+
+                   /* 2. ODS-5 / UNIX report mode should return a failure */
+                   /*    if the parent directory also does not exist */
+                   /*    Otherwise, get the real path for the parent */
+                   /*    and add the child to it.
+
+                   /* basename / dirname only available for VMS 7.0+ */
+                   /* So we may need to implement them as common routines */
+
+                   Newx(dir_name, VMS_MAXRSS + 1, char);
+                   Newx(vms_dir_name, VMS_MAXRSS + 1, char);
+                   dir_name[0] = '\0';
+                   file_name = NULL;
+
+                   /* First try a VMS parse */
+                   sts = vms_split_path
+                         (filespec,
+                          &v_spec,
+                          &v_len,
+                          &r_spec,
+                          &r_len,
+                          &d_spec,
+                          &d_len,
+                          &n_spec,
+                          &n_len,
+                          &e_spec,
+                          &e_len,
+                          &vs_spec,
+                          &vs_len);
+
+                   if (sts == 0) {
+                       /* This is VMS */
+
+                       int dir_len = v_len + r_len + d_len + n_len;
+                       if (dir_len > 0) {
+                          strncpy(dir_name, filespec, dir_len);
+                          dir_name[dir_len] = '\0';
+                          file_name = (char *)&filespec[dir_len + 1];
+                       }
+                   } else {
+                       /* This must be UNIX */
+                       char * tchar;
+
+                       tchar = strrchr(filespec, '/');
+
+                       if (tchar != NULL) {
+                           int dir_len = tchar - filespec;
+                           strncpy(dir_name, filespec, dir_len);
+                           dir_name[dir_len] = '\0';
+                           file_name = (char *) &filespec[dir_len + 1];
+                       }
+                   }
+
+                   /* Dir name is defaulted */
+                   if (dir_name[0] == 0) {
+                       dir_name[0] = '.';
+                       dir_name[1] = '\0';
+                   }
+
+                   /* Need realpath for the directory */
+                   sts = vms_fid_to_name(vms_dir_name,
+                                         VMS_MAXRSS + 1,
+                                         dir_name);
+
+                   if (sts == 0) {
+                       /* Now need to pathify it.
+                       char *tdir = do_pathify_dirspec(vms_dir_name,
+                                                       outbuf, utf8_fl);
+
+                       /* And now add the original filespec to it */
+                       if (file_name != NULL) {
+                           strcat(outbuf, file_name);
+                       }
+                       return outbuf;
+                   }
+                   Safefree(vms_dir_name);
+                   Safefree(dir_name);
+               }
+            }
+        }
         Safefree(vms_spec);
     }
     return rslt;
@@ -13401,7 +13559,6 @@
     gnv_unix_shell = 0;
     status = sys_trnlnm("GNV$UNIX_SHELL", val_str, sizeof(val_str));
     if ($VMS_STATUS_SUCCESS(status)) {
-       if ((val_str[0] == 'E') || (val_str[0] == '1') || (val_str[0] == 'T')) {
         gnv_unix_shell = 1;
         set_feature_default("DECC$EFS_CASE_PRESERVE", 1);
         set_feature_default("DECC$EFS_CHARSET", 1);
@@ -13410,9 +13567,7 @@
         set_feature_default("DECC$READDIR_DROPDOTNOTYPE", 1);
         set_feature_default("DECC$DISABLE_POSIX_ROOT", 0);
         vms_unlink_all_versions = 1;
-       }
-       else
-        gnv_unix_shell = 0;
+        vms_posix_exit = 1;
     }
 #endif
 
@@ -13483,8 +13638,10 @@
     s = decc$feature_get_index("DECC$FILENAME_UNIX_REPORT");
     if (s >= 0) {
        decc_filename_unix_report = decc$feature_get_value(s, 1);
-       if (decc_filename_unix_report > 0)
+       if (decc_filename_unix_report > 0) {
            decc_filename_unix_report = 1;
+           vms_posix_exit = 1;
+       }
        else
            decc_filename_unix_report = 0;
     }
@@ -13596,7 +13753,7 @@
     }
 #endif
 
-#if defined(JPI$_CASE_LOOKUP_PERM) && !defined(__VAX)
+#if defined(JPI$_CASE_LOOKUP_PERM) && defined(PPROP$K_CASE_BLIND) && 
!defined(__VAX)
 
      /* Report true case tolerance */
     /*----------------------------*/
@@ -13612,6 +13769,17 @@
 
 #endif
 
+    /* USE POSIX/DCL Exit codes - Recommended, but needs to default to  */
+    /* for strict backward compatibilty */
+    status = sys_trnlnm
+       ("PERL_VMS_POSIX_EXIT", val_str, sizeof(val_str));
+    if ($VMS_STATUS_SUCCESS(status)) {
+       if ((val_str[0] == 'E') || (val_str[0] == '1') || (val_str[0] == 'T'))
+        vms_posix_exit = 1;
+       else
+        vms_posix_exit = 0;
+    }
+
 
     /* CRTL can be initialized past this point, but not before. */
 /*    DECC$CRTL_INIT(); */

==== //depot/maint-5.10/perl/vms/vmsish.h#2 (text) ====
Index: perl/vms/vmsish.h
--- perl/vms/vmsish.h#1~32694~  2007-12-22 01:23:09.000000000 -0800
+++ perl/vms/vmsish.h   2008-12-03 13:39:10.000000000 -0800
@@ -276,7 +276,7 @@
 #define my_endpwent()          Perl_my_endpwent(aTHX)
 #define my_getlogin            Perl_my_getlogin
 #ifdef HAS_SYMLINK
-#  define my_symlink           Perl_my_symlink
+#  define my_symlink(a, b)     Perl_my_symlink(aTHX_ a, b)
 #endif
 #define init_os_extras         Perl_init_os_extras
 #define vms_realpath(a, b, c)  Perl_vms_realpath(aTHX_ a,b,c)
@@ -449,7 +449,11 @@
  *     getgrgid() routines are available to get group entries.
  *     The getgrent() has a separate definition, HAS_GETGRENT.
  */
+#if __CRTL_VER >= 70302000
+#define HAS_GROUP              /**/
+#else
 #undef HAS_GROUP               /**/
+#endif
 
 /* HAS_PASSWD
  *     This symbol, if defined, indicates that the getpwnam() and
@@ -968,7 +972,7 @@
 int     my_fclose (FILE *);
 int     my_fwrite (const void *, size_t, size_t, FILE *);
 #ifdef HAS_SYMLINK
-int     my_symlink(const char *path1, const char *path2);
+int     Perl_my_symlink(pTHX_ const char *path1, const char *path2);
 #endif
 int    Perl_my_flush (pTHX_ FILE *);
 struct passwd *        Perl_my_getpwnam (pTHX_ const char *name);
End of Patch.

Reply via email to