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 {
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;
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. */
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);
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;
-
- s += strlen(s);
- /* See if all the arguments are contiguous in memory */
+ int mask =
+ ~(PTRSIZE == 4 ? 3 : PTRSIZE == 8 ? 7 : PTRSIZE == 16 ? 15 : 0);
+
+ /* 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;