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