84a63d0ee6732a302af7639e40b32dd71096f0c3
[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         if (PL_ors_sv)
785             sv_setpv(sv,SvPVX(PL_ors_sv));
786         break;
787     case '#':
788         sv_setpv(sv,PL_ofmt);
789         break;
790     case '!':
791 #ifdef VMS
792         sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
793         sv_setpv(sv, errno ? Strerror(errno) : "");
794 #else
795         {
796         int saveerrno = errno;
797         sv_setnv(sv, (NV)errno);
798 #ifdef OS2
799         if (errno == errno_isOS2 || errno == errno_isOS2_set)
800             sv_setpv(sv, os2error(Perl_rc));
801         else
802 #endif
803         sv_setpv(sv, errno ? Strerror(errno) : "");
804         errno = saveerrno;
805         }
806 #endif
807         SvNOK_on(sv);   /* what a wonderful hack! */
808         break;
809     case '<':
810         sv_setiv(sv, (IV)PL_uid);
811         break;
812     case '>':
813         sv_setiv(sv, (IV)PL_euid);
814         break;
815     case '(':
816         sv_setiv(sv, (IV)PL_gid);
817 #ifdef HAS_GETGROUPS
818         Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_gid);
819 #endif
820         goto add_groups;
821     case ')':
822         sv_setiv(sv, (IV)PL_egid);
823 #ifdef HAS_GETGROUPS
824         Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_egid);
825 #endif
826       add_groups:
827 #ifdef HAS_GETGROUPS
828         {
829             Groups_t gary[NGROUPS];
830             i = getgroups(NGROUPS,gary);
831             while (--i >= 0)
832                 Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]);
833         }
834 #endif
835         (void)SvIOK_on(sv);     /* what a wonderful hack! */
836         break;
837     case '*':
838         break;
839 #ifndef MACOS_TRADITIONAL
840     case '0':
841         break;
842 #endif
843 #ifdef USE_5005THREADS
844     case '@':
845         sv_setsv(sv, thr->errsv);
846         break;
847 #endif /* USE_5005THREADS */
848     }
849     return 0;
850 }
851
852 int
853 Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
854 {
855     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
856
857     if (uf && uf->uf_val)
858         (*uf->uf_val)(aTHX_ uf->uf_index, sv);
859     return 0;
860 }
861
862 int
863 Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
864 {
865     register char *s;
866     char *ptr;
867     STRLEN len, klen;
868     I32 i;
869
870     s = SvPV(sv,len);
871     ptr = MgPV(mg,klen);
872     my_setenv(ptr, s);
873
874 #ifdef DYNAMIC_ENV_FETCH
875      /* We just undefd an environment var.  Is a replacement */
876      /* waiting in the wings? */
877     if (!len) {
878         SV **valp;
879         if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
880             s = SvPV(*valp, len);
881     }
882 #endif
883
884 #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
885                             /* And you'll never guess what the dog had */
886                             /*   in its mouth... */
887     if (PL_tainting) {
888         MgTAINTEDDIR_off(mg);
889 #ifdef VMS
890         if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
891             char pathbuf[256], eltbuf[256], *cp, *elt = s;
892             struct stat sbuf;
893             int i = 0, j = 0;
894
895             do {          /* DCL$PATH may be a search list */
896                 while (1) {   /* as may dev portion of any element */
897                     if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
898                         if ( *(cp+1) == '.' || *(cp+1) == '-' ||
899                              cando_by_name(S_IWUSR,0,elt) ) {
900                             MgTAINTEDDIR_on(mg);
901                             return 0;
902                         }
903                     }
904                     if ((cp = strchr(elt, ':')) != Nullch)
905                         *cp = '\0';
906                     if (my_trnlnm(elt, eltbuf, j++))
907                         elt = eltbuf;
908                     else
909                         break;
910                 }
911                 j = 0;
912             } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
913         }
914 #endif /* VMS */
915         if (s && klen == 4 && strEQ(ptr,"PATH")) {
916             char *strend = s + len;
917
918             while (s < strend) {
919                 char tmpbuf[256];
920                 struct stat st;
921                 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
922                              s, strend, ':', &i);
923                 s++;
924                 if (i >= sizeof tmpbuf   /* too long -- assume the worst */
925                       || *tmpbuf != '/'
926                       || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
927                     MgTAINTEDDIR_on(mg);
928                     return 0;
929                 }
930             }
931         }
932     }
933 #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
934
935     return 0;
936 }
937
938 int
939 Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
940 {
941     STRLEN n_a;
942     my_setenv(MgPV(mg,n_a),Nullch);
943     return 0;
944 }
945
946 int
947 Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
948 {
949 #if defined(VMS)
950     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
951 #else
952     if (PL_localizing) {
953         HE* entry;
954         STRLEN n_a;
955         magic_clear_all_env(sv,mg);
956         hv_iterinit((HV*)sv);
957         while ((entry = hv_iternext((HV*)sv))) {
958             I32 keylen;
959             my_setenv(hv_iterkey(entry, &keylen),
960                       SvPV(hv_iterval((HV*)sv, entry), n_a));
961         }
962     }
963 #endif
964     return 0;
965 }
966
967 int
968 Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
969 {
970 #if defined(VMS) || defined(EPOC)
971     Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
972 #else
973 #   if defined(PERL_IMPLICIT_SYS) || defined(WIN32)
974     PerlEnv_clearenv();
975 #   else
976 #       ifdef USE_ENVIRON_ARRAY
977 #           ifndef PERL_USE_SAFE_PUTENV
978     I32 i;
979
980     if (environ == PL_origenviron)
981         environ = (char**)safesysmalloc(sizeof(char*));
982     else
983         for (i = 0; environ[i]; i++)
984             safesysfree(environ[i]);
985 #           endif /* PERL_USE_SAFE_PUTENV */
986
987     environ[0] = Nullch;
988
989 #       endif /* USE_ENVIRON_ARRAY */
990 #   endif /* PERL_IMPLICIT_SYS || WIN32 */
991 #endif /* VMS || EPC */
992     return 0;
993 }
994
995 #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS   
996 static int sig_ignoring_initted = 0;
997 static int sig_ignoring[SIG_SIZE];      /* which signals we are ignoring */
998 #endif
999
1000 #ifndef PERL_MICRO
1001 int
1002 Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
1003 {
1004     I32 i;
1005     STRLEN n_a;
1006     /* Are we fetching a signal entry? */
1007     i = whichsig(MgPV(mg,n_a));
1008     if (i) {
1009         if(PL_psig_ptr[i])
1010             sv_setsv(sv,PL_psig_ptr[i]);
1011         else {
1012             Sighandler_t sigstate;
1013 #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
1014             if (sig_ignoring_initted && sig_ignoring[i]) 
1015               sigstate = SIG_IGN;
1016             else
1017 #endif
1018             sigstate = rsignal_state(i);
1019
1020             /* cache state so we don't fetch it again */
1021             if(sigstate == SIG_IGN)
1022                 sv_setpv(sv,"IGNORE");
1023             else
1024                 sv_setsv(sv,&PL_sv_undef);
1025             PL_psig_ptr[i] = SvREFCNT_inc(sv);
1026             SvTEMP_off(sv);
1027         }
1028     }
1029     return 0;
1030 }
1031 int
1032 Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
1033 {
1034     I32 i;
1035     STRLEN n_a;
1036     /* Are we clearing a signal entry? */
1037     i = whichsig(MgPV(mg,n_a));
1038     if (i) {
1039         if(PL_psig_ptr[i]) {
1040             SvREFCNT_dec(PL_psig_ptr[i]);
1041             PL_psig_ptr[i]=0;
1042         }
1043         if(PL_psig_name[i]) {
1044             SvREFCNT_dec(PL_psig_name[i]);
1045             PL_psig_name[i]=0;
1046         }
1047     }
1048     return 0;
1049 }
1050
1051 void
1052 Perl_raise_signal(pTHX_ int sig)
1053 {
1054     /* Set a flag to say this signal is pending */
1055     PL_psig_pend[sig]++;
1056     /* And one to say _a_ signal is pending */
1057     PL_sig_pending = 1;
1058 }
1059
1060 Signal_t
1061 Perl_csighandler(int sig)
1062 {
1063 #ifndef PERL_OLD_SIGNALS
1064     dTHX;
1065 #endif
1066 #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
1067     (void) rsignal(sig, &Perl_csighandler);
1068     if (sig_ignoring[sig]) return;
1069 #endif
1070 #ifdef PERL_OLD_SIGNALS
1071     /* Call the perl level handler now with risk we may be in malloc() etc. */
1072     (*PL_sighandlerp)(sig);
1073 #else
1074     Perl_raise_signal(aTHX_ sig);
1075 #endif
1076 }
1077
1078 void
1079 Perl_despatch_signals(pTHX)
1080 {
1081     int sig;
1082     PL_sig_pending = 0;
1083     for (sig = 1; sig < SIG_SIZE; sig++) {
1084         if (PL_psig_pend[sig]) {
1085             PL_psig_pend[sig] = 0;
1086             (*PL_sighandlerp)(sig);
1087         }
1088     }
1089 }
1090
1091 int
1092 Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
1093 {
1094     register char *s;
1095     I32 i;
1096     SV** svp = 0;
1097     STRLEN len;
1098
1099     s = MgPV(mg,len);
1100     if (*s == '_') {
1101         if (strEQ(s,"__DIE__"))
1102             svp = &PL_diehook;
1103         else if (strEQ(s,"__WARN__"))
1104             svp = &PL_warnhook;
1105         else
1106             Perl_croak(aTHX_ "No such hook: %s", s);
1107         i = 0;
1108         if (*svp) {
1109             SvREFCNT_dec(*svp);
1110             *svp = 0;
1111         }
1112     }
1113     else {
1114         i = whichsig(s);        /* ...no, a brick */
1115         if (!i) {
1116             if (ckWARN(WARN_SIGNAL))
1117                 Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s);
1118             return 0;
1119         }
1120 #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
1121         if (!sig_ignoring_initted) {
1122             int j;
1123             for (j = 0; j < SIG_SIZE; j++) sig_ignoring[j] = 0;
1124             sig_ignoring_initted = 1;
1125         }
1126         sig_ignoring[i] = 0;
1127 #endif
1128         SvREFCNT_dec(PL_psig_name[i]);
1129         SvREFCNT_dec(PL_psig_ptr[i]);
1130         PL_psig_ptr[i] = SvREFCNT_inc(sv);
1131         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
1132         PL_psig_name[i] = newSVpvn(s, len);
1133         SvREADONLY_on(PL_psig_name[i]);
1134     }
1135     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
1136         if (i)
1137             (void)rsignal(i, &Perl_csighandler);
1138         else
1139             *svp = SvREFCNT_inc(sv);
1140         return 0;
1141     }
1142     s = SvPV_force(sv,len);
1143     if (strEQ(s,"IGNORE")) {
1144         if (i) {
1145 #ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
1146             sig_ignoring[i] = 1;
1147             (void)rsignal(i, &Perl_csighandler);
1148 #else
1149             (void)rsignal(i, SIG_IGN);
1150 #endif
1151         } else
1152             *svp = 0;
1153     }
1154     else if (strEQ(s,"DEFAULT") || !*s) {
1155         if (i)
1156             (void)rsignal(i, SIG_DFL);
1157         else
1158             *svp = 0;
1159     }
1160     else {
1161         /*
1162          * We should warn if HINT_STRICT_REFS, but without
1163          * access to a known hint bit in a known OP, we can't
1164          * tell whether HINT_STRICT_REFS is in force or not.
1165          */
1166         if (!strchr(s,':') && !strchr(s,'\''))
1167             sv_insert(sv, 0, 0, "main::", 6);
1168         if (i)
1169             (void)rsignal(i, &Perl_csighandler);
1170         else
1171             *svp = SvREFCNT_inc(sv);
1172     }
1173     return 0;
1174 }
1175 #endif /* !PERL_MICRO */
1176
1177 int
1178 Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
1179 {
1180     PL_sub_generation++;
1181     return 0;
1182 }
1183
1184 int
1185 Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
1186 {
1187     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
1188     PL_amagic_generation++;
1189
1190     return 0;
1191 }
1192
1193 int
1194 Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
1195 {
1196     HV *hv = (HV*)LvTARG(sv);
1197     I32 i = 0;
1198      
1199     if (hv) {
1200          (void) hv_iterinit(hv);
1201          if (! SvTIED_mg((SV*)hv, PERL_MAGIC_tied))
1202              i = HvKEYS(hv);
1203          else {
1204              while (hv_iternext(hv))
1205                  i++;
1206          }
1207     }
1208
1209     sv_setiv(sv, (IV)i);
1210     return 0;
1211 }
1212
1213 int
1214 Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
1215 {
1216     if (LvTARG(sv)) {
1217         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
1218     }
1219     return 0;
1220 }
1221
1222 /* caller is responsible for stack switching/cleanup */
1223 STATIC int
1224 S_magic_methcall(pTHX_ SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
1225 {
1226     dSP;
1227
1228     PUSHMARK(SP);
1229     EXTEND(SP, n);
1230     PUSHs(SvTIED_obj(sv, mg));
1231     if (n > 1) {
1232         if (mg->mg_ptr) {
1233             if (mg->mg_len >= 0)
1234                 PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
1235             else if (mg->mg_len == HEf_SVKEY)
1236                 PUSHs((SV*)mg->mg_ptr);
1237         }
1238         else if (mg->mg_type == PERL_MAGIC_tiedelem) {
1239             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
1240         }
1241     }
1242     if (n > 2) {
1243         PUSHs(val);
1244     }
1245     PUTBACK;
1246
1247     return call_method(meth, flags);
1248 }
1249
1250 STATIC int
1251 S_magic_methpack(pTHX_ SV *sv, MAGIC *mg, char *meth)
1252 {
1253     dSP;
1254
1255     ENTER;
1256     SAVETMPS;
1257     PUSHSTACKi(PERLSI_MAGIC);
1258
1259     if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
1260         sv_setsv(sv, *PL_stack_sp--);
1261     }
1262
1263     POPSTACK;
1264     FREETMPS;
1265     LEAVE;
1266     return 0;
1267 }
1268
1269 int
1270 Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
1271 {
1272     magic_methpack(sv,mg,"FETCH");
1273     if (mg->mg_ptr)
1274         mg->mg_flags |= MGf_GSKIP;
1275     return 0;
1276 }
1277
1278 int
1279 Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
1280 {
1281     dSP;
1282     ENTER;
1283     PUSHSTACKi(PERLSI_MAGIC);
1284     magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1285     POPSTACK;
1286     LEAVE;
1287     return 0;
1288 }
1289
1290 int
1291 Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
1292 {
1293     return magic_methpack(sv,mg,"DELETE");
1294 }
1295
1296
1297 U32
1298 Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
1299 {
1300     dSP;
1301     U32 retval = 0;
1302
1303     ENTER;
1304     SAVETMPS;
1305     PUSHSTACKi(PERLSI_MAGIC);
1306     if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1307         sv = *PL_stack_sp--;
1308         retval = (U32) SvIV(sv)-1;
1309     }
1310     POPSTACK;
1311     FREETMPS;
1312     LEAVE;
1313     return retval;
1314 }
1315
1316 int
1317 Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
1318 {
1319     dSP;
1320
1321     ENTER;
1322     PUSHSTACKi(PERLSI_MAGIC);
1323     PUSHMARK(SP);
1324     XPUSHs(SvTIED_obj(sv, mg));
1325     PUTBACK;
1326     call_method("CLEAR", G_SCALAR|G_DISCARD);
1327     POPSTACK;
1328     LEAVE;
1329     return 0;
1330 }
1331
1332 int
1333 Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
1334 {
1335     dSP;
1336     const char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1337
1338     ENTER;
1339     SAVETMPS;
1340     PUSHSTACKi(PERLSI_MAGIC);
1341     PUSHMARK(SP);
1342     EXTEND(SP, 2);
1343     PUSHs(SvTIED_obj(sv, mg));
1344     if (SvOK(key))
1345         PUSHs(key);
1346     PUTBACK;
1347
1348     if (call_method(meth, G_SCALAR))
1349         sv_setsv(key, *PL_stack_sp--);
1350
1351     POPSTACK;
1352     FREETMPS;
1353     LEAVE;
1354     return 0;
1355 }
1356
1357 int
1358 Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
1359 {
1360     return magic_methpack(sv,mg,"EXISTS");
1361 }
1362
1363 int
1364 Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
1365 {
1366     OP *o;
1367     I32 i;
1368     GV* gv;
1369     SV** svp;
1370     STRLEN n_a;
1371
1372     gv = PL_DBline;
1373     i = SvTRUE(sv);
1374     svp = av_fetch(GvAV(gv),
1375                      atoi(MgPV(mg,n_a)), FALSE);
1376     if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp))))
1377         o->op_private = i;
1378     return 0;
1379 }
1380
1381 int
1382 Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
1383 {
1384     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
1385     return 0;
1386 }
1387
1388 int
1389 Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
1390 {
1391     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
1392     return 0;
1393 }
1394
1395 int
1396 Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
1397 {
1398     SV* lsv = LvTARG(sv);
1399
1400     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1401         mg = mg_find(lsv, PERL_MAGIC_regex_global);
1402         if (mg && mg->mg_len >= 0) {
1403             I32 i = mg->mg_len;
1404             if (DO_UTF8(lsv))
1405                 sv_pos_b2u(lsv, &i);
1406             sv_setiv(sv, i + PL_curcop->cop_arybase);
1407             return 0;
1408         }
1409     }
1410     (void)SvOK_off(sv);
1411     return 0;
1412 }
1413
1414 int
1415 Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
1416 {
1417     SV* lsv = LvTARG(sv);
1418     SSize_t pos;
1419     STRLEN len;
1420     STRLEN ulen = 0;
1421
1422     mg = 0;
1423
1424     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1425         mg = mg_find(lsv, PERL_MAGIC_regex_global);
1426     if (!mg) {
1427         if (!SvOK(sv))
1428             return 0;
1429         sv_magic(lsv, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
1430         mg = mg_find(lsv, PERL_MAGIC_regex_global);
1431     }
1432     else if (!SvOK(sv)) {
1433         mg->mg_len = -1;
1434         return 0;
1435     }
1436     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1437
1438     pos = SvIV(sv) - PL_curcop->cop_arybase;
1439
1440     if (DO_UTF8(lsv)) {
1441         ulen = sv_len_utf8(lsv);
1442         if (ulen)
1443             len = ulen;
1444     }
1445
1446     if (pos < 0) {
1447         pos += len;
1448         if (pos < 0)
1449             pos = 0;
1450     }
1451     else if (pos > len)
1452         pos = len;
1453
1454     if (ulen) {
1455         I32 p = pos;
1456         sv_pos_u2b(lsv, &p, 0);
1457         pos = p;
1458     }
1459         
1460     mg->mg_len = pos;
1461     mg->mg_flags &= ~MGf_MINMATCH;
1462
1463     return 0;
1464 }
1465
1466 int
1467 Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
1468 {
1469     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1470         SvFAKE_off(sv);
1471         gv_efullname3(sv,((GV*)sv), "*");
1472         SvFAKE_on(sv);
1473     }
1474     else
1475         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1476     return 0;
1477 }
1478
1479 int
1480 Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
1481 {
1482     register char *s;
1483     GV* gv;
1484     STRLEN n_a;
1485
1486     if (!SvOK(sv))
1487         return 0;
1488     s = SvPV(sv, n_a);
1489     if (*s == '*' && s[1])
1490         s++;
1491     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1492     if (sv == (SV*)gv)
1493         return 0;
1494     if (GvGP(sv))
1495         gp_free((GV*)sv);
1496     GvGP(sv) = gp_ref(GvGP(gv));
1497     return 0;
1498 }
1499
1500 int
1501 Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
1502 {
1503     STRLEN len;
1504     SV *lsv = LvTARG(sv);
1505     char *tmps = SvPV(lsv,len);
1506     I32 offs = LvTARGOFF(sv);
1507     I32 rem = LvTARGLEN(sv);
1508
1509     if (SvUTF8(lsv))
1510         sv_pos_u2b(lsv, &offs, &rem);
1511     if (offs > len)
1512         offs = len;
1513     if (rem + offs > len)
1514         rem = len - offs;
1515     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
1516     if (SvUTF8(lsv))
1517         SvUTF8_on(sv);
1518     return 0;
1519 }
1520
1521 int
1522 Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
1523 {
1524     STRLEN len;
1525     char *tmps = SvPV(sv, len);
1526     SV *lsv = LvTARG(sv);
1527     I32 lvoff = LvTARGOFF(sv);
1528     I32 lvlen = LvTARGLEN(sv);
1529
1530     if (DO_UTF8(sv)) {
1531         sv_utf8_upgrade(lsv);
1532         sv_pos_u2b(lsv, &lvoff, &lvlen);
1533         sv_insert(lsv, lvoff, lvlen, tmps, len);
1534         SvUTF8_on(lsv);
1535     }
1536     else if (lsv && SvUTF8(lsv)) {
1537         sv_pos_u2b(lsv, &lvoff, &lvlen);
1538         tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
1539         sv_insert(lsv, lvoff, lvlen, tmps, len);
1540         Safefree(tmps);
1541     }
1542     else
1543         sv_insert(lsv, lvoff, lvlen, tmps, len);
1544
1545     return 0;
1546 }
1547
1548 int
1549 Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
1550 {
1551     TAINT_IF((mg->mg_len & 1) ||
1552              ((mg->mg_len & 2) && mg->mg_obj == sv));   /* kludge */
1553     return 0;
1554 }
1555
1556 int
1557 Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
1558 {
1559     if (PL_localizing) {
1560         if (PL_localizing == 1)
1561             mg->mg_len <<= 1;
1562         else
1563             mg->mg_len >>= 1;
1564     }
1565     else if (PL_tainted)
1566         mg->mg_len |= 1;
1567     else
1568         mg->mg_len &= ~1;
1569     return 0;
1570 }
1571
1572 int
1573 Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
1574 {
1575     SV *lsv = LvTARG(sv);
1576
1577     if (!lsv) {
1578         (void)SvOK_off(sv);
1579         return 0;
1580     }
1581
1582     sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
1583     return 0;
1584 }
1585
1586 int
1587 Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
1588 {
1589     do_vecset(sv);      /* XXX slurp this routine */
1590     return 0;
1591 }
1592
1593 int
1594 Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
1595 {
1596     SV *targ = Nullsv;
1597     if (LvTARGLEN(sv)) {
1598         if (mg->mg_obj) {
1599             SV *ahv = LvTARG(sv);
1600             if (SvTYPE(ahv) == SVt_PVHV) {
1601                 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1602                 if (he)
1603                     targ = HeVAL(he);
1604             }
1605             else {
1606                 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1607                 if (svp)
1608                     targ = *svp;
1609             }
1610         }
1611         else {
1612             AV* av = (AV*)LvTARG(sv);
1613             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1614                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1615         }
1616         if (targ && targ != &PL_sv_undef) {
1617             /* somebody else defined it for us */
1618             SvREFCNT_dec(LvTARG(sv));
1619             LvTARG(sv) = SvREFCNT_inc(targ);
1620             LvTARGLEN(sv) = 0;
1621             SvREFCNT_dec(mg->mg_obj);
1622             mg->mg_obj = Nullsv;
1623             mg->mg_flags &= ~MGf_REFCOUNTED;
1624         }
1625     }
1626     else
1627         targ = LvTARG(sv);
1628     sv_setsv(sv, targ ? targ : &PL_sv_undef);
1629     return 0;
1630 }
1631
1632 int
1633 Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
1634 {
1635     if (LvTARGLEN(sv))
1636         vivify_defelem(sv);
1637     if (LvTARG(sv)) {
1638         sv_setsv(LvTARG(sv), sv);
1639         SvSETMAGIC(LvTARG(sv));
1640     }
1641     return 0;
1642 }
1643
1644 void
1645 Perl_vivify_defelem(pTHX_ SV *sv)
1646 {
1647     MAGIC *mg;
1648     SV *value = Nullsv;
1649
1650     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem)))
1651         return;
1652     if (mg->mg_obj) {
1653         SV *ahv = LvTARG(sv);
1654         STRLEN n_a;
1655         if (SvTYPE(ahv) == SVt_PVHV) {
1656             HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
1657             if (he)
1658                 value = HeVAL(he);
1659         }
1660         else {
1661             SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, TRUE, 0);
1662             if (svp)
1663                 value = *svp;
1664         }
1665         if (!value || value == &PL_sv_undef)
1666             Perl_croak(aTHX_ PL_no_helem, SvPV(mg->mg_obj, n_a));
1667     }
1668     else {
1669         AV* av = (AV*)LvTARG(sv);
1670         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1671             LvTARG(sv) = Nullsv;        /* array can't be extended */
1672         else {
1673             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1674             if (!svp || (value = *svp) == &PL_sv_undef)
1675                 Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
1676         }
1677     }
1678     (void)SvREFCNT_inc(value);
1679     SvREFCNT_dec(LvTARG(sv));
1680     LvTARG(sv) = value;
1681     LvTARGLEN(sv) = 0;
1682     SvREFCNT_dec(mg->mg_obj);
1683     mg->mg_obj = Nullsv;
1684     mg->mg_flags &= ~MGf_REFCOUNTED;
1685 }
1686
1687 int
1688 Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
1689 {
1690     AV *av = (AV*)mg->mg_obj;
1691     SV **svp = AvARRAY(av);
1692     I32 i = AvFILLp(av);
1693     while (i >= 0) {
1694         if (svp[i] && svp[i] != &PL_sv_undef) {
1695             if (!SvWEAKREF(svp[i]))
1696                 Perl_croak(aTHX_ "panic: magic_killbackrefs");
1697             /* XXX Should we check that it hasn't changed? */
1698             SvRV(svp[i]) = 0;
1699             (void)SvOK_off(svp[i]);
1700             SvWEAKREF_off(svp[i]);
1701             svp[i] = &PL_sv_undef;
1702         }
1703         i--;
1704     }
1705     return 0;
1706 }
1707
1708 int
1709 Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
1710 {
1711     mg->mg_len = -1;
1712     SvSCREAM_off(sv);
1713     return 0;
1714 }
1715
1716 int
1717 Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
1718 {
1719     sv_unmagic(sv, PERL_MAGIC_bm);
1720     SvVALID_off(sv);
1721     return 0;
1722 }
1723
1724 int
1725 Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
1726 {
1727     sv_unmagic(sv, PERL_MAGIC_fm);
1728     SvCOMPILED_off(sv);
1729     return 0;
1730 }
1731
1732 int
1733 Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
1734 {
1735     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1736
1737     if (uf && uf->uf_set)
1738         (*uf->uf_set)(aTHX_ uf->uf_index, sv);
1739     return 0;
1740 }
1741
1742 int
1743 Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
1744 {
1745     regexp *re = (regexp *)mg->mg_obj;
1746     ReREFCNT_dec(re);
1747     return 0;
1748 }
1749
1750 #ifdef USE_LOCALE_COLLATE
1751 int
1752 Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
1753 {
1754     /*
1755      * RenE<eacute> Descartes said "I think not."
1756      * and vanished with a faint plop.
1757      */
1758     if (mg->mg_ptr) {
1759         Safefree(mg->mg_ptr);
1760         mg->mg_ptr = NULL;
1761         mg->mg_len = -1;
1762     }
1763     return 0;
1764 }
1765 #endif /* USE_LOCALE_COLLATE */
1766
1767 int
1768 Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
1769 {
1770     register char *s;
1771     I32 i;
1772     STRLEN len;
1773     switch (*mg->mg_ptr) {
1774     case '\001':        /* ^A */
1775         sv_setsv(PL_bodytarget, sv);
1776         break;
1777     case '\003':        /* ^C */
1778         PL_minus_c = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1779         break;
1780
1781     case '\004':        /* ^D */
1782         PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | DEBUG_TOP_FLAG;
1783         DEBUG_x(dump_all());
1784         break;
1785     case '\005':  /* ^E */
1786          if (*(mg->mg_ptr+1) == '\0') {
1787 #ifdef MACOS_TRADITIONAL
1788               gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1789 #else
1790 #  ifdef VMS
1791               set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1792 #  else
1793 #    ifdef WIN32
1794               SetLastError( SvIV(sv) );
1795 #    else
1796 #      ifdef OS2
1797               os2_setsyserrno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1798 #      else
1799               /* will anyone ever use this? */
1800               SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1801 #      endif
1802 #    endif
1803 #  endif
1804 #endif
1805          }
1806          else if (strEQ(mg->mg_ptr+1, "NCODING")) {
1807              if (PL_encoding)
1808                  sv_setsv(PL_encoding, sv);
1809              else
1810                  PL_encoding = newSVsv(sv);
1811          }
1812     case '\006':        /* ^F */
1813         PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1814         break;
1815     case '\010':        /* ^H */
1816         PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1817         break;
1818     case '\011':        /* ^I */ /* NOT \t in EBCDIC */
1819         if (PL_inplace)
1820             Safefree(PL_inplace);
1821         if (SvOK(sv))
1822             PL_inplace = savepv(SvPV(sv,len));
1823         else
1824             PL_inplace = Nullch;
1825         break;
1826     case '\017':        /* ^O */
1827         if (*(mg->mg_ptr+1) == '\0') {
1828             if (PL_osname)
1829                 Safefree(PL_osname);
1830             if (SvOK(sv))
1831                 PL_osname = savepv(SvPV(sv,len));
1832             else
1833                 PL_osname = Nullch;
1834         }
1835         else if (strEQ(mg->mg_ptr, "\017PEN")) {
1836             if (!PL_compiling.cop_io)
1837                 PL_compiling.cop_io = newSVsv(sv);
1838             else
1839                 sv_setsv(PL_compiling.cop_io,sv);
1840         }
1841         break;
1842     case '\020':        /* ^P */
1843         PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1844         if (PL_perldb && !PL_DBsingle)
1845             init_debugger();
1846         break;
1847     case '\024':        /* ^T */
1848 #ifdef BIG_TIME
1849         PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1850 #else
1851         PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1852 #endif
1853         break;
1854     case '\027':        /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */
1855         if (*(mg->mg_ptr+1) == '\0') {
1856             if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
1857                 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1858                 PL_dowarn = (PL_dowarn & ~G_WARN_ON)
1859                                 | (i ? G_WARN_ON : G_WARN_OFF) ;
1860             }
1861         }
1862         else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) {
1863             if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
1864                 if (!SvPOK(sv) && PL_localizing) {
1865                     sv_setpvn(sv, WARN_NONEstring, WARNsize);
1866                     PL_compiling.cop_warnings = pWARN_NONE;
1867                     break;
1868                 }
1869                 {
1870                     STRLEN len, i;
1871                     int accumulate = 0 ;
1872                     int any_fatals = 0 ;
1873                     char * ptr = (char*)SvPV(sv, len) ;
1874                     for (i = 0 ; i < len ; ++i) {
1875                         accumulate |= ptr[i] ;
1876                         any_fatals |= (ptr[i] & 0xAA) ;
1877                     }
1878                     if (!accumulate)
1879                         PL_compiling.cop_warnings = pWARN_NONE;
1880                     else if (isWARN_on(sv, WARN_ALL) && !any_fatals) {
1881                         PL_compiling.cop_warnings = pWARN_ALL;
1882                         PL_dowarn |= G_WARN_ONCE ;
1883                     }   
1884                     else {
1885                         if (specialWARN(PL_compiling.cop_warnings))
1886                             PL_compiling.cop_warnings = newSVsv(sv) ;
1887                         else
1888                             sv_setsv(PL_compiling.cop_warnings, sv);
1889                         if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
1890                             PL_dowarn |= G_WARN_ONCE ;
1891                     }
1892
1893                 }
1894             }
1895         }
1896         else if (strEQ(mg->mg_ptr+1, "IDE_SYSTEM_CALLS"))
1897             PL_widesyscalls = SvTRUE(sv);
1898         break;
1899     case '.':
1900         if (PL_localizing) {
1901             if (PL_localizing == 1)
1902                 SAVESPTR(PL_last_in_gv);
1903         }
1904         else if (SvOK(sv) && GvIO(PL_last_in_gv))
1905             IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv);
1906         break;
1907     case '^':
1908         Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
1909         IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
1910         IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1911         break;
1912     case '~':
1913         Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
1914         IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
1915         IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1916         break;
1917     case '=':
1918         IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1919         break;
1920     case '-':
1921         IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1922         if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
1923             IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
1924         break;
1925     case '%':
1926         IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1927         break;
1928     case '|':
1929         {
1930             IO *io = GvIOp(PL_defoutgv);
1931             if(!io)
1932               break;
1933             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1934                 IoFLAGS(io) &= ~IOf_FLUSH;
1935             else {
1936                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1937                     PerlIO *ofp = IoOFP(io);
1938                     if (ofp)
1939                         (void)PerlIO_flush(ofp);
1940                     IoFLAGS(io) |= IOf_FLUSH;
1941                 }
1942             }
1943         }
1944         break;
1945     case '*':
1946         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1947         PL_multiline = (i != 0);
1948         break;
1949     case '/':
1950         SvREFCNT_dec(PL_rs);
1951         PL_rs = newSVsv(sv);
1952         break;
1953     case '\\':
1954         if (PL_ors_sv)
1955             SvREFCNT_dec(PL_ors_sv);
1956         if (SvOK(sv) || SvGMAGICAL(sv)) {
1957             PL_ors_sv = newSVsv(sv);
1958         }
1959         else {
1960             PL_ors_sv = Nullsv;
1961         }
1962         break;
1963     case ',':
1964         if (PL_ofs_sv)
1965             SvREFCNT_dec(PL_ofs_sv);
1966         if (SvOK(sv) || SvGMAGICAL(sv)) {
1967             PL_ofs_sv = newSVsv(sv);
1968         }
1969         else {
1970             PL_ofs_sv = Nullsv;
1971         }
1972         break;
1973     case '#':
1974         if (PL_ofmt)
1975             Safefree(PL_ofmt);
1976         PL_ofmt = savepv(SvPV(sv,len));
1977         break;
1978     case '[':
1979         PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1980         break;
1981     case '?':
1982 #ifdef COMPLEX_STATUS
1983         if (PL_localizing == 2) {
1984             PL_statusvalue = LvTARGOFF(sv);
1985             PL_statusvalue_vms = LvTARGLEN(sv);
1986         }
1987         else
1988 #endif
1989 #ifdef VMSISH_STATUS
1990         if (VMSISH_STATUS)
1991             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1992         else
1993 #endif
1994             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1995         break;
1996     case '!':
1997         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1998                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1999         break;
2000     case '<':
2001         PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2002         if (PL_delaymagic) {
2003             PL_delaymagic |= DM_RUID;
2004             break;                              /* don't do magic till later */
2005         }
2006 #ifdef HAS_SETRUID
2007         (void)setruid((Uid_t)PL_uid);
2008 #else
2009 #ifdef HAS_SETREUID
2010         (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
2011 #else
2012 #ifdef HAS_SETRESUID
2013       (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
2014 #else
2015         if (PL_uid == PL_euid)          /* special case $< = $> */
2016             (void)PerlProc_setuid(PL_uid);
2017         else {
2018             PL_uid = PerlProc_getuid();
2019             Perl_croak(aTHX_ "setruid() not implemented");
2020         }
2021 #endif
2022 #endif
2023 #endif
2024         PL_uid = PerlProc_getuid();
2025         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
2026         break;
2027     case '>':
2028         PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2029         if (PL_delaymagic) {
2030             PL_delaymagic |= DM_EUID;
2031             break;                              /* don't do magic till later */
2032         }
2033 #ifdef HAS_SETEUID
2034         (void)seteuid((Uid_t)PL_euid);
2035 #else
2036 #ifdef HAS_SETREUID
2037         (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
2038 #else
2039 #ifdef HAS_SETRESUID
2040         (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
2041 #else
2042         if (PL_euid == PL_uid)          /* special case $> = $< */
2043             PerlProc_setuid(PL_euid);
2044         else {
2045             PL_euid = PerlProc_geteuid();
2046             Perl_croak(aTHX_ "seteuid() not implemented");
2047         }
2048 #endif
2049 #endif
2050 #endif
2051         PL_euid = PerlProc_geteuid();
2052         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
2053         break;
2054     case '(':
2055         PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2056         if (PL_delaymagic) {
2057             PL_delaymagic |= DM_RGID;
2058             break;                              /* don't do magic till later */
2059         }
2060 #ifdef HAS_SETRGID
2061         (void)setrgid((Gid_t)PL_gid);
2062 #else
2063 #ifdef HAS_SETREGID
2064         (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
2065 #else
2066 #ifdef HAS_SETRESGID
2067       (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
2068 #else
2069         if (PL_gid == PL_egid)                  /* special case $( = $) */
2070             (void)PerlProc_setgid(PL_gid);
2071         else {
2072             PL_gid = PerlProc_getgid();
2073             Perl_croak(aTHX_ "setrgid() not implemented");
2074         }
2075 #endif
2076 #endif
2077 #endif
2078         PL_gid = PerlProc_getgid();
2079         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
2080         break;
2081     case ')':
2082 #ifdef HAS_SETGROUPS
2083         {
2084             char *p = SvPV(sv, len);
2085             Groups_t gary[NGROUPS];
2086
2087             while (isSPACE(*p))
2088                 ++p;
2089             PL_egid = Atol(p);
2090             for (i = 0; i < NGROUPS; ++i) {
2091                 while (*p && !isSPACE(*p))
2092                     ++p;
2093                 while (isSPACE(*p))
2094                     ++p;
2095                 if (!*p)
2096                     break;
2097                 gary[i] = Atol(p);
2098             }
2099             if (i)
2100                 (void)setgroups(i, gary);
2101         }
2102 #else  /* HAS_SETGROUPS */
2103         PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2104 #endif /* HAS_SETGROUPS */
2105         if (PL_delaymagic) {
2106             PL_delaymagic |= DM_EGID;
2107             break;                              /* don't do magic till later */
2108         }
2109 #ifdef HAS_SETEGID
2110         (void)setegid((Gid_t)PL_egid);
2111 #else
2112 #ifdef HAS_SETREGID
2113         (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
2114 #else
2115 #ifdef HAS_SETRESGID
2116         (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
2117 #else
2118         if (PL_egid == PL_gid)                  /* special case $) = $( */
2119             (void)PerlProc_setgid(PL_egid);
2120         else {
2121             PL_egid = PerlProc_getegid();
2122             Perl_croak(aTHX_ "setegid() not implemented");
2123         }
2124 #endif
2125 #endif
2126 #endif
2127         PL_egid = PerlProc_getegid();
2128         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
2129         break;
2130     case ':':
2131         PL_chopset = SvPV_force(sv,len);
2132         break;
2133 #ifndef MACOS_TRADITIONAL
2134     case '0':
2135 #ifdef HAS_SETPROCTITLE
2136         /* The BSDs don't show the argv[] in ps(1) output, they
2137          * show a string from the process struct and provide
2138          * the setproctitle() routine to manipulate that. */
2139         {
2140             s = SvPV(sv, len);
2141 #   if __FreeBSD_version > 410001
2142             /* The leading "-" removes the "perl: " prefix,
2143              * but not the "(perl) suffix from the ps(1)
2144              * output, because that's what ps(1) shows if the
2145              * argv[] is modified. */
2146             setproctitle("-%s", s);
2147 #   else        /* old FreeBSDs, NetBSD, OpenBSD, anyBSD */
2148             /* This doesn't really work if you assume that
2149              * $0 = 'foobar'; will wipe out 'perl' from the $0
2150              * because in ps(1) output the result will be like
2151              * sprintf("perl: %s (perl)", s)
2152              * I guess this is a security feature:
2153              * one (a user process) cannot get rid of the original name.
2154              * --jhi */
2155             setproctitle("%s", s);
2156 #   endif
2157         }
2158 #endif
2159         if (!PL_origalen) {
2160             s = PL_origargv[0];
2161             s += strlen(s);
2162             /* See if all the arguments are contiguous in memory */
2163             for (i = 1; i < PL_origargc; i++) {
2164                 if (PL_origargv[i] == s + 1
2165 #ifdef OS2
2166                     || PL_origargv[i] == s + 2
2167 #endif
2168                    )
2169                 {
2170                     ++s;
2171                     s += strlen(s);     /* this one is ok too */
2172                 }
2173                 else
2174                     break;
2175             }
2176             /* can grab env area too? */
2177             if (PL_origenviron && (PL_origenviron[0] == s + 1)) {
2178                 my_setenv("NoNe  SuCh", Nullch);
2179                                             /* force copy of environment */
2180                 for (i = 0; PL_origenviron[i]; i++)
2181                     if (PL_origenviron[i] == s + 1) {
2182                         ++s;
2183                         s += strlen(s);
2184                     }
2185                     else
2186                         break;
2187             }
2188             PL_origalen = s - PL_origargv[0];
2189         }
2190         s = SvPV_force(sv,len);
2191         i = len;
2192         if (i >= PL_origalen) {
2193             i = PL_origalen;
2194             /* don't allow system to limit $0 seen by script */
2195             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
2196             Copy(s, PL_origargv[0], i, char);
2197             s = PL_origargv[0]+i;
2198             *s = '\0';
2199         }
2200         else {
2201             Copy(s, PL_origargv[0], i, char);
2202             s = PL_origargv[0]+i;
2203             *s++ = '\0';
2204             while (++i < PL_origalen)
2205                 *s++ = ' ';
2206             s = PL_origargv[0]+i;
2207             for (i = 1; i < PL_origargc; i++)
2208                 PL_origargv[i] = Nullch;
2209         }
2210         break;
2211 #endif
2212 #ifdef USE_5005THREADS
2213     case '@':
2214         sv_setsv(thr->errsv, sv);
2215         break;
2216 #endif /* USE_5005THREADS */
2217     }
2218     return 0;
2219 }
2220
2221 #ifdef USE_5005THREADS
2222 int
2223 Perl_magic_mutexfree(pTHX_ SV *sv, MAGIC *mg)
2224 {
2225     DEBUG_S(PerlIO_printf(Perl_debug_log,
2226                           "0x%"UVxf": magic_mutexfree 0x%"UVxf"\n",
2227                           PTR2UV(thr), PTR2UV(sv)));
2228     if (MgOWNER(mg))
2229         Perl_croak(aTHX_ "panic: magic_mutexfree");
2230     MUTEX_DESTROY(MgMUTEXP(mg));
2231     COND_DESTROY(MgCONDP(mg));
2232     return 0;
2233 }
2234 #endif /* USE_5005THREADS */
2235
2236 I32
2237 Perl_whichsig(pTHX_ char *sig)
2238 {
2239     register char **sigv;
2240
2241     for (sigv = PL_sig_name+1; *sigv; sigv++)
2242         if (strEQ(sig,*sigv))
2243             return PL_sig_num[sigv - PL_sig_name];
2244 #ifdef SIGCLD
2245     if (strEQ(sig,"CHLD"))
2246         return SIGCLD;
2247 #endif
2248 #ifdef SIGCHLD
2249     if (strEQ(sig,"CLD"))
2250         return SIGCHLD;
2251 #endif
2252     return 0;
2253 }
2254
2255 #if !defined(PERL_IMPLICIT_CONTEXT)
2256 static SV* sig_sv;
2257 #endif
2258
2259 Signal_t
2260 Perl_sighandler(int sig)
2261 {
2262 #if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2263     dTHXa(PL_curinterp);        /* fake TLS, because signals don't do TLS */
2264 #else
2265     dTHX;
2266 #endif
2267     dSP;
2268     GV *gv = Nullgv;
2269     HV *st;
2270     SV *sv = Nullsv, *tSv = PL_Sv;
2271     CV *cv = Nullcv;
2272     OP *myop = PL_op;
2273     U32 flags = 0;
2274     XPV *tXpv = PL_Xpv;
2275
2276 #if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2277     PERL_SET_THX(aTHX); /* fake TLS, see above */
2278 #endif
2279
2280     if (PL_savestack_ix + 15 <= PL_savestack_max)
2281         flags |= 1;
2282     if (PL_markstack_ptr < PL_markstack_max - 2)
2283         flags |= 4;
2284     if (PL_retstack_ix < PL_retstack_max - 2)
2285         flags |= 8;
2286     if (PL_scopestack_ix < PL_scopestack_max - 3)
2287         flags |= 16;
2288
2289     if (!PL_psig_ptr[sig])
2290         Perl_die(aTHX_ "Signal SIG%s received, but no signal handler set.\n",
2291             PL_sig_name[sig]);
2292
2293     /* Max number of items pushed there is 3*n or 4. We cannot fix
2294        infinity, so we fix 4 (in fact 5): */
2295     if (flags & 1) {
2296         PL_savestack_ix += 5;           /* Protect save in progress. */
2297         SAVEDESTRUCTOR_X(unwind_handler_stack, (void*)&flags);
2298     }
2299     if (flags & 4)
2300         PL_markstack_ptr++;             /* Protect mark. */
2301     if (flags & 8) {
2302         PL_retstack_ix++;
2303         PL_retstack[PL_retstack_ix] = NULL;
2304     }
2305     if (flags & 16)
2306         PL_scopestack_ix += 1;
2307     /* sv_2cv is too complicated, try a simpler variant first: */
2308     if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
2309         || SvTYPE(cv) != SVt_PVCV)
2310         cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
2311
2312     if (!cv || !CvROOT(cv)) {
2313         if (ckWARN(WARN_SIGNAL))
2314             Perl_warner(aTHX_ WARN_SIGNAL, "SIG%s handler \"%s\" not defined.\n",
2315                 PL_sig_name[sig], (gv ? GvENAME(gv)
2316                                 : ((cv && CvGV(cv))
2317                                    ? GvENAME(CvGV(cv))
2318                                    : "__ANON__")));
2319         goto cleanup;
2320     }
2321
2322     if(PL_psig_name[sig]) {
2323         sv = SvREFCNT_inc(PL_psig_name[sig]);
2324         flags |= 64;
2325 #if !defined(PERL_IMPLICIT_CONTEXT)
2326         sig_sv = sv;
2327 #endif
2328     } else {
2329         sv = sv_newmortal();
2330         sv_setpv(sv,PL_sig_name[sig]);
2331     }
2332
2333     PUSHSTACKi(PERLSI_SIGNAL);
2334     PUSHMARK(SP);
2335     PUSHs(sv);
2336     PUTBACK;
2337
2338     call_sv((SV*)cv, G_DISCARD|G_EVAL);
2339
2340     POPSTACK;
2341     if (SvTRUE(ERRSV)) {
2342 #ifndef PERL_MICRO
2343 #ifdef HAS_SIGPROCMASK
2344         /* Handler "died", for example to get out of a restart-able read().
2345          * Before we re-do that on its behalf re-enable the signal which was
2346          * blocked by the system when we entered.
2347          */
2348         sigset_t set;
2349         sigemptyset(&set);
2350         sigaddset(&set,sig);
2351         sigprocmask(SIG_UNBLOCK, &set, NULL);
2352 #else
2353         /* Not clear if this will work */
2354         (void)rsignal(sig, SIG_IGN);
2355         (void)rsignal(sig, &Perl_csighandler);
2356 #endif
2357 #endif /* !PERL_MICRO */
2358         Perl_die(aTHX_ Nullformat);
2359     }
2360 cleanup:
2361     if (flags & 1)
2362         PL_savestack_ix -= 8; /* Unprotect save in progress. */
2363     if (flags & 4)
2364         PL_markstack_ptr--;
2365     if (flags & 8)
2366         PL_retstack_ix--;
2367     if (flags & 16)
2368         PL_scopestack_ix -= 1;
2369     if (flags & 64)
2370         SvREFCNT_dec(sv);
2371     PL_op = myop;                       /* Apparently not needed... */
2372
2373     PL_Sv = tSv;                        /* Restore global temporaries. */
2374     PL_Xpv = tXpv;
2375     return;
2376 }
2377
2378
2379 static void
2380 restore_magic(pTHX_ void *p)
2381 {
2382     MGS* mgs = SSPTR(PTR2IV(p), MGS*);
2383     SV* sv = mgs->mgs_sv;
2384
2385     if (!sv)
2386         return;
2387
2388     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
2389     {
2390         if (mgs->mgs_flags)
2391             SvFLAGS(sv) |= mgs->mgs_flags;
2392         else
2393             mg_magical(sv);
2394         if (SvGMAGICAL(sv))
2395             SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
2396     }
2397
2398     mgs->mgs_sv = NULL;  /* mark the MGS structure as restored */
2399
2400     /* If we're still on top of the stack, pop us off.  (That condition
2401      * will be satisfied if restore_magic was called explicitly, but *not*
2402      * if it's being called via leave_scope.)
2403      * The reason for doing this is that otherwise, things like sv_2cv()
2404      * may leave alloc gunk on the savestack, and some code
2405      * (e.g. sighandler) doesn't expect that...
2406      */
2407     if (PL_savestack_ix == mgs->mgs_ss_ix)
2408     {
2409         I32 popval = SSPOPINT;
2410         assert(popval == SAVEt_DESTRUCTOR_X);
2411         PL_savestack_ix -= 2;
2412         popval = SSPOPINT;
2413         assert(popval == SAVEt_ALLOC);
2414         popval = SSPOPINT;
2415         PL_savestack_ix -= popval;
2416     }
2417
2418 }
2419
2420 static void
2421 unwind_handler_stack(pTHX_ void *p)
2422 {
2423     U32 flags = *(U32*)p;
2424
2425     if (flags & 1)
2426         PL_savestack_ix -= 5; /* Unprotect save in progress. */
2427     /* cxstack_ix-- Not needed, die already unwound it. */
2428 #if !defined(PERL_IMPLICIT_CONTEXT)
2429     if (flags & 64)
2430         SvREFCNT_dec(sig_sv);
2431 #endif
2432 }