Change 19889 by [EMAIL PROTECTED] on 2003/06/30 08:36:38

        The 'contiguous' test for argv[], envp[] was bogus
        since those need not be in memory end-to-end, e.g.
        in Tru64 they are aligned by eight.  Loosen the test
        so that 'contiguousness' is fulfilled if the elements
        are within PTRSIZE alignment.  This makes Tru64 to pass
        the join.t, too.

Affected files ...

... //depot/perl/ext/threads/t/join.t#11 edit
... //depot/perl/mg.c#269 edit
... //depot/perl/perl.c#496 edit

Differences ...

==== //depot/perl/ext/threads/t/join.t#11 (text) ====
Index: perl/ext/threads/t/join.t
--- perl/ext/threads/t/join.t#10~19887~ Mon Jun 30 00:20:58 2003
+++ perl/ext/threads/t/join.t   Mon Jun 30 01:36:38 2003
@@ -91,7 +91,8 @@
     ok(1,"");
 }
 
-if ($^O eq 'linux') { # We parse ps output so this is OS-dependent.
+# We parse ps output so this is OS-dependent.
+if ($^O =~ /^(linux|dec_osf)$/) {
   # First modify $0 in a subthread.
   print "# mainthread: \$0 = $0\n";
   threads->new( sub {
@@ -100,7 +101,7 @@
                  print "# subthread: \$0 = $0\n" } )->join;
   print "# mainthread: \$0 = $0\n";
   print "# pid = $$\n";
-  if (open PS, "ps -f |") { # Note: must work in (all) Linux(es).
+  if (open PS, "ps -f |") { # Note: must work in (all) systems.
     my ($sawpid, $sawexe);
     while (<PS>) {
       chomp;

==== //depot/perl/mg.c#269 (text) ====
Index: perl/mg.c
--- perl/mg.c#268~19884~        Sun Jun 29 08:41:05 2003
+++ perl/mg.c   Mon Jun 30 01:36:38 2003
@@ -2372,13 +2372,7 @@
             pstat(PSTAT_SETCMD, un, len, 0, 0);
        }
 #endif
-       /* PL_origalen is set in perl_parse() to be the sum
-        * of the contiguous argv[] elements plus the size of
-        * the env in case that is contiguous with the argv[].
-        *
-        * This means that in the worst case the area we are able
-        * to modify is limited to the size of the original argv[0].
-        * --jhi */
+       /* PL_origalen is set in perl_parse(). */
        s = SvPV_force(sv,len);
        if (len >= (I32)PL_origalen) {
            /* Longer than original, will be truncated. */
@@ -2392,7 +2386,7 @@
            memset(PL_origargv[0] + len + 1,
                   /* Is the space counterintuitive?  Yes.
                    * (You were expecting \0?)  
-                   * Does it work?  Seems to.  (In Linux at least.)
+                   * Does it work?  Seems to.  (In Linux 2.4.20 at least.)
                    * --jhi */
                   (int)' ',
                   PL_origalen - len - 1);

==== //depot/perl/perl.c#496 (text) ====
Index: perl/perl.c
--- perl/perl.c#495~19884~      Sun Jun 29 08:41:05 2003
+++ perl/perl.c Mon Jun 30 01:36:38 2003
@@ -934,35 +934,52 @@
     PL_origargv = argv;
 
     {
-        char *s = PL_origargv[0];
+       /* Set PL_origalen be the sum of the contiguous argv[]
+        * elements plus the size of the env in case that it is
+        * contiguous with the argv[].  This is used in mg.c:mg_set()
+        * as the maximum modifiable length of $0.  In the worst case
+        * the area we are able to modify is limited to the size of
+        * the original argv[0].
+        * --jhi */
+        char *s;
         int i;
+        int mask =
+          ~(PTRSIZE == 4 ? 3 : PTRSIZE == 8 ? 7 : PTRSIZE == 16 ? 15 : 0);
 
-        s += strlen(s);
-        /* See if all the arguments are contiguous in memory */
+        /* See if all the arguments are contiguous in memory.
+         * Note that 'contiguous' is a loose term because some
+         * platforms align the argv[] and the envp[].  We just check
+         * that they are within aligned PTRSIZE bytes.  As long as no
+         * system has something bizarre like the argv[] interleaved
+         * with some other data, we are fine.  (Did I just evoke
+         * Murphy's Law?) --jhi */
+        s = PL_origargv[0];
+        while (*s) s++;
         for (i = 1; i < PL_origargc; i++) {
-             if (PL_origargv[i] == s + 1
-#ifdef OS2
-                 || PL_origargv[i] == s + 2
-#endif
-                  )
-             {
-                  ++s;
-                  s += strlen(s);      /* this one is ok too */
+             if (PL_origargv[i] >  s &&
+                 PL_origargv[i] <=
+                 INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) {
+                  s = PL_origargv[i];
+                  while (*s) s++;
              }
              else
                   break;
         }
-        /* Can we grab env area too to be used as the area for $0
-         * (in case we later modify it)? */
-        if (PL_origenviron
-            && (PL_origenviron[0] == s + 1))
-        {
+        /* Can we grab env area too to be used as the area for $0? */
+        if (PL_origenviron &&
+            PL_origenviron[0] >  s &&
+            PL_origenviron[0] <=
+            INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) {
+             s = PL_origenviron[0];
+             while (*s) s++;
              my_setenv("NoNe  SuCh", Nullch);
-             /* force copy of environment */
-             for (i = 0; PL_origenviron[i]; i++)
-                  if (PL_origenviron[i] == s + 1) {
-                       ++s;
-                       s += strlen(s);
+             /* Force copy of environment. */
+             for (i = 1; PL_origenviron[i]; i++)
+                  if (PL_origenviron[i] >  s &&
+                      PL_origenviron[i] <=
+                      INT2PTR(char *, PTR2UV(s + PTRSIZE) & mask)) {
+                       s = PL_origenviron[i];
+                       while (*s) s++;
                   }
                   else
                        break;
End of Patch.

Reply via email to