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;
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. */
=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