From: Jarkko Hietaniemi Date: Sat, 30 Nov 2002 20:16:51 +0000 (+0200) Subject: $0 mofifying part I X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e297595301ee5f3b0643be0fb1fffae9b6b548a0;p=p5sagit%2Fp5-mst-13.2.git $0 mofifying part I Subject: [PATCH] $0 modifying Message-ID: <20021130181651.GA5876@kosh.hut.fi> p4raw-id: //depot/perl@18229 --- diff --git a/ext/threads/t/join.t b/ext/threads/t/join.t index f2c88d5..892f48d 100644 --- a/ext/threads/t/join.t +++ b/ext/threads/t/join.t @@ -11,7 +11,7 @@ BEGIN { use ExtUtils::testlib; use strict; -BEGIN { print "1..10\n" }; +BEGIN { print "1..11\n" }; use threads; use threads::shared; @@ -87,3 +87,30 @@ ok(1,""); })->join(); ok(1,""); } + +if ($^O eq 'linux') { # We parse ps output so this is OS-dependent. + + # First modify $0 in a subthread. + print "# 1a: \$0 = $0\n"; + join( threads->new( sub { + print "# 2a: \$0 = $0\n"; + $0 = "foobar"; + print "# 2b: \$0 = $0\n" } ) ); + print "# 1b: \$0 = $0\n"; + if (open PS, "ps -f |") { + my $ok; + while () { + print "# $_"; + if (/^\S+\s+$$\s.+\sfoobar\s*$/) { + $ok++; + last; + } + } + close PS; + ok($ok, 'altering $0 is effective'); + } else { + skip("\$0 check: opening 'ps -f |' failed: $!"); + } +} else { + skip("\$0 check: only on Linux"); +} diff --git a/makedef.pl b/makedef.pl index 564ded0..3813b9f 100644 --- a/makedef.pl +++ b/makedef.pl @@ -643,6 +643,7 @@ unless ($define{'USE_ITHREADS'}) { PL_regex_padav PL_sharedsv_space PL_sharedsv_space_mutex + PL_dollarzero_mutex Perl_dirp_dup Perl_cx_dup Perl_si_dup diff --git a/mg.c b/mg.c index 64f6497..69bb521 100644 --- a/mg.c +++ b/mg.c @@ -2207,6 +2207,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) break; #ifndef MACOS_TRADITIONAL case '0': + LOCK_DOLLARZERO_MUTEX; #ifdef HAS_SETPROCTITLE /* The BSDs don't show the argv[] in ps(1) output, they * show a string from the process struct and provide @@ -2286,6 +2287,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) for (i = 1; i < PL_origargc; i++) PL_origargv[i] = Nullch; } + UNLOCK_DOLLARZERO_MUTEX; break; #endif } diff --git a/perl.c b/perl.c index 11da315..bc0c28b 100644 --- a/perl.c +++ b/perl.c @@ -489,11 +489,6 @@ perl_destruct(pTHXx) PL_e_script = Nullsv; } - while (--PL_origargc >= 0) { - Safefree(PL_origargv[PL_origargc]); - } - Safefree(PL_origargv); - /* magical thingies */ SvREFCNT_dec(PL_ofs_sv); /* $, */ @@ -897,21 +892,7 @@ setuid perl scripts securely.\n"); #endif PL_origargc = argc; - { - /* we copy rather than point to argv - * since perl_clone will copy and perl_destruct - * has no way of knowing if we've made a copy or - * just point to argv - */ - int i = PL_origargc; - New(0, PL_origargv, i+1, char*); - PL_origargv[i] = '\0'; - while (i-- > 0) { - PL_origargv[i] = savepv(argv[i]); - } - } - - + PL_origargv = argv; if (PL_do_undump) { @@ -937,6 +918,10 @@ setuid perl scripts securely.\n"); oldscope = PL_scopestack_ix; PL_dowarn = G_WARN_OFF; +#ifdef USE_ITHREADS + MUTEX_INIT(&PL_dollarzero_mutex); +#endif + #ifdef PERL_FLEXIBLE_EXCEPTIONS CALLPROTECT(aTHX_ pcur_env, &ret, MEMBER_TO_FPTR(S_vparse_body), env, xsinit); #else diff --git a/pod/perlvar.pod b/pod/perlvar.pod index 258645e..1a71142 100644 --- a/pod/perlvar.pod +++ b/pod/perlvar.pod @@ -869,6 +869,10 @@ 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. +In multithreaded scripts Perl coordinates the threads so that any +thread may modify its copy of the C<$0> and the change becomes visible +to ps(1) (assuming the operating system plays along). + =item $[ The index of the first element in an array, and of the first character diff --git a/sv.c b/sv.c index 9597a8a..90a99df 100644 --- a/sv.c +++ b/sv.c @@ -10233,12 +10233,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, /* pseudo environmental stuff */ PL_origargc = proto_perl->Iorigargc; - i = PL_origargc; - New(0, PL_origargv, i+1, char*); - PL_origargv[i] = '\0'; - while (i-- > 0) { - PL_origargv[i] = SAVEPV(proto_perl->Iorigargv[i]); - } + PL_origargv = proto_perl->Iorigargv; param->stashes = newAV(); /* Setup array of objects to call clone on */ diff --git a/t/op/magic.t b/t/op/magic.t index f6958fd..cbf8564 100755 --- a/t/op/magic.t +++ b/t/op/magic.t @@ -257,7 +257,7 @@ else { open CMDLINE, "/proc/$$/cmdline") { chomp(my $line = scalar ); my $me = (split /\0/, $line)[0]; - ok($me eq $0, 'altering $0 is effective', 'PL_origarg{c,v} copy breaks this'); + ok($me eq $0, 'altering $0 is effective'); close CMDLINE; } else { skip("\$0 check only on Linux and FreeBSD with /proc"); diff --git a/thread.h b/thread.h index 1d33161..1b57ebe 100644 --- a/thread.h +++ b/thread.h @@ -326,6 +326,9 @@ # define THREAD_RET_CAST(p) ((void *)(p)) #endif /* THREAD_RET */ +# define LOCK_DOLLARZERO_MUTEX MUTEX_LOCK(&PL_dollarzero_mutex) +# define UNLOCK_DOLLARZERO_MUTEX MUTEX_UNLOCK(&PL_dollarzero_mutex) + #endif /* USE_ITHREADS */ #ifndef MUTEX_LOCK @@ -404,6 +407,14 @@ # define UNLOCK_SV_LOCK_MUTEX #endif +#ifndef LOCK_DOLLARZERO_MUTEX +# define LOCK_DOLLARZERO_MUTEX +#endif + +#ifndef UNLOCK_DOLLARZERO_MUTEX +# define UNLOCK_DOLLARZERO_MUTEX +#endif + /* THR, SET_THR, and dTHR are there for compatibility with old versions */ #ifndef THR # define THR PERL_GET_THX