This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
dTHR is a nop in 5.6.0 onwards. Ergo, it can go.
[perl5.git] / mg.c
1 /*    mg.c
2  *
3  *    Copyright (c) 1991-2000, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * "Sam sat on the ground and put his head in his hands.  'I wish I had never
12  * come here, and I don't want to see no more magic,' he said, and fell silent."
13  */
14
15 #include "EXTERN.h"
16 #define PERL_IN_MG_C
17 #include "perl.h"
18
19 #if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
20 #  ifndef NGROUPS
21 #    define NGROUPS 32
22 #  endif
23 #endif
24
25 static void restore_magic(pTHXo_ void *p);
26 static void unwind_handler_stack(pTHXo_ void *p);
27
28 /*
29  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
30  */
31
32 struct magic_state {
33     SV* mgs_sv;
34     U32 mgs_flags;
35     I32 mgs_ss_ix;
36 };
37 /* MGS is typedef'ed to struct magic_state in perl.h */
38
39 STATIC void
40 S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
41 {
42     MGS* mgs;
43     assert(SvMAGICAL(sv));
44
45     SAVEDESTRUCTOR_X(restore_magic, (void*)mgs_ix);
46
47     mgs = SSPTR(mgs_ix, MGS*);
48     mgs->mgs_sv = sv;
49     mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
50     mgs->mgs_ss_ix = PL_savestack_ix;   /* points after the saved destructor */
51
52     SvMAGICAL_off(sv);
53     SvREADONLY_off(sv);
54     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
55 }
56
57 /*
58 =for apidoc mg_magical
59
60 Turns on the magical status of an SV.  See C<sv_magic>.
61
62 =cut
63 */
64
65 void
66 Perl_mg_magical(pTHX_ SV *sv)
67 {
68     MAGIC* mg;
69     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
70         MGVTBL* vtbl = mg->mg_virtual;
71         if (vtbl) {
72             if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
73                 SvGMAGICAL_on(sv);
74             if (vtbl->svt_set)
75                 SvSMAGICAL_on(sv);
76             if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
77                 SvRMAGICAL_on(sv);
78         }
79     }
80 }
81
82 /*
83 =for apidoc mg_get
84
85 Do magic after a value is retrieved from the SV.  See C<sv_magic>.
86
87 =cut
88 */
89
90 int
91 Perl_mg_get(pTHX_ SV *sv)
92 {
93     I32 mgs_ix;
94     MAGIC* mg;
95     MAGIC** mgp;
96     int mgp_valid = 0;
97
98     mgs_ix = SSNEW(sizeof(MGS));
99     save_magic(mgs_ix, sv);
100
101     mgp = &SvMAGIC(sv);
102     while ((mg = *mgp) != 0) {
103         MGVTBL* vtbl = mg->mg_virtual;
104         if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
105             CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
106             /* Ignore this magic if it's been deleted */
107             if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
108                   (mg->mg_flags & MGf_GSKIP))
109                 (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
110         }
111         /* Advance to next magic (complicated by possible deletion) */
112         if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
113             mgp = &mg->mg_moremagic;
114             mgp_valid = 1;
115         }
116         else
117             mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
118     }
119
120     restore_magic(aTHXo_ (void*)mgs_ix);
121     return 0;
122 }
123
124 /*
125 =for apidoc mg_set
126
127 Do magic after a value is assigned to the SV.  See C<sv_magic>.
128
129 =cut
130 */
131
132 int
133 Perl_mg_set(pTHX_ SV *sv)
134 {
135     I32 mgs_ix;
136     MAGIC* mg;
137     MAGIC* nextmg;
138
139     mgs_ix = SSNEW(sizeof(MGS));
140     save_magic(mgs_ix, sv);
141
142     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
143         MGVTBL* vtbl = mg->mg_virtual;
144         nextmg = mg->mg_moremagic;      /* it may delete itself */
145         if (mg->mg_flags & MGf_GSKIP) {
146             mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
147             (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
148         }
149         if (vtbl && vtbl->svt_set)
150             CALL_FPTR(vtbl->svt_set)(aTHX_ sv, mg);
151     }
152
153     restore_magic(aTHXo_ (void*)mgs_ix);
154     return 0;
155 }
156
157 /*
158 =for apidoc mg_length
159
160 Report on the SV's length.  See C<sv_magic>.
161
162 =cut
163 */
164
165 U32
166 Perl_mg_length(pTHX_ SV *sv)
167 {
168     MAGIC* mg;
169     char *junk;
170     STRLEN len;
171
172     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
173         MGVTBL* vtbl = mg->mg_virtual;
174         if (vtbl && vtbl->svt_len) {
175             I32 mgs_ix;
176
177             mgs_ix = SSNEW(sizeof(MGS));
178             save_magic(mgs_ix, sv);
179             /* omit MGf_GSKIP -- not changed here */
180             len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
181             restore_magic(aTHXo_ (void*)mgs_ix);
182             return len;
183         }
184     }
185
186     junk = SvPV(sv, len);
187     return len;
188 }
189
190 I32
191 Perl_mg_size(pTHX_ SV *sv)
192 {
193     MAGIC* mg;
194     I32 len;
195
196     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
197         MGVTBL* vtbl = mg->mg_virtual;
198         if (vtbl && vtbl->svt_len) {
199             I32 mgs_ix;
200
201             mgs_ix = SSNEW(sizeof(MGS));
202             save_magic(mgs_ix, sv);
203             /* omit MGf_GSKIP -- not changed here */
204             len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
205             restore_magic(aTHXo_ (void*)mgs_ix);
206             return len;
207         }
208     }
209
210     switch(SvTYPE(sv)) {
211         case SVt_PVAV:
212             len = AvFILLp((AV *) sv); /* Fallback to non-tied array */
213             return len;
214         case SVt_PVHV:
215             /* FIXME */
216         default:
217             Perl_croak(aTHX_ "Size magic not implemented");
218             break;
219     }
220     return 0;
221 }
222
223 /*
224 =for apidoc mg_clear
225
226 Clear something magical that the SV represents.  See C<sv_magic>.
227
228 =cut
229 */
230
231 int
232 Perl_mg_clear(pTHX_ SV *sv)
233 {
234     I32 mgs_ix;
235     MAGIC* mg;
236
237     mgs_ix = SSNEW(sizeof(MGS));
238     save_magic(mgs_ix, sv);
239
240     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
241         MGVTBL* vtbl = mg->mg_virtual;
242         /* omit GSKIP -- never set here */
243         
244         if (vtbl && vtbl->svt_clear)
245             CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
246     }
247
248     restore_magic(aTHXo_ (void*)mgs_ix);
249     return 0;
250 }
251
252 /*
253 =for apidoc mg_find
254
255 Finds the magic pointer for type matching the SV.  See C<sv_magic>.
256
257 =cut
258 */
259
260 MAGIC*
261 Perl_mg_find(pTHX_ SV *sv, int type)
262 {
263     MAGIC* mg;
264     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
265         if (mg->mg_type == type)
266             return mg;
267     }
268     return 0;
269 }
270
271 /*
272 =for apidoc mg_copy
273
274 Copies the magic from one SV to another.  See C<sv_magic>.
275
276 =cut
277 */
278
279 int
280 Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
281 {
282     int count = 0;
283     MAGIC* mg;
284     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
285         if (isUPPER(mg->mg_type)) {
286             sv_magic(nsv,
287                      mg->mg_type == 'P' ? SvTIED_obj(sv, mg) :
288                      (mg->mg_type == 'D' && mg->mg_obj) ? sv : mg->mg_obj,
289                      toLOWER(mg->mg_type), key, klen);
290             count++;
291         }
292     }
293     return count;
294 }
295
296 /*
297 =for apidoc mg_free
298
299 Free any magic storage used by the SV.  See C<sv_magic>.
300
301 =cut
302 */
303
304 int
305 Perl_mg_free(pTHX_ SV *sv)
306 {
307     MAGIC* mg;
308     MAGIC* moremagic;
309     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
310         MGVTBL* vtbl = mg->mg_virtual;
311         moremagic = mg->mg_moremagic;
312         if (vtbl && vtbl->svt_free)
313             CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
314         if (mg->mg_ptr && mg->mg_type != 'g')
315             if (mg->mg_len >= 0)
316                 Safefree(mg->mg_ptr);
317             else if (mg->mg_len == HEf_SVKEY)
318                 SvREFCNT_dec((SV*)mg->mg_ptr);
319         if (mg->mg_flags & MGf_REFCOUNTED)
320             SvREFCNT_dec(mg->mg_obj);
321         Safefree(mg);
322     }
323     SvMAGIC(sv) = 0;
324     return 0;
325 }
326
327 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
328 #include <signal.h>
329 #endif
330
331 U32
332 Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
333 {
334     register REGEXP *rx;
335
336     if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
337         if (mg->mg_obj)         /* @+ */
338             return rx->nparens;
339         else                    /* @- */
340             return rx->lastparen;
341     }
342
343     return (U32)-1;
344 }
345
346 int
347 Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
348 {
349     register I32 paren;
350     register I32 s;
351     register I32 i;
352     register REGEXP *rx;
353     I32 t;
354
355     if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
356         paren = mg->mg_len;
357         if (paren < 0)
358             return 0;
359         if (paren <= rx->nparens &&
360             (s = rx->startp[paren]) != -1 &&
361             (t = rx->endp[paren]) != -1)
362             {
363                 if (mg->mg_obj)         /* @+ */
364                     i = t;
365                 else                    /* @- */
366                     i = s;
367                 sv_setiv(sv,i);
368             }
369     }
370     return 0;
371 }
372
373 int
374 Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
375 {
376     Perl_croak(aTHX_ PL_no_modify);
377     /* NOT REACHED */
378     return 0;
379 }
380
381 U32
382 Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
383 {
384     register I32 paren;
385     register I32 i;
386     register REGEXP *rx;
387     I32 s1, t1;
388
389     switch (*mg->mg_ptr) {
390     case '1': case '2': case '3': case '4':
391     case '5': case '6': case '7': case '8': case '9': case '&':
392         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
393
394             paren = atoi(mg->mg_ptr);
395           getparen:
396             if (paren <= rx->nparens &&
397                 (s1 = rx->startp[paren]) != -1 &&
398                 (t1 = rx->endp[paren]) != -1)
399             {
400                 i = t1 - s1;
401               getlen:
402                 if (i > 0 && (PL_curpm->op_pmdynflags & PMdf_UTF8) && !IN_BYTE) {
403                     char *s = rx->subbeg + s1;
404                     char *send = rx->subbeg + t1;
405                     i = 0;
406                     while (s < send) {
407                         s += UTF8SKIP(s);
408                         i++;
409                     }
410                 }
411                 if (i >= 0)
412                     return i;
413             }
414         }
415         return 0;
416     case '+':
417         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
418             paren = rx->lastparen;
419             if (paren)
420                 goto getparen;
421         }
422         return 0;
423     case '`':
424         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
425             if (rx->startp[0] != -1) {
426                 i = rx->startp[0];
427                 if (i > 0) {
428                     s1 = 0;
429                     t1 = i;
430                     goto getlen;
431                 }
432             }
433         }
434         return 0;
435     case '\'':
436         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
437             if (rx->endp[0] != -1) {
438                 i = rx->sublen - rx->endp[0];
439                 if (i > 0) {
440                     s1 = rx->endp[0];
441                     t1 = rx->sublen;
442                     goto getlen;
443                 }
444             }
445         }
446         return 0;
447     case ',':
448         return (STRLEN)PL_ofslen;
449     case '\\':
450         return (STRLEN)PL_orslen;
451     }
452     magic_get(sv,mg);
453     if (!SvPOK(sv) && SvNIOK(sv)) {
454         STRLEN n_a;
455         sv_2pv(sv, &n_a);
456     }
457     if (SvPOK(sv))
458         return SvCUR(sv);
459     return 0;
460 }
461
462 int
463 Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
464 {
465     register I32 paren;
466     register char *s;
467     register I32 i;
468     register REGEXP *rx;
469
470     switch (*mg->mg_ptr) {
471     case '\001':                /* ^A */
472         sv_setsv(sv, PL_bodytarget);
473         break;
474     case '\003':                /* ^C */
475         sv_setiv(sv, (IV)PL_minus_c);
476         break;
477
478     case '\004':                /* ^D */
479         sv_setiv(sv, (IV)(PL_debug & 32767));
480 #if defined(YYDEBUG) && defined(DEBUGGING)
481         PL_yydebug = (PL_debug & 1);
482 #endif
483         break;
484     case '\005':  /* ^E */
485 #ifdef MACOS_TRADITIONAL
486         {
487             char msg[256];
488         
489             sv_setnv(sv,(double)gMacPerl_OSErr);
490             sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : "");     
491         }
492 #else   
493 #ifdef VMS
494         {
495 #           include <descrip.h>
496 #           include <starlet.h>
497             char msg[255];
498             $DESCRIPTOR(msgdsc,msg);
499             sv_setnv(sv,(NV) vaxc$errno);
500             if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
501                 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
502             else
503                 sv_setpv(sv,"");
504         }
505 #else
506 #ifdef OS2
507         if (!(_emx_env & 0x200)) {      /* Under DOS */
508             sv_setnv(sv, (NV)errno);
509             sv_setpv(sv, errno ? Strerror(errno) : "");
510         } else {
511             if (errno != errno_isOS2) {
512                 int tmp = _syserrno();
513                 if (tmp)        /* 2nd call to _syserrno() makes it 0 */
514                     Perl_rc = tmp;
515             }
516             sv_setnv(sv, (NV)Perl_rc);
517             sv_setpv(sv, os2error(Perl_rc));
518         }
519 #else
520 #ifdef WIN32
521         {
522             DWORD dwErr = GetLastError();
523             sv_setnv(sv, (NV)dwErr);
524             if (dwErr)
525             {
526                 PerlProc_GetOSError(sv, dwErr);
527             }
528             else
529                 sv_setpv(sv, "");
530             SetLastError(dwErr);
531         }
532 #else
533         sv_setnv(sv, (NV)errno);
534         sv_setpv(sv, errno ? Strerror(errno) : "");
535 #endif
536 #endif
537 #endif
538 #endif
539         SvNOK_on(sv);   /* what a wonderful hack! */
540         break;
541     case '\006':                /* ^F */
542         sv_setiv(sv, (IV)PL_maxsysfd);
543         break;
544     case '\010':                /* ^H */
545         sv_setiv(sv, (IV)PL_hints);
546         break;
547     case '\011':                /* ^I */ /* NOT \t in EBCDIC */
548         if (PL_inplace)
549             sv_setpv(sv, PL_inplace);
550         else
551             sv_setsv(sv, &PL_sv_undef);
552         break;
553     case '\017':                /* ^O & ^OPEN */
554         if (*(mg->mg_ptr+1) == '\0')
555             sv_setpv(sv, PL_osname);
556         else if (strEQ(mg->mg_ptr, "\017PEN")) {
557             if (!PL_compiling.cop_io)
558                 sv_setsv(sv, &PL_sv_undef);
559             else {
560                 sv_setsv(sv, PL_compiling.cop_io);
561             }
562         }
563         break;
564     case '\020':                /* ^P */
565         sv_setiv(sv, (IV)PL_perldb);
566         break;
567     case '\023':                /* ^S */
568         {
569             if (PL_lex_state != LEX_NOTPARSING)
570                 (void)SvOK_off(sv);
571             else if (PL_in_eval)
572                 sv_setiv(sv, PL_in_eval & ~(EVAL_INREQUIRE));
573         }
574         break;
575     case '\024':                /* ^T */
576 #ifdef BIG_TIME
577         sv_setnv(sv, PL_basetime);
578 #else
579         sv_setiv(sv, (IV)PL_basetime);
580 #endif
581         break;
582     case '\027':                /* ^W  & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */
583         if (*(mg->mg_ptr+1) == '\0')
584             sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE));
585         else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) {
586             if (PL_compiling.cop_warnings == pWARN_NONE ||
587                 PL_compiling.cop_warnings == pWARN_STD)
588             {
589                 sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
590             }
591             else if (PL_compiling.cop_warnings == pWARN_ALL) {
592                 sv_setpvn(sv, WARN_ALLstring, WARNsize) ;
593             }
594             else {
595                 sv_setsv(sv, PL_compiling.cop_warnings);
596             }
597             SvPOK_only(sv);
598         }
599         else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS"))
600             sv_setiv(sv, (IV)PL_widesyscalls);
601         break;
602     case '1': case '2': case '3': case '4':
603     case '5': case '6': case '7': case '8': case '9': case '&':
604         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
605             I32 s1, t1;
606
607             /*
608              * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
609              * XXX Does the new way break anything?
610              */
611             paren = atoi(mg->mg_ptr);
612           getparen:
613             if (paren <= rx->nparens &&
614                 (s1 = rx->startp[paren]) != -1 &&
615                 (t1 = rx->endp[paren]) != -1)
616             {
617                 i = t1 - s1;
618                 s = rx->subbeg + s1;
619                 if (!rx->subbeg)
620                     break;
621
622               getrx:
623                 if (i >= 0) {
624                     bool was_tainted;
625                     if (PL_tainting) {
626                         was_tainted = PL_tainted;
627                         PL_tainted = FALSE;
628                     }
629                     sv_setpvn(sv, s, i);
630                     if ((PL_curpm->op_pmdynflags & PMdf_UTF8) && !IN_BYTE)
631                         SvUTF8_on(sv);
632                     else
633                         SvUTF8_off(sv);
634                     if (PL_tainting)
635                         PL_tainted = (was_tainted || RX_MATCH_TAINTED(rx));
636                     break;
637                 }
638             }
639         }
640         sv_setsv(sv,&PL_sv_undef);
641         break;
642     case '+':
643         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
644             paren = rx->lastparen;
645             if (paren)
646                 goto getparen;
647         }
648         sv_setsv(sv,&PL_sv_undef);
649         break;
650     case '`':
651         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
652             if ((s = rx->subbeg) && rx->startp[0] != -1) {
653                 i = rx->startp[0];
654                 goto getrx;
655             }
656         }
657         sv_setsv(sv,&PL_sv_undef);
658         break;
659     case '\'':
660         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
661             if (rx->subbeg && rx->endp[0] != -1) {
662                 s = rx->subbeg + rx->endp[0];
663                 i = rx->sublen - rx->endp[0];
664                 goto getrx;
665             }
666         }
667         sv_setsv(sv,&PL_sv_undef);
668         break;
669     case '.':
670 #ifndef lint
671         if (GvIO(PL_last_in_gv)) {
672             sv_setiv(sv, (IV)IoLINES(GvIO(PL_last_in_gv)));
673         }
674 #endif
675         break;
676     case '?':
677         {
678             sv_setiv(sv, (IV)STATUS_CURRENT);
679 #ifdef COMPLEX_STATUS
680             LvTARGOFF(sv) = PL_statusvalue;
681             LvTARGLEN(sv) = PL_statusvalue_vms;
682 #endif
683         }
684         break;
685     case '^':
686         s = IoTOP_NAME(GvIOp(PL_defoutgv));
687         if (s)
688             sv_setpv(sv,s);
689         else {
690             sv_setpv(sv,GvENAME(PL_defoutgv));
691             sv_catpv(sv,"_TOP");
692         }
693         break;
694     case '~':
695         s = IoFMT_NAME(GvIOp(PL_defoutgv));
696         if (!s)
697             s = GvENAME(PL_defoutgv);
698         sv_setpv(sv,s);
699         break;
700 #ifndef lint
701     case '=':
702         sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
703         break;
704     case '-':
705         sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
706         break;
707     case '%':
708         sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
709         break;
710 #endif
711     case ':':
712         break;
713     case '/':
714         break;
715     case '[':
716         WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
717         break;
718     case '|':
719         sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
720         break;
721     case ',':
722         sv_setpvn(sv,PL_ofs,PL_ofslen);
723         break;
724     case '\\':
725         sv_setpvn(sv,PL_ors,PL_orslen);
726         break;
727     case '#':
728         sv_setpv(sv,PL_ofmt);
729         break;
730     case '!':
731 #ifdef VMS
732         sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
733         sv_setpv(sv, errno ? Strerror(errno) : "");
734 #else
735         {
736         int saveerrno = errno;
737         sv_setnv(sv, (NV)errno);
738 #ifdef OS2
739         if (errno == errno_isOS2 || errno == errno_isOS2_set)
740             sv_setpv(sv, os2error(Perl_rc));
741         else
742 #endif
743         sv_setpv(sv, errno ? Strerror(errno) : "");
744         errno = saveerrno;
745         }
746 #endif
747         SvNOK_on(sv);   /* what a wonderful hack! */
748         break;
749     case '<':
750         sv_setiv(sv, (IV)PL_uid);
751         break;
752     case '>':
753         sv_setiv(sv, (IV)PL_euid);
754         break;
755     case '(':
756         sv_setiv(sv, (IV)PL_gid);
757 #ifdef HAS_GETGROUPS
758         Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_gid);
759 #endif
760         goto add_groups;
761     case ')':
762         sv_setiv(sv, (IV)PL_egid);
763 #ifdef HAS_GETGROUPS
764         Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_egid);
765 #endif
766       add_groups:
767 #ifdef HAS_GETGROUPS
768         {
769             Groups_t gary[NGROUPS];
770             i = getgroups(NGROUPS,gary);
771             while (--i >= 0)
772                 Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]);
773         }
774 #endif
775         (void)SvIOK_on(sv);     /* what a wonderful hack! */
776         break;
777     case '*':
778         break;
779 #ifndef MACOS_TRADITIONAL
780     case '0':
781         break;
782 #endif
783 #ifdef USE_THREADS
784     case '@':
785         sv_setsv(sv, thr->errsv);
786         break;
787 #endif /* USE_THREADS */
788     }
789     return 0;
790 }
791
792 int
793 Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
794 {
795     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
796
797     if (uf && uf->uf_val)
798         (*uf->uf_val)(uf->uf_index, sv);
799     return 0;
800 }
801
802 int
803 Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
804 {
805     register char *s;
806     char *ptr;
807     STRLEN len, klen;
808     I32 i;
809
810     s = SvPV(sv,len);
811     ptr = MgPV(mg,klen);
812     my_setenv(ptr, s);
813
814 #ifdef DYNAMIC_ENV_FETCH
815      /* We just undefd an environment var.  Is a replacement */
816      /* waiting in the wings? */
817     if (!len) {
818         SV **valp;
819         if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
820             s = SvPV(*valp, len);
821     }
822 #endif
823
824 #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
825                             /* And you'll never guess what the dog had */
826                             /*   in its mouth... */
827     if (PL_tainting) {
828         MgTAINTEDDIR_off(mg);
829 #ifdef VMS
830         if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
831             char pathbuf[256], eltbuf[256], *cp, *elt = s;
832             struct stat sbuf;
833             int i = 0, j = 0;
834
835             do {          /* DCL$PATH may be a search list */
836                 while (1) {   /* as may dev portion of any element */
837                     if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
838                         if ( *(cp+1) == '.' || *(cp+1) == '-' ||
839                              cando_by_name(S_IWUSR,0,elt) ) {
840                             MgTAINTEDDIR_on(mg);
841                             return 0;
842                         }
843                     }
844                     if ((cp = strchr(elt, ':')) != Nullch)
845                         *cp = '\0';
846                     if (my_trnlnm(elt, eltbuf, j++))
847                         elt = eltbuf;
848                     else
849                         break;
850                 }
851                 j = 0;
852             } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
853         }
854 #endif /* VMS */
855         if (s && klen == 4 && strEQ(ptr,"PATH")) {
856             char *strend = s + len;
857
858             while (s < strend) {
859                 char tmpbuf[256];
860                 struct stat st;
861                 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
862                              s, strend, ':', &i);
863                 s++;
864                 if (i >= sizeof tmpbuf   /* too long -- assume the worst */
865                       || *tmpbuf != '/'
866                       || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
867                     MgTAINTEDDIR_on(mg);
868                     return 0;
869                 }
870             }
871         }
872     }
873 #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
874
875     return 0;
876 }
877
878 int
879 Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
880 {
881     STRLEN n_a;
882     my_setenv(MgPV(mg,n_a),Nullch);
883     return 0;
884 }
885
886 int
887 Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
888 {
889 #if defined(VMS)
890     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
891 #else
892     if (PL_localizing) {
893         HE* entry;
894         STRLEN n_a;
895         magic_clear_all_env(sv,mg);
896         hv_iterinit((HV*)sv);
897         while ((entry = hv_iternext((HV*)sv))) {
898             I32 keylen;
899             my_setenv(hv_iterkey(entry, &keylen),
900                       SvPV(hv_iterval((HV*)sv, entry), n_a));
901         }
902     }
903 #endif
904     return 0;
905 }
906
907 int
908 Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
909 {
910 #if defined(VMS) || defined(EPOC)
911     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
912 #else
913 #   ifdef PERL_IMPLICIT_SYS
914     PerlEnv_clearenv();
915 #   else
916 #       ifdef WIN32
917     char *envv = GetEnvironmentStrings();
918     char *cur = envv;
919     STRLEN len;
920     while (*cur) {
921         char *end = strchr(cur,'=');
922         if (end && end != cur) {
923             *end = '\0';
924             my_setenv(cur,Nullch);
925             *end = '=';
926             cur = end + strlen(end+1)+2;
927         }
928         else if ((len = strlen(cur)))
929             cur += len+1;
930     }
931     FreeEnvironmentStrings(envv);
932 #       else
933 #           ifndef PERL_USE_SAFE_PUTENV
934     I32 i;
935
936     if (environ == PL_origenviron)
937         environ = (char**)safesysmalloc(sizeof(char*));
938     else
939         for (i = 0; environ[i]; i++)
940             safesysfree(environ[i]);
941 #           endif /* PERL_USE_SAFE_PUTENV */
942
943     environ[0] = Nullch;
944
945 #       endif /* WIN32 */
946 #   endif /* PERL_IMPLICIT_SYS */
947 #endif /* VMS */
948     return 0;
949 }
950
951 #ifndef PERL_MICRO
952 int
953 Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
954 {
955     I32 i;
956     STRLEN n_a;
957     /* Are we fetching a signal entry? */
958     i = whichsig(MgPV(mg,n_a));
959     if (i) {
960         if(PL_psig_ptr[i])
961             sv_setsv(sv,PL_psig_ptr[i]);
962         else {
963             Sighandler_t sigstate = rsignal_state(i);
964
965             /* cache state so we don't fetch it again */
966             if(sigstate == SIG_IGN)
967                 sv_setpv(sv,"IGNORE");
968             else
969                 sv_setsv(sv,&PL_sv_undef);
970             PL_psig_ptr[i] = SvREFCNT_inc(sv);
971             SvTEMP_off(sv);
972         }
973     }
974     return 0;
975 }
976 int
977 Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
978 {
979     I32 i;
980     STRLEN n_a;
981     /* Are we clearing a signal entry? */
982     i = whichsig(MgPV(mg,n_a));
983     if (i) {
984         if(PL_psig_ptr[i]) {
985             SvREFCNT_dec(PL_psig_ptr[i]);
986             PL_psig_ptr[i]=0;
987         }
988         if(PL_psig_name[i]) {
989             SvREFCNT_dec(PL_psig_name[i]);
990             PL_psig_name[i]=0;
991         }
992     }
993     return 0;
994 }
995
996 int
997 Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
998 {
999     register char *s;
1000     I32 i;
1001     SV** svp;
1002     STRLEN len;
1003
1004     s = MgPV(mg,len);
1005     if (*s == '_') {
1006         if (strEQ(s,"__DIE__"))
1007             svp = &PL_diehook;
1008         else if (strEQ(s,"__WARN__"))
1009             svp = &PL_warnhook;
1010         else
1011             Perl_croak(aTHX_ "No such hook: %s", s);
1012         i = 0;
1013         if (*svp) {
1014             SvREFCNT_dec(*svp);
1015             *svp = 0;
1016         }
1017     }
1018     else {
1019         i = whichsig(s);        /* ...no, a brick */
1020         if (!i) {
1021             if (ckWARN(WARN_SIGNAL))
1022                 Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s);
1023             return 0;
1024         }
1025         SvREFCNT_dec(PL_psig_name[i]);
1026         SvREFCNT_dec(PL_psig_ptr[i]);
1027         PL_psig_ptr[i] = SvREFCNT_inc(sv);
1028         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
1029         PL_psig_name[i] = newSVpvn(s, len);
1030         SvREADONLY_on(PL_psig_name[i]);
1031     }
1032     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
1033         if (i)
1034             (void)rsignal(i, PL_sighandlerp);
1035         else
1036             *svp = SvREFCNT_inc(sv);
1037         return 0;
1038     }
1039     s = SvPV_force(sv,len);
1040     if (strEQ(s,"IGNORE")) {
1041         if (i)
1042             (void)rsignal(i, SIG_IGN);
1043         else
1044             *svp = 0;
1045     }
1046     else if (strEQ(s,"DEFAULT") || !*s) {
1047         if (i)
1048             (void)rsignal(i, SIG_DFL);
1049         else
1050             *svp = 0;
1051     }
1052     else {
1053         /*
1054          * We should warn if HINT_STRICT_REFS, but without
1055          * access to a known hint bit in a known OP, we can't
1056          * tell whether HINT_STRICT_REFS is in force or not.
1057          */
1058         if (!strchr(s,':') && !strchr(s,'\''))
1059             sv_insert(sv, 0, 0, "main::", 6);
1060         if (i)
1061             (void)rsignal(i, PL_sighandlerp);
1062         else
1063             *svp = SvREFCNT_inc(sv);
1064     }
1065     return 0;
1066 }
1067 #endif /* !PERL_MICRO */
1068
1069 int
1070 Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
1071 {
1072     PL_sub_generation++;
1073     return 0;
1074 }
1075
1076 int
1077 Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
1078 {
1079     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
1080     PL_amagic_generation++;
1081
1082     return 0;
1083 }
1084
1085 int
1086 Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
1087 {
1088     HV *hv = (HV*)LvTARG(sv);
1089     HE *entry;
1090     I32 i = 0;
1091
1092     if (hv) {
1093         (void) hv_iterinit(hv);
1094         if (! SvTIED_mg((SV*)hv, 'P'))
1095             i = HvKEYS(hv);
1096         else {
1097             /*SUPPRESS 560*/
1098             while ((entry = hv_iternext(hv))) {
1099                 i++;
1100             }
1101         }
1102     }
1103
1104     sv_setiv(sv, (IV)i);
1105     return 0;
1106 }
1107
1108 int
1109 Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
1110 {
1111     if (LvTARG(sv)) {
1112         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
1113     }
1114     return 0;
1115 }
1116
1117 /* caller is responsible for stack switching/cleanup */
1118 STATIC int
1119 S_magic_methcall(pTHX_ SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
1120 {
1121     dSP;
1122
1123     PUSHMARK(SP);
1124     EXTEND(SP, n);
1125     PUSHs(SvTIED_obj(sv, mg));
1126     if (n > 1) {
1127         if (mg->mg_ptr) {
1128             if (mg->mg_len >= 0)
1129                 PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
1130             else if (mg->mg_len == HEf_SVKEY)
1131                 PUSHs((SV*)mg->mg_ptr);
1132         }
1133         else if (mg->mg_type == 'p') {
1134             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
1135         }
1136     }
1137     if (n > 2) {
1138         PUSHs(val);
1139     }
1140     PUTBACK;
1141
1142     return call_method(meth, flags);
1143 }
1144
1145 STATIC int
1146 S_magic_methpack(pTHX_ SV *sv, MAGIC *mg, char *meth)
1147 {
1148     dSP;
1149
1150     ENTER;
1151     SAVETMPS;
1152     PUSHSTACKi(PERLSI_MAGIC);
1153
1154     if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
1155         sv_setsv(sv, *PL_stack_sp--);
1156     }
1157
1158     POPSTACK;
1159     FREETMPS;
1160     LEAVE;
1161     return 0;
1162 }
1163
1164 int
1165 Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
1166 {
1167     magic_methpack(sv,mg,"FETCH");
1168     if (mg->mg_ptr)
1169         mg->mg_flags |= MGf_GSKIP;
1170     return 0;
1171 }
1172
1173 int
1174 Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
1175 {
1176     dSP;
1177     ENTER;
1178     PUSHSTACKi(PERLSI_MAGIC);
1179     magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1180     POPSTACK;
1181     LEAVE;
1182     return 0;
1183 }
1184
1185 int
1186 Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
1187 {
1188     return magic_methpack(sv,mg,"DELETE");
1189 }
1190
1191
1192 U32
1193 Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
1194 {
1195     dSP;
1196     U32 retval = 0;
1197
1198     ENTER;
1199     SAVETMPS;
1200     PUSHSTACKi(PERLSI_MAGIC);
1201     if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1202         sv = *PL_stack_sp--;
1203         retval = (U32) SvIV(sv)-1;
1204     }
1205     POPSTACK;
1206     FREETMPS;
1207     LEAVE;
1208     return retval;
1209 }
1210
1211 int
1212 Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
1213 {
1214     dSP;
1215
1216     ENTER;
1217     PUSHSTACKi(PERLSI_MAGIC);
1218     PUSHMARK(SP);
1219     XPUSHs(SvTIED_obj(sv, mg));
1220     PUTBACK;
1221     call_method("CLEAR", G_SCALAR|G_DISCARD);
1222     POPSTACK;
1223     LEAVE;
1224     return 0;
1225 }
1226
1227 int
1228 Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
1229 {
1230     dSP;
1231     const char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1232
1233     ENTER;
1234     SAVETMPS;
1235     PUSHSTACKi(PERLSI_MAGIC);
1236     PUSHMARK(SP);
1237     EXTEND(SP, 2);
1238     PUSHs(SvTIED_obj(sv, mg));
1239     if (SvOK(key))
1240         PUSHs(key);
1241     PUTBACK;
1242
1243     if (call_method(meth, G_SCALAR))
1244         sv_setsv(key, *PL_stack_sp--);
1245
1246     POPSTACK;
1247     FREETMPS;
1248     LEAVE;
1249     return 0;
1250 }
1251
1252 int
1253 Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
1254 {
1255     return magic_methpack(sv,mg,"EXISTS");
1256 }
1257
1258 int
1259 Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
1260 {
1261     OP *o;
1262     I32 i;
1263     GV* gv;
1264     SV** svp;
1265     STRLEN n_a;
1266
1267     gv = PL_DBline;
1268     i = SvTRUE(sv);
1269     svp = av_fetch(GvAV(gv),
1270                      atoi(MgPV(mg,n_a)), FALSE);
1271     if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp))))
1272         o->op_private = i;
1273     return 0;
1274 }
1275
1276 int
1277 Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
1278 {
1279     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
1280     return 0;
1281 }
1282
1283 int
1284 Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
1285 {
1286     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
1287     return 0;
1288 }
1289
1290 int
1291 Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
1292 {
1293     SV* lsv = LvTARG(sv);
1294
1295     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1296         mg = mg_find(lsv, 'g');
1297         if (mg && mg->mg_len >= 0) {
1298             I32 i = mg->mg_len;
1299             if (DO_UTF8(lsv))
1300                 sv_pos_b2u(lsv, &i);
1301             sv_setiv(sv, i + PL_curcop->cop_arybase);
1302             return 0;
1303         }
1304     }
1305     (void)SvOK_off(sv);
1306     return 0;
1307 }
1308
1309 int
1310 Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
1311 {
1312     SV* lsv = LvTARG(sv);
1313     SSize_t pos;
1314     STRLEN len;
1315     STRLEN ulen = 0;
1316
1317     mg = 0;
1318
1319     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1320         mg = mg_find(lsv, 'g');
1321     if (!mg) {
1322         if (!SvOK(sv))
1323             return 0;
1324         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1325         mg = mg_find(lsv, 'g');
1326     }
1327     else if (!SvOK(sv)) {
1328         mg->mg_len = -1;
1329         return 0;
1330     }
1331     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1332
1333     pos = SvIV(sv) - PL_curcop->cop_arybase;
1334
1335     if (DO_UTF8(lsv)) {
1336         ulen = sv_len_utf8(lsv);
1337         if (ulen)
1338             len = ulen;
1339     }
1340
1341     if (pos < 0) {
1342         pos += len;
1343         if (pos < 0)
1344             pos = 0;
1345     }
1346     else if (pos > len)
1347         pos = len;
1348
1349     if (ulen) {
1350         I32 p = pos;
1351         sv_pos_u2b(lsv, &p, 0);
1352         pos = p;
1353     }
1354         
1355     mg->mg_len = pos;
1356     mg->mg_flags &= ~MGf_MINMATCH;
1357
1358     return 0;
1359 }
1360
1361 int
1362 Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
1363 {
1364     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1365         SvFAKE_off(sv);
1366         gv_efullname3(sv,((GV*)sv), "*");
1367         SvFAKE_on(sv);
1368     }
1369     else
1370         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1371     return 0;
1372 }
1373
1374 int
1375 Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
1376 {
1377     register char *s;
1378     GV* gv;
1379     STRLEN n_a;
1380
1381     if (!SvOK(sv))
1382         return 0;
1383     s = SvPV(sv, n_a);
1384     if (*s == '*' && s[1])
1385         s++;
1386     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1387     if (sv == (SV*)gv)
1388         return 0;
1389     if (GvGP(sv))
1390         gp_free((GV*)sv);
1391     GvGP(sv) = gp_ref(GvGP(gv));
1392     return 0;
1393 }
1394
1395 int
1396 Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
1397 {
1398     STRLEN len;
1399     SV *lsv = LvTARG(sv);
1400     char *tmps = SvPV(lsv,len);
1401     I32 offs = LvTARGOFF(sv);
1402     I32 rem = LvTARGLEN(sv);
1403
1404     if (offs > len)
1405         offs = len;
1406     if (rem + offs > len)
1407         rem = len - offs;
1408     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
1409     if (DO_UTF8(lsv))
1410         SvUTF8_on(sv);
1411     return 0;
1412 }
1413
1414 int
1415 Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
1416 {
1417     STRLEN len;
1418     char *tmps = SvPV(sv,len);
1419     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1420     return 0;
1421 }
1422
1423 int
1424 Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
1425 {
1426     TAINT_IF((mg->mg_len & 1) ||
1427              ((mg->mg_len & 2) && mg->mg_obj == sv));   /* kludge */
1428     return 0;
1429 }
1430
1431 int
1432 Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
1433 {
1434     if (PL_localizing) {
1435         if (PL_localizing == 1)
1436             mg->mg_len <<= 1;
1437         else
1438             mg->mg_len >>= 1;
1439     }
1440     else if (PL_tainted)
1441         mg->mg_len |= 1;
1442     else
1443         mg->mg_len &= ~1;
1444     return 0;
1445 }
1446
1447 int
1448 Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
1449 {
1450     SV *lsv = LvTARG(sv);
1451
1452     if (!lsv) {
1453         (void)SvOK_off(sv);
1454         return 0;
1455     }
1456
1457     sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
1458     return 0;
1459 }
1460
1461 int
1462 Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
1463 {
1464     do_vecset(sv);      /* XXX slurp this routine */
1465     return 0;
1466 }
1467
1468 int
1469 Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
1470 {
1471     SV *targ = Nullsv;
1472     if (LvTARGLEN(sv)) {
1473         if (mg->mg_obj) {
1474             SV *ahv = LvTARG(sv);
1475             if (SvTYPE(ahv) == SVt_PVHV) {
1476                 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1477                 if (he)
1478                     targ = HeVAL(he);
1479             }
1480             else {
1481                 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1482                 if (svp)
1483                     targ = *svp;
1484             }
1485         }
1486         else {
1487             AV* av = (AV*)LvTARG(sv);
1488             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1489                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1490         }
1491         if (targ && targ != &PL_sv_undef) {
1492             /* somebody else defined it for us */
1493             SvREFCNT_dec(LvTARG(sv));
1494             LvTARG(sv) = SvREFCNT_inc(targ);
1495             LvTARGLEN(sv) = 0;
1496             SvREFCNT_dec(mg->mg_obj);
1497             mg->mg_obj = Nullsv;
1498             mg->mg_flags &= ~MGf_REFCOUNTED;
1499         }
1500     }
1501     else
1502         targ = LvTARG(sv);
1503     sv_setsv(sv, targ ? targ : &PL_sv_undef);
1504     return 0;
1505 }
1506
1507 int
1508 Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
1509 {
1510     if (LvTARGLEN(sv))
1511         vivify_defelem(sv);
1512     if (LvTARG(sv)) {
1513         sv_setsv(LvTARG(sv), sv);
1514         SvSETMAGIC(LvTARG(sv));
1515     }
1516     return 0;
1517 }
1518
1519 void
1520 Perl_vivify_defelem(pTHX_ SV *sv)
1521 {
1522     MAGIC *mg;
1523     SV *value = Nullsv;
1524
1525     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
1526         return;
1527     if (mg->mg_obj) {
1528         SV *ahv = LvTARG(sv);
1529         STRLEN n_a;
1530         if (SvTYPE(ahv) == SVt_PVHV) {
1531             HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
1532             if (he)
1533                 value = HeVAL(he);
1534         }
1535         else {
1536             SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, TRUE, 0);
1537             if (svp)
1538                 value = *svp;
1539         }
1540         if (!value || value == &PL_sv_undef)
1541             Perl_croak(aTHX_ PL_no_helem, SvPV(mg->mg_obj, n_a));
1542     }
1543     else {
1544         AV* av = (AV*)LvTARG(sv);
1545         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1546             LvTARG(sv) = Nullsv;        /* array can't be extended */
1547         else {
1548             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1549             if (!svp || (value = *svp) == &PL_sv_undef)
1550                 Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
1551         }
1552     }
1553     (void)SvREFCNT_inc(value);
1554     SvREFCNT_dec(LvTARG(sv));
1555     LvTARG(sv) = value;
1556     LvTARGLEN(sv) = 0;
1557     SvREFCNT_dec(mg->mg_obj);
1558     mg->mg_obj = Nullsv;
1559     mg->mg_flags &= ~MGf_REFCOUNTED;
1560 }
1561
1562 int
1563 Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
1564 {
1565     AV *av = (AV*)mg->mg_obj;
1566     SV **svp = AvARRAY(av);
1567     I32 i = AvFILLp(av);
1568     while (i >= 0) {
1569         if (svp[i] && svp[i] != &PL_sv_undef) {
1570             if (!SvWEAKREF(svp[i]))
1571                 Perl_croak(aTHX_ "panic: magic_killbackrefs");
1572             /* XXX Should we check that it hasn't changed? */
1573             SvRV(svp[i]) = 0;
1574             (void)SvOK_off(svp[i]);
1575             SvWEAKREF_off(svp[i]);
1576             svp[i] = &PL_sv_undef;
1577         }
1578         i--;
1579     }
1580     return 0;
1581 }
1582
1583 int
1584 Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
1585 {
1586     mg->mg_len = -1;
1587     SvSCREAM_off(sv);
1588     return 0;
1589 }
1590
1591 int
1592 Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
1593 {
1594     sv_unmagic(sv, 'B');
1595     SvVALID_off(sv);
1596     return 0;
1597 }
1598
1599 int
1600 Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
1601 {
1602     sv_unmagic(sv, 'f');
1603     SvCOMPILED_off(sv);
1604     return 0;
1605 }
1606
1607 int
1608 Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
1609 {
1610     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1611
1612     if (uf && uf->uf_set)
1613         (*uf->uf_set)(uf->uf_index, sv);
1614     return 0;
1615 }
1616
1617 int
1618 Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
1619 {
1620     regexp *re = (regexp *)mg->mg_obj;
1621     ReREFCNT_dec(re);
1622     return 0;
1623 }
1624
1625 #ifdef USE_LOCALE_COLLATE
1626 int
1627 Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
1628 {
1629     /*
1630      * RenE<eacute> Descartes said "I think not."
1631      * and vanished with a faint plop.
1632      */
1633     if (mg->mg_ptr) {
1634         Safefree(mg->mg_ptr);
1635         mg->mg_ptr = NULL;
1636         mg->mg_len = -1;
1637     }
1638     return 0;
1639 }
1640 #endif /* USE_LOCALE_COLLATE */
1641
1642 int
1643 Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
1644 {
1645     register char *s;
1646     I32 i;
1647     STRLEN len;
1648     switch (*mg->mg_ptr) {
1649     case '\001':        /* ^A */
1650         sv_setsv(PL_bodytarget, sv);
1651         break;
1652     case '\003':        /* ^C */
1653         PL_minus_c = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1654         break;
1655
1656     case '\004':        /* ^D */
1657         PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1658         DEBUG_x(dump_all());
1659         break;
1660     case '\005':  /* ^E */
1661 #ifdef MACOS_TRADITIONAL
1662         gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1663 #else
1664 #  ifdef VMS
1665         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1666 #  else
1667 #    ifdef WIN32
1668         SetLastError( SvIV(sv) );
1669 #    else
1670 #      ifndef OS2
1671         /* will anyone ever use this? */
1672         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1673 #      endif
1674 #    endif
1675 #  endif
1676 #endif
1677         break;
1678     case '\006':        /* ^F */
1679         PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1680         break;
1681     case '\010':        /* ^H */
1682         PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1683         break;
1684     case '\011':        /* ^I */ /* NOT \t in EBCDIC */
1685         if (PL_inplace)
1686             Safefree(PL_inplace);
1687         if (SvOK(sv))
1688             PL_inplace = savepv(SvPV(sv,len));
1689         else
1690             PL_inplace = Nullch;
1691         break;
1692     case '\017':        /* ^O */
1693         if (*(mg->mg_ptr+1) == '\0') {
1694             if (PL_osname)
1695                 Safefree(PL_osname);
1696             if (SvOK(sv))
1697                 PL_osname = savepv(SvPV(sv,len));
1698             else
1699                 PL_osname = Nullch;
1700         }
1701         else if (strEQ(mg->mg_ptr, "\017PEN")) {
1702             if (!PL_compiling.cop_io)
1703                 PL_compiling.cop_io = newSVsv(sv);
1704             else
1705                 sv_setsv(PL_compiling.cop_io,sv);
1706         }
1707         break;
1708     case '\020':        /* ^P */
1709         PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1710         if (PL_perldb && !PL_DBsingle)
1711             init_debugger();
1712         break;
1713     case '\024':        /* ^T */
1714 #ifdef BIG_TIME
1715         PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1716 #else
1717         PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1718 #endif
1719         break;
1720     case '\027':        /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */
1721         if (*(mg->mg_ptr+1) == '\0') {
1722             if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
1723                 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1724                 PL_dowarn = (PL_dowarn & ~G_WARN_ON)
1725                                 | (i ? G_WARN_ON : G_WARN_OFF) ;
1726             }
1727         }
1728         else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) {
1729             if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
1730                 if (!SvPOK(sv) && PL_localizing) {
1731                     sv_setpvn(sv, WARN_NONEstring, WARNsize);
1732                     PL_compiling.cop_warnings = pWARN_NONE;
1733                     break;
1734                 }
1735                 {
1736                     STRLEN len, i;
1737                     int accumulate = 0 ;
1738                     int any_fatals = 0 ;
1739                     char * ptr = (char*)SvPV(sv, len) ;
1740                     for (i = 0 ; i < len ; ++i) {
1741                         accumulate |= ptr[i] ;
1742                         any_fatals |= (ptr[i] & 0xAA) ;
1743                     }
1744                     if (!accumulate)
1745                         PL_compiling.cop_warnings = pWARN_NONE;
1746                     else if (isWARN_on(sv, WARN_ALL) && !any_fatals) {
1747                         PL_compiling.cop_warnings = pWARN_ALL;
1748                         PL_dowarn |= G_WARN_ONCE ;
1749                     }   
1750                     else {
1751                         if (specialWARN(PL_compiling.cop_warnings))
1752                             PL_compiling.cop_warnings = newSVsv(sv) ;
1753                         else
1754                             sv_setsv(PL_compiling.cop_warnings, sv);
1755                         if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
1756                             PL_dowarn |= G_WARN_ONCE ;
1757                     }
1758
1759                 }
1760             }
1761         }
1762         else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS"))
1763             PL_widesyscalls = SvTRUE(sv);
1764         break;
1765     case '.':
1766         if (PL_localizing) {
1767             if (PL_localizing == 1)
1768                 SAVESPTR(PL_last_in_gv);
1769         }
1770         else if (SvOK(sv) && GvIO(PL_last_in_gv))
1771             IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv);
1772         break;
1773     case '^':
1774         Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
1775         IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
1776         IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1777         break;
1778     case '~':
1779         Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
1780         IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
1781         IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1782         break;
1783     case '=':
1784         IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1785         break;
1786     case '-':
1787         IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1788         if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
1789             IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
1790         break;
1791     case '%':
1792         IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1793         break;
1794     case '|':
1795         {
1796             IO *io = GvIOp(PL_defoutgv);
1797             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1798                 IoFLAGS(io) &= ~IOf_FLUSH;
1799             else {
1800                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1801                     PerlIO *ofp = IoOFP(io);
1802                     if (ofp)
1803                         (void)PerlIO_flush(ofp);
1804                     IoFLAGS(io) |= IOf_FLUSH;
1805                 }
1806             }
1807         }
1808         break;
1809     case '*':
1810         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1811         PL_multiline = (i != 0);
1812         break;
1813     case '/':
1814         SvREFCNT_dec(PL_nrs);
1815         PL_nrs = newSVsv(sv);
1816         SvREFCNT_dec(PL_rs);
1817         PL_rs = SvREFCNT_inc(PL_nrs);
1818         break;
1819     case '\\':
1820         if (PL_ors)
1821             Safefree(PL_ors);
1822         if (SvOK(sv) || SvGMAGICAL(sv)) {
1823             s = SvPV(sv,PL_orslen);
1824             PL_ors = savepvn(s,PL_orslen);
1825         }
1826         else {
1827             PL_ors = Nullch;
1828             PL_orslen = 0;
1829         }
1830         break;
1831     case ',':
1832         if (PL_ofs)
1833             Safefree(PL_ofs);
1834         PL_ofs = savepv(SvPV(sv, PL_ofslen));
1835         break;
1836     case '#':
1837         if (PL_ofmt)
1838             Safefree(PL_ofmt);
1839         PL_ofmt = savepv(SvPV(sv,len));
1840         break;
1841     case '[':
1842         PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1843         break;
1844     case '?':
1845 #ifdef COMPLEX_STATUS
1846         if (PL_localizing == 2) {
1847             PL_statusvalue = LvTARGOFF(sv);
1848             PL_statusvalue_vms = LvTARGLEN(sv);
1849         }
1850         else
1851 #endif
1852 #ifdef VMSISH_STATUS
1853         if (VMSISH_STATUS)
1854             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1855         else
1856 #endif
1857             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1858         break;
1859     case '!':
1860         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1861                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1862         break;
1863     case '<':
1864         PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1865         if (PL_delaymagic) {
1866             PL_delaymagic |= DM_RUID;
1867             break;                              /* don't do magic till later */
1868         }
1869 #ifdef HAS_SETRUID
1870         (void)setruid((Uid_t)PL_uid);
1871 #else
1872 #ifdef HAS_SETREUID
1873         (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
1874 #else
1875 #ifdef HAS_SETRESUID
1876       (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
1877 #else
1878         if (PL_uid == PL_euid)          /* special case $< = $> */
1879             (void)PerlProc_setuid(PL_uid);
1880         else {
1881             PL_uid = PerlProc_getuid();
1882             Perl_croak(aTHX_ "setruid() not implemented");
1883         }
1884 #endif
1885 #endif
1886 #endif
1887         PL_uid = PerlProc_getuid();
1888         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1889         break;
1890     case '>':
1891         PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1892         if (PL_delaymagic) {
1893             PL_delaymagic |= DM_EUID;
1894             break;                              /* don't do magic till later */
1895         }
1896 #ifdef HAS_SETEUID
1897         (void)seteuid((Uid_t)PL_euid);
1898 #else
1899 #ifdef HAS_SETREUID
1900         (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
1901 #else
1902 #ifdef HAS_SETRESUID
1903         (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
1904 #else
1905         if (PL_euid == PL_uid)          /* special case $> = $< */
1906             PerlProc_setuid(PL_euid);
1907         else {
1908             PL_euid = PerlProc_geteuid();
1909             Perl_croak(aTHX_ "seteuid() not implemented");
1910         }
1911 #endif
1912 #endif
1913 #endif
1914         PL_euid = PerlProc_geteuid();
1915         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1916         break;
1917     case '(':
1918         PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1919         if (PL_delaymagic) {
1920             PL_delaymagic |= DM_RGID;
1921             break;                              /* don't do magic till later */
1922         }
1923 #ifdef HAS_SETRGID
1924         (void)setrgid((Gid_t)PL_gid);
1925 #else
1926 #ifdef HAS_SETREGID
1927         (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
1928 #else
1929 #ifdef HAS_SETRESGID
1930       (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
1931 #else
1932         if (PL_gid == PL_egid)                  /* special case $( = $) */
1933             (void)PerlProc_setgid(PL_gid);
1934         else {
1935             PL_gid = PerlProc_getgid();
1936             Perl_croak(aTHX_ "setrgid() not implemented");
1937         }
1938 #endif
1939 #endif
1940 #endif
1941         PL_gid = PerlProc_getgid();
1942         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1943         break;
1944     case ')':
1945 #ifdef HAS_SETGROUPS
1946         {
1947             char *p = SvPV(sv, len);
1948             Groups_t gary[NGROUPS];
1949
1950             while (isSPACE(*p))
1951                 ++p;
1952             PL_egid = Atol(p);
1953             for (i = 0; i < NGROUPS; ++i) {
1954                 while (*p && !isSPACE(*p))
1955                     ++p;
1956                 while (isSPACE(*p))
1957                     ++p;
1958                 if (!*p)
1959                     break;
1960                 gary[i] = Atol(p);
1961             }
1962             if (i)
1963                 (void)setgroups(i, gary);
1964         }
1965 #else  /* HAS_SETGROUPS */
1966         PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1967 #endif /* HAS_SETGROUPS */
1968         if (PL_delaymagic) {
1969             PL_delaymagic |= DM_EGID;
1970             break;                              /* don't do magic till later */
1971         }
1972 #ifdef HAS_SETEGID
1973         (void)setegid((Gid_t)PL_egid);
1974 #else
1975 #ifdef HAS_SETREGID
1976         (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
1977 #else
1978 #ifdef HAS_SETRESGID
1979         (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
1980 #else
1981         if (PL_egid == PL_gid)                  /* special case $) = $( */
1982             (void)PerlProc_setgid(PL_egid);
1983         else {
1984             PL_egid = PerlProc_getegid();
1985             Perl_croak(aTHX_ "setegid() not implemented");
1986         }
1987 #endif
1988 #endif
1989 #endif
1990         PL_egid = PerlProc_getegid();
1991         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1992         break;
1993     case ':':
1994         PL_chopset = SvPV_force(sv,len);
1995         break;
1996 #ifndef MACOS_TRADITIONAL
1997     case '0':
1998 #ifdef HAS_SETPROCTITLE
1999         /* The BSDs don't show the argv[] in ps(1) output, they
2000          * show a string from the process struct and provide
2001          * the setproctitle() routine to manipulate that. */
2002         {
2003             s = SvPV(sv, len);
2004 #   if __FreeBSD_version >= 410001
2005             /* The leading "-" removes the "perl: " prefix,
2006              * but not the "(perl) suffix from the ps(1)
2007              * output, because that's what ps(1) shows if the
2008              * argv[] is modified. */
2009             setproctitle("-%s", s, len + 1);
2010 #   else        /* old FreeBSDs, NetBSD, OpenBSD, anyBSD */
2011             /* This doesn't really work if you assume that
2012              * $0 = 'foobar'; will wipe out 'perl' from the $0
2013              * because in ps(1) output the result will be like
2014              * sprintf("perl: %s (perl)", s)
2015              * I guess this is a security feature:
2016              * one (a user process) cannot get rid of the original name.
2017              * --jhi */
2018             setproctitle("%s", s);
2019 #   endif
2020         }
2021 #endif
2022         if (!PL_origalen) {
2023             s = PL_origargv[0];
2024             s += strlen(s);
2025             /* See if all the arguments are contiguous in memory */
2026             for (i = 1; i < PL_origargc; i++) {
2027                 if (PL_origargv[i] == s + 1
2028 #ifdef OS2
2029                     || PL_origargv[i] == s + 2
2030 #endif
2031                    )
2032                 {
2033                     ++s;
2034                     s += strlen(s);     /* this one is ok too */
2035                 }
2036                 else
2037                     break;
2038             }
2039             /* can grab env area too? */
2040             if (PL_origenviron && (PL_origenviron[0] == s + 1
2041 #ifdef OS2
2042                                 || (PL_origenviron[0] == s + 9 && (s += 8))
2043 #endif
2044                )) {
2045                 my_setenv("NoNe  SuCh", Nullch);
2046                                             /* force copy of environment */
2047                 for (i = 0; PL_origenviron[i]; i++)
2048                     if (PL_origenviron[i] == s + 1) {
2049                         ++s;
2050                         s += strlen(s);
2051                     }
2052                     else
2053                         break;
2054             }
2055             PL_origalen = s - PL_origargv[0];
2056         }
2057         s = SvPV_force(sv,len);
2058         i = len;
2059         if (i >= PL_origalen) {
2060             i = PL_origalen;
2061             /* don't allow system to limit $0 seen by script */
2062             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
2063             Copy(s, PL_origargv[0], i, char);
2064             s = PL_origargv[0]+i;
2065             *s = '\0';
2066         }
2067         else {
2068             Copy(s, PL_origargv[0], i, char);
2069             s = PL_origargv[0]+i;
2070             *s++ = '\0';
2071             while (++i < PL_origalen)
2072                 *s++ = ' ';
2073             s = PL_origargv[0]+i;
2074             for (i = 1; i < PL_origargc; i++)
2075                 PL_origargv[i] = Nullch;
2076         }
2077         break;
2078 #endif
2079 #ifdef USE_THREADS
2080     case '@':
2081         sv_setsv(thr->errsv, sv);
2082         break;
2083 #endif /* USE_THREADS */
2084     }
2085     return 0;
2086 }
2087
2088 #ifdef USE_THREADS
2089 int
2090 Perl_magic_mutexfree(pTHX_ SV *sv, MAGIC *mg)
2091 {
2092     DEBUG_S(PerlIO_printf(Perl_debug_log,
2093                           "0x%"UVxf": magic_mutexfree 0x%"UVxf"\n",
2094                           PTR2UV(thr), PTR2UV(sv));)
2095     if (MgOWNER(mg))
2096         Perl_croak(aTHX_ "panic: magic_mutexfree");
2097     MUTEX_DESTROY(MgMUTEXP(mg));
2098     COND_DESTROY(MgCONDP(mg));
2099     return 0;
2100 }
2101 #endif /* USE_THREADS */
2102
2103 I32
2104 Perl_whichsig(pTHX_ char *sig)
2105 {
2106     register char **sigv;
2107
2108     for (sigv = PL_sig_name+1; *sigv; sigv++)
2109         if (strEQ(sig,*sigv))
2110             return PL_sig_num[sigv - PL_sig_name];
2111 #ifdef SIGCLD
2112     if (strEQ(sig,"CHLD"))
2113         return SIGCLD;
2114 #endif
2115 #ifdef SIGCHLD
2116     if (strEQ(sig,"CLD"))
2117         return SIGCHLD;
2118 #endif
2119     return 0;
2120 }
2121
2122 static SV* sig_sv;
2123
2124 Signal_t
2125 Perl_sighandler(int sig)
2126 {
2127 #if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2128     dTHXoa(PL_curinterp);       /* fake TLS, because signals don't do TLS */
2129 #else
2130     dTHX;
2131 #endif
2132     dSP;
2133     GV *gv = Nullgv;
2134     HV *st;
2135     SV *sv, *tSv = PL_Sv;
2136     CV *cv = Nullcv;
2137     OP *myop = PL_op;
2138     U32 flags = 0;
2139     I32 o_save_i = PL_savestack_ix;
2140     XPV *tXpv = PL_Xpv;
2141
2142 #if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2143     PERL_SET_THX(aTHXo);        /* fake TLS, see above */
2144 #endif
2145
2146     if (PL_savestack_ix + 15 <= PL_savestack_max)
2147         flags |= 1;
2148     if (PL_markstack_ptr < PL_markstack_max - 2)
2149         flags |= 4;
2150     if (PL_retstack_ix < PL_retstack_max - 2)
2151         flags |= 8;
2152     if (PL_scopestack_ix < PL_scopestack_max - 3)
2153         flags |= 16;
2154
2155     if (!PL_psig_ptr[sig])
2156         Perl_die(aTHX_ "Signal SIG%s received, but no signal handler set.\n",
2157             PL_sig_name[sig]);
2158
2159     /* Max number of items pushed there is 3*n or 4. We cannot fix
2160        infinity, so we fix 4 (in fact 5): */
2161     if (flags & 1) {
2162         PL_savestack_ix += 5;           /* Protect save in progress. */
2163         o_save_i = PL_savestack_ix;
2164         SAVEDESTRUCTOR_X(unwind_handler_stack, (void*)&flags);
2165     }
2166     if (flags & 4)
2167         PL_markstack_ptr++;             /* Protect mark. */
2168     if (flags & 8) {
2169         PL_retstack_ix++;
2170         PL_retstack[PL_retstack_ix] = NULL;
2171     }
2172     if (flags & 16)
2173         PL_scopestack_ix += 1;
2174     /* sv_2cv is too complicated, try a simpler variant first: */
2175     if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
2176         || SvTYPE(cv) != SVt_PVCV)
2177         cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
2178
2179     if (!cv || !CvROOT(cv)) {
2180         if (ckWARN(WARN_SIGNAL))
2181             Perl_warner(aTHX_ WARN_SIGNAL, "SIG%s handler \"%s\" not defined.\n",
2182                 PL_sig_name[sig], (gv ? GvENAME(gv)
2183                                 : ((cv && CvGV(cv))
2184                                    ? GvENAME(CvGV(cv))
2185                                    : "__ANON__")));
2186         goto cleanup;
2187     }
2188
2189     if(PL_psig_name[sig]) {
2190         sv = SvREFCNT_inc(PL_psig_name[sig]);
2191         flags |= 64;
2192         sig_sv = sv;
2193     } else {
2194         sv = sv_newmortal();
2195         sv_setpv(sv,PL_sig_name[sig]);
2196     }
2197
2198     PUSHSTACKi(PERLSI_SIGNAL);
2199     PUSHMARK(SP);
2200     PUSHs(sv);
2201     PUTBACK;
2202
2203     call_sv((SV*)cv, G_DISCARD);
2204
2205     POPSTACK;
2206 cleanup:
2207     if (flags & 1)
2208         PL_savestack_ix -= 8; /* Unprotect save in progress. */
2209     if (flags & 4)
2210         PL_markstack_ptr--;
2211     if (flags & 8)
2212         PL_retstack_ix--;
2213     if (flags & 16)
2214         PL_scopestack_ix -= 1;
2215     if (flags & 64)
2216         SvREFCNT_dec(sv);
2217     PL_op = myop;                       /* Apparently not needed... */
2218
2219     PL_Sv = tSv;                        /* Restore global temporaries. */
2220     PL_Xpv = tXpv;
2221     return;
2222 }
2223
2224
2225 #ifdef PERL_OBJECT
2226 #include "XSUB.h"
2227 #endif
2228
2229 static void
2230 restore_magic(pTHXo_ void *p)
2231 {
2232     MGS* mgs = SSPTR(PTR2IV(p), MGS*);
2233     SV* sv = mgs->mgs_sv;
2234
2235     if (!sv)
2236         return;
2237
2238     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
2239     {
2240         if (mgs->mgs_flags)
2241             SvFLAGS(sv) |= mgs->mgs_flags;
2242         else
2243             mg_magical(sv);
2244         if (SvGMAGICAL(sv))
2245             SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
2246     }
2247
2248     mgs->mgs_sv = NULL;  /* mark the MGS structure as restored */
2249
2250     /* If we're still on top of the stack, pop us off.  (That condition
2251      * will be satisfied if restore_magic was called explicitly, but *not*
2252      * if it's being called via leave_scope.)
2253      * The reason for doing this is that otherwise, things like sv_2cv()
2254      * may leave alloc gunk on the savestack, and some code
2255      * (e.g. sighandler) doesn't expect that...
2256      */
2257     if (PL_savestack_ix == mgs->mgs_ss_ix)
2258     {
2259         I32 popval = SSPOPINT;
2260         assert(popval == SAVEt_DESTRUCTOR_X);
2261         PL_savestack_ix -= 2;
2262         popval = SSPOPINT;
2263         assert(popval == SAVEt_ALLOC);
2264         popval = SSPOPINT;
2265         PL_savestack_ix -= popval;
2266     }
2267
2268 }
2269
2270 static void
2271 unwind_handler_stack(pTHXo_ void *p)
2272 {
2273     U32 flags = *(U32*)p;
2274
2275     if (flags & 1)
2276         PL_savestack_ix -= 5; /* Unprotect save in progress. */
2277     /* cxstack_ix-- Not needed, die already unwound it. */
2278     if (flags & 64)
2279         SvREFCNT_dec(sig_sv);
2280 }