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