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