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