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