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