Change 19884 by [EMAIL PROTECTED] on 2003/06/29 15:41:05

        The joy of $0.  Undoing the #16399 makes Andreas'
        tests (see [perl #22811]) pass (yes, padding with space instead
        of nul makes no sense, but that seems to work, maybe Linux does
        some deep magic in ps(1)?); moving the PL_origalen computation
        earlier makes also the threaded-first case fully pass.
        
        But in general modifying the argv[] is very non-portable.
        (e.g. in Tru64 it seems to be limited to the size of the
        original argv[0] since the argv[] are not contiguous?)
        
        Everybody should just have setproctitle().

Affected files ...

... //depot/perl/mg.c#268 edit
... //depot/perl/perl.c#495 edit
... //depot/perl/pod/perlvar.pod#122 edit

Differences ...

==== //depot/perl/mg.c#268 (text) ====
Index: perl/mg.c
--- perl/mg.c#267~19870~        Sat Jun 28 08:39:57 2003
+++ perl/mg.c   Sun Jun 29 08:41:05 2003
@@ -2372,60 +2372,32 @@
             pstat(PSTAT_SETCMD, un, len, 0, 0);
        }
 #endif
-       if (!PL_origalen) {
-           s = PL_origargv[0];
-           s += strlen(s);
-           /* See if all the arguments are contiguous in memory */
-           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 */
-               }
-               else
-                   break;
-           }
-           /* can grab env area too? */
-           if (PL_origenviron
-#ifdef USE_ITHREADS
-               && PL_curinterp == aTHX
-#endif
-               && (PL_origenviron[0] == s + 1))
-           {
-               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);
-                   }
-                   else
-                       break;
-           }
-           PL_origalen = s - PL_origargv[0];
-       }
+       /* 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 */
        s = SvPV_force(sv,len);
-       i = len;
-       if (i >= (I32)PL_origalen) {
-           i = PL_origalen;
-           /* don't allow system to limit $0 seen by script */
-           /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
-           Copy(s, PL_origargv[0], i, char);
-           s = PL_origargv[0]+i;
-           *s = '\0';
+       if (len >= (I32)PL_origalen) {
+           /* Longer than original, will be truncated. */
+           Copy(s, PL_origargv[0], PL_origalen, char);
+           PL_origargv[0][PL_origalen - 1] = 0;
        }
        else {
-           Copy(s, PL_origargv[0], i, char);
-           s = PL_origargv[0]+i;
-           *s++ = '\0';
-           while (++i < (I32)PL_origalen)
-               *s++ = '\0';
+           /* Shorter than original, will be padded. */
+           Copy(s, PL_origargv[0], len, char);
+           PL_origargv[0][len] = 0;
+           memset(PL_origargv[0] + len + 1,
+                  /* Is the space counterintuitive?  Yes.
+                   * (You were expecting \0?)  
+                   * Does it work?  Seems to.  (In Linux at least.)
+                   * --jhi */
+                  (int)' ',
+                  PL_origalen - len - 1);
            for (i = 1; i < PL_origargc; i++)
-               PL_origargv[i] = Nullch;
+                PL_origargv[i] = 0;
        }
        UNLOCK_DOLLARZERO_MUTEX;
        break;

==== //depot/perl/perl.c#495 (text) ====
Index: perl/perl.c
--- perl/perl.c#494~19870~      Sat Jun 28 08:39:57 2003
+++ perl/perl.c Sun Jun 29 08:41:05 2003
@@ -933,6 +933,43 @@
     PL_origargc = argc;
     PL_origargv = argv;
 
+    {
+        char *s = PL_origargv[0];
+        int i;
+
+        s += strlen(s);
+        /* See if all the arguments are contiguous in memory */
+        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 */
+             }
+             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))
+        {
+             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);
+                  }
+                  else
+                       break;
+        }
+        PL_origalen = s - PL_origargv[0];
+    }
+
     if (PL_do_undump) {
 
        /* Come here if running an undumped a.out. */

==== //depot/perl/pod/perlvar.pod#122 (text) ====
Index: perl/pod/perlvar.pod
--- perl/pod/perlvar.pod#121~19870~     Sat Jun 28 08:39:57 2003
+++ perl/pod/perlvar.pod        Sun Jun 29 08:41:05 2003
@@ -838,16 +838,17 @@
 
 =item $0
 
-Contains the name of the program being executed.  On some operating
-systems assigning to C<$0> modifies the argument area that the B<ps>
-program sees.  This is more useful as a way of indicating the current
-program state than it is for hiding the program you're running.
-(Mnemonic: same as B<sh> and B<ksh>.)
+Contains the name of the program being executed.  On some (read: not
+all) operating systems assigning to C<$0> modifies the argument area
+that the B<ps> program sees.  Also note that depending on the platform,
+the maximum length of C<$0> may be limited to the space occupied by
+the original C<$0>.  This is more useful as a way of indicating the
+current program state than it is for hiding the program you're
+running.  (Mnemonic: same as B<sh> and B<ksh>.)
 
 Note for BSD users: setting C<$0> does not completely remove "perl"
 from the ps(1) output.  For example, setting C<$0> to C<"foobar"> will
-result in C<"perl: foobar (perl)">.  This is an operating system
-feature.
+result in C<"perl: foobar (perl)">.  This is an operating system feature.
 
 In multithreaded scripts Perl coordinates the threads so that any
 thread may modify its copy of the C<$0> and the change becomes visible
End of Patch.

Reply via email to