X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=mg.c;h=4369e4ae10c0f0d5e71a20ce8a3ae0ae2199e1f7;hb=1ed8eac0dfbbdc6acb022ff1733a2473c102328b;hp=5511c09a409dc4428dcd7c805abe1168786c9940;hpb=acfe0abcedaf592fb4b9cb69ce3468308ae99d91;p=p5sagit%2Fp5-mst-13.2.git diff --git a/mg.c b/mg.c index 5511c09..4369e4a 100644 --- a/mg.c +++ b/mg.c @@ -25,6 +25,15 @@ # endif #endif +/* if you only have signal() and it resets on each signal, FAKE_PERSISTENT_SIGNAL_HANDLERS fixes */ +#if !defined(HAS_SIGACTION) && defined(VMS) +# define FAKE_PERSISTENT_SIGNAL_HANDLERS +#endif +/* if we're doing kill() with sys$sigprc on VMS, FAKE_DEFAULT_SIGNAL_HANDLERS */ +#if defined(KILL_BY_SIGPRC) +# define FAKE_DEFAULT_SIGNAL_HANDLERS +#endif + static void restore_magic(pTHX_ void *p); static void unwind_handler_stack(pTHX_ void *p); @@ -392,7 +401,7 @@ Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg) else /* @- */ i = s; - if (i > 0 && PL_reg_sv_utf8) { + if (i > 0 && PL_reg_match_utf8) { char *b = rx->subbeg; if (b) i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i)); @@ -433,7 +442,7 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) { i = t1 - s1; getlen: - if (i > 0 && PL_reg_sv_utf8) { + if (i > 0 && PL_reg_match_utf8) { char *s = rx->subbeg + s1; char *send = rx->subbeg + t1; @@ -519,62 +528,66 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) #endif break; case '\005': /* ^E */ + if (*(mg->mg_ptr+1) == '\0') { #ifdef MACOS_TRADITIONAL - { - char msg[256]; + { + char msg[256]; - sv_setnv(sv,(double)gMacPerl_OSErr); - sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : ""); - } + sv_setnv(sv,(double)gMacPerl_OSErr); + sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : ""); + } #else #ifdef VMS - { -# include -# include - char msg[255]; - $DESCRIPTOR(msgdsc,msg); - sv_setnv(sv,(NV) vaxc$errno); - if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1) - sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length); - else - sv_setpv(sv,""); - } + { +# include +# include + char msg[255]; + $DESCRIPTOR(msgdsc,msg); + sv_setnv(sv,(NV) vaxc$errno); + if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1) + sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length); + else + sv_setpv(sv,""); + } #else #ifdef OS2 - if (!(_emx_env & 0x200)) { /* Under DOS */ - sv_setnv(sv, (NV)errno); - sv_setpv(sv, errno ? Strerror(errno) : ""); - } else { - if (errno != errno_isOS2) { - int tmp = _syserrno(); - if (tmp) /* 2nd call to _syserrno() makes it 0 */ - Perl_rc = tmp; - } - sv_setnv(sv, (NV)Perl_rc); - sv_setpv(sv, os2error(Perl_rc)); - } + if (!(_emx_env & 0x200)) { /* Under DOS */ + sv_setnv(sv, (NV)errno); + sv_setpv(sv, errno ? Strerror(errno) : ""); + } else { + if (errno != errno_isOS2) { + int tmp = _syserrno(); + if (tmp) /* 2nd call to _syserrno() makes it 0 */ + Perl_rc = tmp; + } + sv_setnv(sv, (NV)Perl_rc); + sv_setpv(sv, os2error(Perl_rc)); + } #else #ifdef WIN32 - { - DWORD dwErr = GetLastError(); - sv_setnv(sv, (NV)dwErr); - if (dwErr) - { - PerlProc_GetOSError(sv, dwErr); - } - else - sv_setpv(sv, ""); - SetLastError(dwErr); - } + { + DWORD dwErr = GetLastError(); + sv_setnv(sv, (NV)dwErr); + if (dwErr) + { + PerlProc_GetOSError(sv, dwErr); + } + else + sv_setpv(sv, ""); + SetLastError(dwErr); + } #else - sv_setnv(sv, (NV)errno); - sv_setpv(sv, errno ? Strerror(errno) : ""); + sv_setnv(sv, (NV)errno); + sv_setpv(sv, errno ? Strerror(errno) : ""); #endif #endif #endif #endif - SvNOK_on(sv); /* what a wonderful hack! */ - break; + SvNOK_on(sv); /* what a wonderful hack! */ + } + else if (strEQ(mg->mg_ptr+1, "NCODING")) + sv_setsv(sv, PL_encoding); + break; case '\006': /* ^F */ sv_setiv(sv, (IV)PL_maxsysfd); break; @@ -612,16 +625,20 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) } break; case '\024': /* ^T */ + if (*(mg->mg_ptr+1) == '\0') { #ifdef BIG_TIME - sv_setnv(sv, PL_basetime); + sv_setnv(sv, PL_basetime); #else - sv_setiv(sv, (IV)PL_basetime); + sv_setiv(sv, (IV)PL_basetime); #endif - break; + } + else if (strEQ(mg->mg_ptr, "\024AINT")) + sv_setiv(sv, PL_tainting); + break; case '\027': /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */ if (*(mg->mg_ptr+1) == '\0') sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE)); - else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) { + else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) { if (PL_compiling.cop_warnings == pWARN_NONE || PL_compiling.cop_warnings == pWARN_STD) { @@ -635,7 +652,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) } SvPOK_only(sv); } - else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS")) + else if (strEQ(mg->mg_ptr+1, "IDE_SYSTEM_CALLS")) sv_setiv(sv, (IV)PL_widesyscalls); break; case '1': case '2': case '3': case '4': @@ -666,7 +683,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) PL_tainted = FALSE; } sv_setpvn(sv, s, i); - if (PL_reg_sv_utf8 && is_utf8_string((U8*)s, i)) + if (PL_reg_match_utf8 && is_utf8_string((U8*)s, i)) SvUTF8_on(sv); else SvUTF8_off(sv); @@ -768,6 +785,8 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) case ',': break; case '\\': + if (PL_ors_sv) + sv_setpv(sv,SvPVX(PL_ors_sv)); break; case '#': sv_setpv(sv,PL_ofmt); @@ -850,7 +869,6 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) register char *s; char *ptr; STRLEN len, klen; - I32 i; s = SvPV(sv,len); ptr = MgPV(mg,klen); @@ -903,6 +921,7 @@ Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg) while (s < strend) { char tmpbuf[256]; struct stat st; + I32 i; s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, s, strend, ':', &i); s++; @@ -955,27 +974,10 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) #if defined(VMS) || defined(EPOC) Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system"); #else -# ifdef PERL_IMPLICIT_SYS +# if defined(PERL_IMPLICIT_SYS) || defined(WIN32) PerlEnv_clearenv(); # else -# ifdef WIN32 - char *envv = GetEnvironmentStrings(); - char *cur = envv; - STRLEN len; - while (*cur) { - char *end = strchr(cur,'='); - if (end && end != cur) { - *end = '\0'; - my_setenv(cur,Nullch); - *end = '='; - cur = end + strlen(end+1)+2; - } - else if ((len = strlen(cur))) - cur += len+1; - } - FreeEnvironmentStrings(envv); -# else -#ifdef USE_ENVIRON_ARRAY +# ifdef USE_ENVIRON_ARRAY # ifndef PERL_USE_SAFE_PUTENV I32 i; @@ -988,13 +990,22 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) environ[0] = Nullch; -#endif /* USE_ENVIRON_ARRAY */ -# endif /* WIN32 */ -# endif /* PERL_IMPLICIT_SYS */ -#endif /* VMS */ +# endif /* USE_ENVIRON_ARRAY */ +# endif /* PERL_IMPLICIT_SYS || WIN32 */ +#endif /* VMS || EPC */ return 0; } +#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS)||defined(FAKE_DEFAULT_SIGNAL_HANDLERS) +static int sig_handlers_initted = 0; +#endif +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS +static int sig_ignoring[SIG_SIZE]; /* which signals we are ignoring */ +#endif +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS +static int sig_defaulting[SIG_SIZE]; +#endif + #ifndef PERL_MICRO int Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg) @@ -1007,8 +1018,14 @@ Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg) if(PL_psig_ptr[i]) sv_setsv(sv,PL_psig_ptr[i]); else { - Sighandler_t sigstate = rsignal_state(i); - + Sighandler_t sigstate; + sigstate = rsignal_state(i); +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS + if (sig_handlers_initted && sig_ignoring[i]) sigstate = SIG_IGN; +#endif +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS + if (sig_handlers_initted && sig_defaulting[i]) sigstate = SIG_DFL; +#endif /* cache state so we don't fetch it again */ if(sigstate == SIG_IGN) sv_setpv(sv,"IGNORE"); @@ -1052,15 +1069,51 @@ Perl_raise_signal(pTHX_ int sig) Signal_t Perl_csighandler(int sig) { +#ifndef PERL_OLD_SIGNALS + dTHX; +#endif +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS + (void) rsignal(sig, &Perl_csighandler); + if (sig_ignoring[sig]) return; +#endif +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS + if (sig_defaulting[sig]) +#ifdef KILL_BY_SIGPRC + exit((Perl_sig_to_vmscondition(sig)&STS$M_COND_ID)|STS$K_SEVERE|STS$M_INHIB_MSG); +#else + exit(1); +#endif +#endif + #ifdef PERL_OLD_SIGNALS /* Call the perl level handler now with risk we may be in malloc() etc. */ (*PL_sighandlerp)(sig); #else - dTHX; Perl_raise_signal(aTHX_ sig); #endif } +#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS) +void +Perl_csighandler_init(void) +{ + int sig; + if (sig_handlers_initted) return; + + for (sig = 1; sig < SIG_SIZE; sig++) { +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS + dTHX; + sig_defaulting[sig] = 1; + (void) rsignal(sig, &Perl_csighandler); +#endif +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS + sig_ignoring[sig] = 0; +#endif + } + sig_handlers_initted = 1; +} +#endif + void Perl_despatch_signals(pTHX) { @@ -1103,6 +1156,15 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s); return 0; } +#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS) + if (!sig_handlers_initted) Perl_csighandler_init(); +#endif +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS + sig_ignoring[i] = 0; +#endif +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS + sig_defaulting[i] = 0; +#endif SvREFCNT_dec(PL_psig_name[i]); SvREFCNT_dec(PL_psig_ptr[i]); PL_psig_ptr[i] = SvREFCNT_inc(sv); @@ -1119,14 +1181,26 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) } s = SvPV_force(sv,len); if (strEQ(s,"IGNORE")) { - if (i) + if (i) { +#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS + sig_ignoring[i] = 1; + (void)rsignal(i, &Perl_csighandler); +#else (void)rsignal(i, SIG_IGN); - else +#endif + } else *svp = 0; } else if (strEQ(s,"DEFAULT") || !*s) { if (i) +#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS + { + sig_defaulting[i] = 1; + (void)rsignal(i, &Perl_csighandler); + } +#else (void)rsignal(i, SIG_DFL); +#endif else *svp = 0; } @@ -1506,7 +1580,7 @@ Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg) sv_insert(lsv, lvoff, lvlen, tmps, len); SvUTF8_on(lsv); } - else if (SvUTF8(lsv)) { + else if (lsv && SvUTF8(lsv)) { sv_pos_u2b(lsv, &lvoff, &lvlen); tmps = (char*)bytes_to_utf8((U8*)tmps, &len); sv_insert(lsv, lvoff, lvlen, tmps, len); @@ -1756,25 +1830,32 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) DEBUG_x(dump_all()); break; case '\005': /* ^E */ + if (*(mg->mg_ptr+1) == '\0') { #ifdef MACOS_TRADITIONAL - gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); + gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); #else # ifdef VMS - set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); # else # ifdef WIN32 - SetLastError( SvIV(sv) ); + SetLastError( SvIV(sv) ); # else # ifdef OS2 - os2_setsyserrno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + os2_setsyserrno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); # else - /* will anyone ever use this? */ - SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4); + /* will anyone ever use this? */ + SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4); # endif # endif # endif #endif - break; + } + else if (strEQ(mg->mg_ptr+1, "NCODING")) { + if (PL_encoding) + sv_setsv(PL_encoding, sv); + else + PL_encoding = newSVsv(sv); + } case '\006': /* ^F */ PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); break; @@ -1825,7 +1906,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) | (i ? G_WARN_ON : G_WARN_OFF) ; } } - else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) { + else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) { if ( ! (PL_dowarn & G_WARN_ALL_MASK)) { if (!SvPOK(sv) && PL_localizing) { sv_setpvn(sv, WARN_NONEstring, WARNsize); @@ -1859,7 +1940,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) } } } - else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS")) + else if (strEQ(mg->mg_ptr+1, "IDE_SYSTEM_CALLS")) PL_widesyscalls = SvTRUE(sv); break; case '.': @@ -1868,7 +1949,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) SAVESPTR(PL_last_in_gv); } else if (SvOK(sv) && GvIO(PL_last_in_gv)) - IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv); + IoLINES(GvIOp(PL_last_in_gv)) = SvIV(sv); break; case '^': Safefree(IoTOP_NAME(GvIOp(PL_defoutgv))); @@ -1881,19 +1962,21 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO); break; case '=': - IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + IoPAGE_LEN(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); break; case '-': - IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + IoLINES_LEFT(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L) IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L; break; case '%': - IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); + IoPAGE(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); break; case '|': { IO *io = GvIOp(PL_defoutgv); + if(!io) + break; if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0) IoFLAGS(io) &= ~IOf_FLUSH; else { @@ -1911,10 +1994,8 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) PL_multiline = (i != 0); break; case '/': - SvREFCNT_dec(PL_nrs); - PL_nrs = newSVsv(sv); SvREFCNT_dec(PL_rs); - PL_rs = SvREFCNT_inc(PL_nrs); + PL_rs = newSVsv(sv); break; case '\\': if (PL_ors_sv) @@ -2218,7 +2299,9 @@ Perl_whichsig(pTHX_ char *sig) return 0; } +#if !defined(PERL_IMPLICIT_CONTEXT) static SV* sig_sv; +#endif Signal_t Perl_sighandler(int sig) @@ -2286,7 +2369,9 @@ Perl_sighandler(int sig) if(PL_psig_name[sig]) { sv = SvREFCNT_inc(PL_psig_name[sig]); flags |= 64; +#if !defined(PERL_IMPLICIT_CONTEXT) sig_sv = sv; +#endif } else { sv = sv_newmortal(); sv_setpv(sv,PL_sig_name[sig]); @@ -2317,7 +2402,7 @@ Perl_sighandler(int sig) (void)rsignal(sig, &Perl_csighandler); #endif #endif /* !PERL_MICRO */ - Perl_die(aTHX_ Nullch); + Perl_die(aTHX_ Nullformat); } cleanup: if (flags & 1) @@ -2387,6 +2472,8 @@ unwind_handler_stack(pTHX_ void *p) if (flags & 1) PL_savestack_ix -= 5; /* Unprotect save in progress. */ /* cxstack_ix-- Not needed, die already unwound it. */ +#if !defined(PERL_IMPLICIT_CONTEXT) if (flags & 64) SvREFCNT_dec(sig_sv); +#endif }