Consolidated patch to 5.004_64
[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                     break;
465                 }
466             }
467         }
468         sv_setsv(sv,&sv_undef);
469         break;
470     case '+':
471         if (curpm && (rx = curpm->op_pmregexp)) {
472             paren = rx->lastparen;
473             if (paren)
474                 goto getparen;
475         }
476         sv_setsv(sv,&sv_undef);
477         break;
478     case '`':
479         if (curpm && (rx = curpm->op_pmregexp)) {
480             if ((s = rx->subbeg) && rx->startp[0]) {
481                 i = rx->startp[0] - s;
482                 goto getrx;
483             }
484         }
485         sv_setsv(sv,&sv_undef);
486         break;
487     case '\'':
488         if (curpm && (rx = curpm->op_pmregexp)) {
489             if (rx->subend && (s = rx->endp[0])) {
490                 i = rx->subend - s;
491                 goto getrx;
492             }
493         }
494         sv_setsv(sv,&sv_undef);
495         break;
496     case '.':
497 #ifndef lint
498         if (GvIO(last_in_gv)) {
499             sv_setiv(sv, (IV)IoLINES(GvIO(last_in_gv)));
500         }
501 #endif
502         break;
503     case '?':
504         {
505             dTHR;
506             sv_setiv(sv, (IV)STATUS_CURRENT);
507 #ifdef COMPLEX_STATUS
508             LvTARGOFF(sv) = statusvalue;
509             LvTARGLEN(sv) = statusvalue_vms;
510 #endif
511         }
512         break;
513     case '^':
514         s = IoTOP_NAME(GvIOp(defoutgv));
515         if (s)
516             sv_setpv(sv,s);
517         else {
518             sv_setpv(sv,GvENAME(defoutgv));
519             sv_catpv(sv,"_TOP");
520         }
521         break;
522     case '~':
523         s = IoFMT_NAME(GvIOp(defoutgv));
524         if (!s)
525             s = GvENAME(defoutgv);
526         sv_setpv(sv,s);
527         break;
528 #ifndef lint
529     case '=':
530         sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(defoutgv)));
531         break;
532     case '-':
533         sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(defoutgv)));
534         break;
535     case '%':
536         sv_setiv(sv, (IV)IoPAGE(GvIOp(defoutgv)));
537         break;
538 #endif
539     case ':':
540         break;
541     case '/':
542         break;
543     case '[':
544         WITH_THR(sv_setiv(sv, (IV)curcop->cop_arybase));
545         break;
546     case '|':
547         sv_setiv(sv, (IV)(IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
548         break;
549     case ',':
550         sv_setpvn(sv,ofs,ofslen);
551         break;
552     case '\\':
553         sv_setpvn(sv,ors,orslen);
554         break;
555     case '#':
556         sv_setpv(sv,ofmt);
557         break;
558     case '!':
559 #ifdef VMS
560         sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
561         sv_setpv(sv, errno ? Strerror(errno) : "");
562 #else
563         {
564         int saveerrno = errno;
565         sv_setnv(sv, (double)errno);
566 #ifdef OS2
567         if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
568         else
569 #endif
570         sv_setpv(sv, errno ? Strerror(errno) : "");
571         errno = saveerrno;
572         }
573 #endif
574         SvNOK_on(sv);   /* what a wonderful hack! */
575         break;
576     case '<':
577         sv_setiv(sv, (IV)uid);
578         break;
579     case '>':
580         sv_setiv(sv, (IV)euid);
581         break;
582     case '(':
583         sv_setiv(sv, (IV)gid);
584         sv_setpvf(sv, "%Vd", (IV)gid);
585         goto add_groups;
586     case ')':
587         sv_setiv(sv, (IV)egid);
588         sv_setpvf(sv, "%Vd", (IV)egid);
589       add_groups:
590 #ifdef HAS_GETGROUPS
591         {
592             Groups_t gary[NGROUPS];
593             i = getgroups(NGROUPS,gary);
594             while (--i >= 0)
595                 sv_catpvf(sv, " %Vd", (IV)gary[i]);
596         }
597 #endif
598         SvIOK_on(sv);   /* what a wonderful hack! */
599         break;
600     case '*':
601         break;
602     case '0':
603         break;
604 #ifdef USE_THREADS
605     case '@':
606         sv_setsv(sv, thr->errsv);
607         break;
608 #endif /* USE_THREADS */
609     }
610     return 0;
611 }
612
613 int
614 magic_getuvar(SV *sv, MAGIC *mg)
615 {
616     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
617
618     if (uf && uf->uf_val)
619         (*uf->uf_val)(uf->uf_index, sv);
620     return 0;
621 }
622
623 int
624 magic_setenv(SV *sv, MAGIC *mg)
625 {
626     register char *s;
627     char *ptr;
628     STRLEN len, klen;
629     I32 i;
630
631     s = SvPV(sv,len);
632     ptr = MgPV(mg,klen);
633     my_setenv(ptr, s);
634
635 #ifdef DYNAMIC_ENV_FETCH
636      /* We just undefd an environment var.  Is a replacement */
637      /* waiting in the wings? */
638     if (!len) {
639         SV **valp;
640         if ((valp = hv_fetch(GvHVn(envgv), ptr, klen, FALSE)))
641             s = SvPV(*valp, len);
642     }
643 #endif
644
645 #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
646                             /* And you'll never guess what the dog had */
647                             /*   in its mouth... */
648     if (tainting) {
649         MgTAINTEDDIR_off(mg);
650 #ifdef VMS
651         if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
652             char pathbuf[256], eltbuf[256], *cp, *elt = s;
653             struct stat sbuf;
654             int i = 0, j = 0;
655
656             do {          /* DCL$PATH may be a search list */
657                 while (1) {   /* as may dev portion of any element */
658                     if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
659                         if ( *(cp+1) == '.' || *(cp+1) == '-' ||
660                              cando_by_name(S_IWUSR,0,elt) ) {
661                             MgTAINTEDDIR_on(mg);
662                             return 0;
663                         }
664                     }
665                     if ((cp = strchr(elt, ':')) != Nullch)
666                         *cp = '\0';
667                     if (my_trnlnm(elt, eltbuf, j++))
668                         elt = eltbuf;
669                     else
670                         break;
671                 }
672                 j = 0;
673             } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
674         }
675 #endif /* VMS */
676         if (s && klen == 4 && strEQ(ptr,"PATH")) {
677             char *strend = s + len;
678
679             while (s < strend) {
680                 char tmpbuf[256];
681                 struct stat st;
682                 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
683                              s, strend, ':', &i);
684                 s++;
685                 if (i >= sizeof tmpbuf   /* too long -- assume the worst */
686                       || *tmpbuf != '/'
687                       || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
688                     MgTAINTEDDIR_on(mg);
689                     return 0;
690                 }
691             }
692         }
693     }
694 #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
695
696     return 0;
697 }
698
699 int
700 magic_clearenv(SV *sv, MAGIC *mg)
701 {
702     my_setenv(MgPV(mg,na),Nullch);
703     return 0;
704 }
705
706 int
707 magic_set_all_env(SV *sv, MAGIC *mg)
708 {
709 #if defined(VMS)
710     die("Can't make list assignment to %%ENV on this system");
711 #else
712     dTHR;
713     if (localizing) {
714         HE* entry;
715         magic_clear_all_env(sv,mg);
716         hv_iterinit((HV*)sv);
717         while (entry = hv_iternext((HV*)sv)) {
718             I32 keylen;
719             my_setenv(hv_iterkey(entry, &keylen),
720                       SvPV(hv_iterval((HV*)sv, entry), na));
721         }
722     }
723 #endif
724     return 0;
725 }
726
727 int
728 magic_clear_all_env(SV *sv, MAGIC *mg)
729 {
730 #if defined(VMS)
731     die("Can't make list assignment to %%ENV on this system");
732 #else
733 #ifdef WIN32
734     char *envv = GetEnvironmentStrings();
735     char *cur = envv;
736     STRLEN len;
737     while (*cur) {
738         char *end = strchr(cur,'=');
739         if (end && end != cur) {
740             *end = '\0';
741             my_setenv(cur,Nullch);
742             *end = '=';
743             cur += strlen(end+1)+1;
744         }
745         else if ((len = strlen(cur)))
746             cur += len+1;
747     }
748     FreeEnvironmentStrings(envv);
749 #else
750     I32 i;
751
752     if (environ == origenviron)
753         New(901, environ, 1, char*);
754     else
755         for (i = 0; environ[i]; i++)
756             Safefree(environ[i]);
757     environ[0] = Nullch;
758
759 #endif
760 #endif
761     return 0;
762 }
763
764 int
765 magic_getsig(SV *sv, MAGIC *mg)
766 {
767     I32 i;
768     /* Are we fetching a signal entry? */
769     i = whichsig(MgPV(mg,na));
770     if (i) {
771         if(psig_ptr[i])
772             sv_setsv(sv,psig_ptr[i]);
773         else {
774             Sighandler_t sigstate = rsignal_state(i);
775
776             /* cache state so we don't fetch it again */
777             if(sigstate == SIG_IGN)
778                 sv_setpv(sv,"IGNORE");
779             else
780                 sv_setsv(sv,&sv_undef);
781             psig_ptr[i] = SvREFCNT_inc(sv);
782             SvTEMP_off(sv);
783         }
784     }
785     return 0;
786 }
787 int
788 magic_clearsig(SV *sv, MAGIC *mg)
789 {
790     I32 i;
791     /* Are we clearing a signal entry? */
792     i = whichsig(MgPV(mg,na));
793     if (i) {
794         if(psig_ptr[i]) {
795             SvREFCNT_dec(psig_ptr[i]);
796             psig_ptr[i]=0;
797         }
798         if(psig_name[i]) {
799             SvREFCNT_dec(psig_name[i]);
800             psig_name[i]=0;
801         }
802     }
803     return 0;
804 }
805
806 int
807 magic_setsig(SV *sv, MAGIC *mg)
808 {
809     dTHR;
810     register char *s;
811     I32 i;
812     SV** svp;
813
814     s = MgPV(mg,na);
815     if (*s == '_') {
816         if (strEQ(s,"__DIE__"))
817             svp = &diehook;
818         else if (strEQ(s,"__WARN__"))
819             svp = &warnhook;
820         else if (strEQ(s,"__PARSE__"))
821             svp = &parsehook;
822         else
823             croak("No such hook: %s", s);
824         i = 0;
825         if (*svp) {
826             SvREFCNT_dec(*svp);
827             *svp = 0;
828         }
829     }
830     else {
831         i = whichsig(s);        /* ...no, a brick */
832         if (!i) {
833             if (dowarn || strEQ(s,"ALARM"))
834                 warn("No such signal: SIG%s", s);
835             return 0;
836         }
837         SvREFCNT_dec(psig_name[i]);
838         SvREFCNT_dec(psig_ptr[i]);
839         psig_ptr[i] = SvREFCNT_inc(sv);
840         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
841         psig_name[i] = newSVpv(s, strlen(s));
842         SvREADONLY_on(psig_name[i]);
843     }
844     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
845         if (i)
846             (void)rsignal(i, sighandlerp);
847         else
848             *svp = SvREFCNT_inc(sv);
849         return 0;
850     }
851     s = SvPV_force(sv,na);
852     if (strEQ(s,"IGNORE")) {
853         if (i)
854             (void)rsignal(i, SIG_IGN);
855         else
856             *svp = 0;
857     }
858     else if (strEQ(s,"DEFAULT") || !*s) {
859         if (i)
860             (void)rsignal(i, SIG_DFL);
861         else
862             *svp = 0;
863     }
864     else {
865         /*
866          * We should warn if HINT_STRICT_REFS, but without
867          * access to a known hint bit in a known OP, we can't
868          * tell whether HINT_STRICT_REFS is in force or not.
869          */
870         if (!strchr(s,':') && !strchr(s,'\''))
871             sv_setpv(sv, form("main::%s", s));
872         if (i)
873             (void)rsignal(i, sighandlerp);
874         else
875             *svp = SvREFCNT_inc(sv);
876     }
877     return 0;
878 }
879
880 int
881 magic_setisa(SV *sv, MAGIC *mg)
882 {
883     HV *stash;
884     SV **svp;
885     I32 fill;
886     HV *basefields = Nullhv;
887     GV **gvp;
888     GV *gv;
889     HE *he;
890     static char *FIELDS = "FIELDS";
891
892     sub_generation++;
893
894     if (mg->mg_type == 'i')
895         return 0;       /* Ignore lower-case version of the magic */
896
897     stash = GvSTASH(mg->mg_obj);
898     svp = AvARRAY((AV*)sv);
899                 
900     /* NOTE: No support for tied ISA */
901     for (fill = AvFILLp((AV*)sv); fill >= 0; fill--, svp++) {
902         HV *basestash = gv_stashsv(*svp, FALSE);
903
904         if (!basestash) {
905             if (dowarn)
906                 warn("No such package \"%_\" in @ISA assignment", *svp);
907             continue;
908         }
909         gvp = (GV**)hv_fetch(basestash, FIELDS, 6, FALSE);
910         if (gvp && *gvp && GvHV(*gvp)) {
911             if (basefields)
912                 croak("Can't multiply inherit %%FIELDS");
913             basefields = GvHV(*gvp);
914         }
915     }
916
917     if (!basefields)
918         return 0;
919     
920     gv = (GV*)*hv_fetch(stash, FIELDS, 6, TRUE);
921     if (!isGV(gv))
922         gv_init(gv, stash, FIELDS, 6, TRUE);
923     if (!GvHV(gv))
924         GvHV(gv) = newHV();
925     if (HvKEYS(GvHV(gv)))
926         croak("Inherited %%FIELDS can't override existing %%FIELDS");
927
928     hv_iterinit(GvHV(gv));
929     while ((he = hv_iternext(basefields)))
930         hv_store(GvHV(gv), HeKEY(he), HeKLEN(he), HeVAL(he), HeHASH(he));
931
932     return 0;
933 }
934
935 #ifdef OVERLOAD
936
937 int
938 magic_setamagic(SV *sv, MAGIC *mg)
939 {
940     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
941     amagic_generation++;
942
943     return 0;
944 }
945 #endif /* OVERLOAD */
946
947 int
948 magic_setnkeys(SV *sv, MAGIC *mg)
949 {
950     if (LvTARG(sv)) {
951         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
952         LvTARG(sv) = Nullsv;    /* Don't allow a ref to reassign this. */
953     }
954     return 0;
955 }          
956
957 /* caller is responsible for stack switching/cleanup */
958 static int
959 magic_methcall(MAGIC *mg, char *meth, I32 flags, int n, SV *val)
960 {
961     dSP;
962
963     PUSHMARK(SP);
964     EXTEND(SP, n);
965     PUSHs(mg->mg_obj);
966     if (n > 1) { 
967         if (mg->mg_ptr) {
968             if (mg->mg_len >= 0)
969                 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
970             else if (mg->mg_len == HEf_SVKEY)
971                 PUSHs((SV*)mg->mg_ptr);
972         }
973         else if (mg->mg_type == 'p') {
974             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
975         }
976     }
977     if (n > 2) {
978         PUSHs(val);
979     }
980     PUTBACK;
981
982     return perl_call_method(meth, flags);
983 }
984
985 static int
986 magic_methpack(SV *sv, MAGIC *mg, char *meth)
987 {
988     dSP;
989
990     ENTER;
991     SAVETMPS;
992     PUSHSTACK(SI_MAGIC);
993
994     if (magic_methcall(mg, meth, G_SCALAR, 2, NULL)) {
995         sv_setsv(sv, *stack_sp--);
996     }
997
998     POPSTACK();
999     FREETMPS;
1000     LEAVE;
1001     return 0;
1002 }
1003
1004 int
1005 magic_getpack(SV *sv, MAGIC *mg)
1006 {
1007     magic_methpack(sv,mg,"FETCH");
1008     if (mg->mg_ptr)
1009         mg->mg_flags |= MGf_GSKIP;
1010     return 0;
1011 }
1012
1013 int
1014 magic_setpack(SV *sv, MAGIC *mg)
1015 {
1016     dSP;
1017     ENTER;
1018     PUSHSTACK(SI_MAGIC);
1019     magic_methcall(mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1020     POPSTACK();
1021     LEAVE;
1022     return 0;
1023 }
1024
1025 int
1026 magic_clearpack(SV *sv, MAGIC *mg)
1027 {
1028     return magic_methpack(sv,mg,"DELETE");
1029 }
1030
1031
1032 U32
1033 magic_sizepack(SV *sv, MAGIC *mg)
1034 {         
1035     dSP;
1036     U32 retval = 0;
1037
1038     ENTER;
1039     SAVETMPS;
1040     PUSHSTACK(SI_MAGIC);
1041     if (magic_methcall(mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1042         sv = *stack_sp--;
1043         retval = (U32) SvIV(sv)-1;
1044     }
1045     POPSTACK();
1046     FREETMPS;
1047     LEAVE;
1048     return retval;
1049 }
1050
1051 int magic_wipepack(SV *sv, MAGIC *mg)
1052 {
1053     dSP;
1054
1055     ENTER;
1056     PUSHSTACK(SI_MAGIC);
1057     PUSHMARK(SP);
1058     XPUSHs(mg->mg_obj);
1059     PUTBACK;
1060     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
1061     POPSTACK();
1062     LEAVE;
1063     return 0;
1064 }
1065
1066 int
1067 magic_nextpack(SV *sv, MAGIC *mg, SV *key)
1068 {
1069     dSP;
1070     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1071
1072     ENTER;
1073     SAVETMPS;
1074     PUSHSTACK(SI_MAGIC);
1075     PUSHMARK(SP);
1076     EXTEND(SP, 2);
1077     PUSHs(mg->mg_obj);
1078     if (SvOK(key))
1079         PUSHs(key);
1080     PUTBACK;
1081
1082     if (perl_call_method(meth, G_SCALAR))
1083         sv_setsv(key, *stack_sp--);
1084
1085     POPSTACK();
1086     FREETMPS;
1087     LEAVE;
1088     return 0;
1089 }
1090
1091 int
1092 magic_existspack(SV *sv, MAGIC *mg)
1093 {
1094     return magic_methpack(sv,mg,"EXISTS");
1095
1096
1097 int
1098 magic_setdbline(SV *sv, MAGIC *mg)
1099 {
1100     dTHR;
1101     OP *o;
1102     I32 i;
1103     GV* gv;
1104     SV** svp;
1105
1106     gv = DBline;
1107     i = SvTRUE(sv);
1108     svp = av_fetch(GvAV(gv),
1109                      atoi(MgPV(mg,na)), FALSE);
1110     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
1111         o->op_private = i;
1112     else
1113         warn("Can't break at that line\n");
1114     return 0;
1115 }
1116
1117 int
1118 magic_getarylen(SV *sv, MAGIC *mg)
1119 {
1120     dTHR;
1121     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
1122     return 0;
1123 }
1124
1125 int
1126 magic_setarylen(SV *sv, MAGIC *mg)
1127 {
1128     dTHR;
1129     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
1130     return 0;
1131 }
1132
1133 int
1134 magic_getpos(SV *sv, MAGIC *mg)
1135 {
1136     SV* lsv = LvTARG(sv);
1137     
1138     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1139         mg = mg_find(lsv, 'g');
1140         if (mg && mg->mg_len >= 0) {
1141             dTHR;
1142             sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
1143             return 0;
1144         }
1145     }
1146     (void)SvOK_off(sv);
1147     return 0;
1148 }
1149
1150 int
1151 magic_setpos(SV *sv, MAGIC *mg)
1152 {
1153     SV* lsv = LvTARG(sv);
1154     SSize_t pos;
1155     STRLEN len;
1156
1157     mg = 0;
1158     
1159     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1160         mg = mg_find(lsv, 'g');
1161     if (!mg) {
1162         if (!SvOK(sv))
1163             return 0;
1164         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1165         mg = mg_find(lsv, 'g');
1166     }
1167     else if (!SvOK(sv)) {
1168         mg->mg_len = -1;
1169         return 0;
1170     }
1171     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1172
1173     WITH_THR(pos = SvIV(sv) - curcop->cop_arybase);
1174     if (pos < 0) {
1175         pos += len;
1176         if (pos < 0)
1177             pos = 0;
1178     }
1179     else if (pos > len)
1180         pos = len;
1181     mg->mg_len = pos;
1182     mg->mg_flags &= ~MGf_MINMATCH;
1183
1184     return 0;
1185 }
1186
1187 int
1188 magic_getglob(SV *sv, MAGIC *mg)
1189 {
1190     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1191         SvFAKE_off(sv);
1192         gv_efullname3(sv,((GV*)sv), "*");
1193         SvFAKE_on(sv);
1194     }
1195     else
1196         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1197     return 0;
1198 }
1199
1200 int
1201 magic_setglob(SV *sv, MAGIC *mg)
1202 {
1203     register char *s;
1204     GV* gv;
1205
1206     if (!SvOK(sv))
1207         return 0;
1208     s = SvPV(sv, na);
1209     if (*s == '*' && s[1])
1210         s++;
1211     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1212     if (sv == (SV*)gv)
1213         return 0;
1214     if (GvGP(sv))
1215         gp_free((GV*)sv);
1216     GvGP(sv) = gp_ref(GvGP(gv));
1217     return 0;
1218 }
1219
1220 int
1221 magic_setsubstr(SV *sv, MAGIC *mg)
1222 {
1223     STRLEN len;
1224     char *tmps = SvPV(sv,len);
1225     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1226     return 0;
1227 }
1228
1229 int
1230 magic_gettaint(SV *sv, MAGIC *mg)
1231 {
1232     dTHR;
1233     TAINT_IF((mg->mg_len & 1) ||
1234              (mg->mg_len & 2) && mg->mg_obj == sv);     /* kludge */
1235     return 0;
1236 }
1237
1238 int
1239 magic_settaint(SV *sv, MAGIC *mg)
1240 {
1241     dTHR;
1242     if (localizing) {
1243         if (localizing == 1)
1244             mg->mg_len <<= 1;
1245         else
1246             mg->mg_len >>= 1;
1247     }
1248     else if (tainted)
1249         mg->mg_len |= 1;
1250     else
1251         mg->mg_len &= ~1;
1252     return 0;
1253 }
1254
1255 int
1256 magic_setvec(SV *sv, MAGIC *mg)
1257 {
1258     do_vecset(sv);      /* XXX slurp this routine */
1259     return 0;
1260 }
1261
1262 int
1263 magic_getdefelem(SV *sv, MAGIC *mg)
1264 {
1265     SV *targ = Nullsv;
1266     if (LvTARGLEN(sv)) {
1267         if (mg->mg_obj) {
1268             HV* hv = (HV*)LvTARG(sv);
1269             HE* he = hv_fetch_ent(hv, mg->mg_obj, FALSE, 0);
1270             if (he)
1271                 targ = HeVAL(he);
1272         }
1273         else {
1274             AV* av = (AV*)LvTARG(sv); 
1275             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1276                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1277         }
1278         if (targ && targ != &sv_undef) {
1279             dTHR;               /* just for SvREFCNT_dec */
1280             /* somebody else defined it for us */
1281             SvREFCNT_dec(LvTARG(sv));
1282             LvTARG(sv) = SvREFCNT_inc(targ);
1283             LvTARGLEN(sv) = 0;
1284             SvREFCNT_dec(mg->mg_obj);
1285             mg->mg_obj = Nullsv;
1286             mg->mg_flags &= ~MGf_REFCOUNTED;
1287         }
1288     }
1289     else
1290         targ = LvTARG(sv);
1291     sv_setsv(sv, targ ? targ : &sv_undef);
1292     return 0;
1293 }
1294
1295 int
1296 magic_setdefelem(SV *sv, MAGIC *mg)
1297 {
1298     if (LvTARGLEN(sv))
1299         vivify_defelem(sv);
1300     if (LvTARG(sv)) {
1301         sv_setsv(LvTARG(sv), sv);
1302         SvSETMAGIC(LvTARG(sv));
1303     }
1304     return 0;
1305 }
1306
1307 int
1308 magic_freedefelem(SV *sv, MAGIC *mg)
1309 {
1310     SvREFCNT_dec(LvTARG(sv));
1311     return 0;
1312 }
1313
1314 void
1315 vivify_defelem(SV *sv)
1316 {
1317     dTHR;                       /* just for SvREFCNT_inc and SvREFCNT_dec*/
1318     MAGIC* mg;
1319     SV* value;
1320
1321     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
1322         return;
1323     if (mg->mg_obj) {
1324         HV* hv = (HV*)LvTARG(sv);
1325         HE* he = hv_fetch_ent(hv, mg->mg_obj, TRUE, 0);
1326         if (!he || (value = HeVAL(he)) == &sv_undef)
1327             croak(no_helem, SvPV(mg->mg_obj, na));
1328     }
1329     else {
1330         AV* av = (AV*)LvTARG(sv);
1331         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1332             LvTARG(sv) = Nullsv;        /* array can't be extended */
1333         else {
1334             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1335             if (!svp || (value = *svp) == &sv_undef)
1336                 croak(no_aelem, (I32)LvTARGOFF(sv));
1337         }
1338     }
1339     (void)SvREFCNT_inc(value);
1340     SvREFCNT_dec(LvTARG(sv));
1341     LvTARG(sv) = value;
1342     LvTARGLEN(sv) = 0;
1343     SvREFCNT_dec(mg->mg_obj);
1344     mg->mg_obj = Nullsv;
1345     mg->mg_flags &= ~MGf_REFCOUNTED;
1346 }
1347
1348 int
1349 magic_setmglob(SV *sv, MAGIC *mg)
1350 {
1351     mg->mg_len = -1;
1352     SvSCREAM_off(sv);
1353     return 0;
1354 }
1355
1356 int
1357 magic_setbm(SV *sv, MAGIC *mg)
1358 {
1359     sv_unmagic(sv, 'B');
1360     SvVALID_off(sv);
1361     return 0;
1362 }
1363
1364 int
1365 magic_setfm(SV *sv, MAGIC *mg)
1366 {
1367     sv_unmagic(sv, 'f');
1368     SvCOMPILED_off(sv);
1369     return 0;
1370 }
1371
1372 int
1373 magic_setuvar(SV *sv, MAGIC *mg)
1374 {
1375     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1376
1377     if (uf && uf->uf_set)
1378         (*uf->uf_set)(uf->uf_index, sv);
1379     return 0;
1380 }
1381
1382 int
1383 magic_freeregexp(SV *sv, MAGIC *mg)
1384 {
1385     regexp *re = (regexp *)mg->mg_obj;
1386     ReREFCNT_dec(re);
1387     return 0;
1388 }
1389
1390 #ifdef USE_LOCALE_COLLATE
1391 int
1392 magic_setcollxfrm(SV *sv, MAGIC *mg)
1393 {
1394     /*
1395      * René Descartes said "I think not."
1396      * and vanished with a faint plop.
1397      */
1398     if (mg->mg_ptr) {
1399         Safefree(mg->mg_ptr);
1400         mg->mg_ptr = NULL;
1401         mg->mg_len = -1;
1402     }
1403     return 0;
1404 }
1405 #endif /* USE_LOCALE_COLLATE */
1406
1407 int
1408 magic_set(SV *sv, MAGIC *mg)
1409 {
1410     dTHR;
1411     register char *s;
1412     I32 i;
1413     STRLEN len;
1414     switch (*mg->mg_ptr) {
1415     case '\001':        /* ^A */
1416         sv_setsv(bodytarget, sv);
1417         break;
1418     case '\004':        /* ^D */
1419         debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1420         DEBUG_x(dump_all());
1421         break;
1422     case '\005':  /* ^E */
1423 #ifdef VMS
1424         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1425 #else
1426 #ifdef WIN32
1427         SetLastError( SvIV(sv) );
1428 #else
1429         /* will anyone ever use this? */
1430         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1431 #endif
1432 #endif
1433         break;
1434     case '\006':        /* ^F */
1435         maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1436         break;
1437     case '\010':        /* ^H */
1438         hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1439         break;
1440     case '\t':  /* ^I */
1441         if (inplace)
1442             Safefree(inplace);
1443         if (SvOK(sv))
1444             inplace = savepv(SvPV(sv,na));
1445         else
1446             inplace = Nullch;
1447         break;
1448     case '\017':        /* ^O */
1449         if (osname)
1450             Safefree(osname);
1451         if (SvOK(sv))
1452             osname = savepv(SvPV(sv,na));
1453         else
1454             osname = Nullch;
1455         break;
1456     case '\020':        /* ^P */
1457         perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1458         break;
1459     case '\024':        /* ^T */
1460 #ifdef BIG_TIME
1461         basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1462 #else
1463         basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1464 #endif
1465         break;
1466     case '\027':        /* ^W */
1467         dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1468         break;
1469     case '.':
1470         if (localizing) {
1471             if (localizing == 1)
1472                 save_sptr((SV**)&last_in_gv);
1473         }
1474         else if (SvOK(sv) && GvIO(last_in_gv))
1475             IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
1476         break;
1477     case '^':
1478         Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1479         IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1480         IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1481         break;
1482     case '~':
1483         Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1484         IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1485         IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1486         break;
1487     case '=':
1488         IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1489         break;
1490     case '-':
1491         IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1492         if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1493             IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
1494         break;
1495     case '%':
1496         IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1497         break;
1498     case '|':
1499         {
1500             IO *io = GvIOp(defoutgv);
1501             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1502                 IoFLAGS(io) &= ~IOf_FLUSH;
1503             else {
1504                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1505                     PerlIO *ofp = IoOFP(io);
1506                     if (ofp)
1507                         (void)PerlIO_flush(ofp);
1508                     IoFLAGS(io) |= IOf_FLUSH;
1509                 }
1510             }
1511         }
1512         break;
1513     case '*':
1514         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1515         multiline = (i != 0);
1516         break;
1517     case '/':
1518         SvREFCNT_dec(nrs);
1519         nrs = newSVsv(sv);
1520         SvREFCNT_dec(rs);
1521         rs = SvREFCNT_inc(nrs);
1522         break;
1523     case '\\':
1524         if (ors)
1525             Safefree(ors);
1526         if (SvOK(sv) || SvGMAGICAL(sv))
1527             ors = savepv(SvPV(sv,orslen));
1528         else {
1529             ors = Nullch;
1530             orslen = 0;
1531         }
1532         break;
1533     case ',':
1534         if (ofs)
1535             Safefree(ofs);
1536         ofs = savepv(SvPV(sv, ofslen));
1537         break;
1538     case '#':
1539         if (ofmt)
1540             Safefree(ofmt);
1541         ofmt = savepv(SvPV(sv,na));
1542         break;
1543     case '[':
1544         compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1545         break;
1546     case '?':
1547 #ifdef COMPLEX_STATUS
1548         if (localizing == 2) {
1549             statusvalue = LvTARGOFF(sv);
1550             statusvalue_vms = LvTARGLEN(sv);
1551         }
1552         else
1553 #endif
1554 #ifdef VMSISH_STATUS
1555         if (VMSISH_STATUS)
1556             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1557         else
1558 #endif
1559             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1560         break;
1561     case '!':
1562         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1563                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1564         break;
1565     case '<':
1566         uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1567         if (delaymagic) {
1568             delaymagic |= DM_RUID;
1569             break;                              /* don't do magic till later */
1570         }
1571 #ifdef HAS_SETRUID
1572         (void)setruid((Uid_t)uid);
1573 #else
1574 #ifdef HAS_SETREUID
1575         (void)setreuid((Uid_t)uid, (Uid_t)-1);
1576 #else
1577 #ifdef HAS_SETRESUID
1578       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
1579 #else
1580         if (uid == euid)                /* special case $< = $> */
1581             (void)setuid(uid);
1582         else {
1583             uid = (I32)getuid();
1584             croak("setruid() not implemented");
1585         }
1586 #endif
1587 #endif
1588 #endif
1589         uid = (I32)getuid();
1590         tainting |= (uid && (euid != uid || egid != gid));
1591         break;
1592     case '>':
1593         euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1594         if (delaymagic) {
1595             delaymagic |= DM_EUID;
1596             break;                              /* don't do magic till later */
1597         }
1598 #ifdef HAS_SETEUID
1599         (void)seteuid((Uid_t)euid);
1600 #else
1601 #ifdef HAS_SETREUID
1602         (void)setreuid((Uid_t)-1, (Uid_t)euid);
1603 #else
1604 #ifdef HAS_SETRESUID
1605         (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
1606 #else
1607         if (euid == uid)                /* special case $> = $< */
1608             setuid(euid);
1609         else {
1610             euid = (I32)geteuid();
1611             croak("seteuid() not implemented");
1612         }
1613 #endif
1614 #endif
1615 #endif
1616         euid = (I32)geteuid();
1617         tainting |= (uid && (euid != uid || egid != gid));
1618         break;
1619     case '(':
1620         gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1621         if (delaymagic) {
1622             delaymagic |= DM_RGID;
1623             break;                              /* don't do magic till later */
1624         }
1625 #ifdef HAS_SETRGID
1626         (void)setrgid((Gid_t)gid);
1627 #else
1628 #ifdef HAS_SETREGID
1629         (void)setregid((Gid_t)gid, (Gid_t)-1);
1630 #else
1631 #ifdef HAS_SETRESGID
1632       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
1633 #else
1634         if (gid == egid)                        /* special case $( = $) */
1635             (void)setgid(gid);
1636         else {
1637             gid = (I32)getgid();
1638             croak("setrgid() not implemented");
1639         }
1640 #endif
1641 #endif
1642 #endif
1643         gid = (I32)getgid();
1644         tainting |= (uid && (euid != uid || egid != gid));
1645         break;
1646     case ')':
1647 #ifdef HAS_SETGROUPS
1648         {
1649             char *p = SvPV(sv, na);
1650             Groups_t gary[NGROUPS];
1651
1652             SET_NUMERIC_STANDARD();
1653             while (isSPACE(*p))
1654                 ++p;
1655             egid = I_V(atof(p));
1656             for (i = 0; i < NGROUPS; ++i) {
1657                 while (*p && !isSPACE(*p))
1658                     ++p;
1659                 while (isSPACE(*p))
1660                     ++p;
1661                 if (!*p)
1662                     break;
1663                 gary[i] = I_V(atof(p));
1664             }
1665             if (i)
1666                 (void)setgroups(i, gary);
1667         }
1668 #else  /* HAS_SETGROUPS */
1669         egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1670 #endif /* HAS_SETGROUPS */
1671         if (delaymagic) {
1672             delaymagic |= DM_EGID;
1673             break;                              /* don't do magic till later */
1674         }
1675 #ifdef HAS_SETEGID
1676         (void)setegid((Gid_t)egid);
1677 #else
1678 #ifdef HAS_SETREGID
1679         (void)setregid((Gid_t)-1, (Gid_t)egid);
1680 #else
1681 #ifdef HAS_SETRESGID
1682         (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
1683 #else
1684         if (egid == gid)                        /* special case $) = $( */
1685             (void)setgid(egid);
1686         else {
1687             egid = (I32)getegid();
1688             croak("setegid() not implemented");
1689         }
1690 #endif
1691 #endif
1692 #endif
1693         egid = (I32)getegid();
1694         tainting |= (uid && (euid != uid || egid != gid));
1695         break;
1696     case ':':
1697         chopset = SvPV_force(sv,na);
1698         break;
1699     case '0':
1700         if (!origalen) {
1701             s = origargv[0];
1702             s += strlen(s);
1703             /* See if all the arguments are contiguous in memory */
1704             for (i = 1; i < origargc; i++) {
1705                 if (origargv[i] == s + 1
1706 #ifdef OS2
1707                     || origargv[i] == s + 2
1708 #endif 
1709                    )
1710                     s += strlen(++s);   /* this one is ok too */
1711                 else
1712                     break;
1713             }
1714             /* can grab env area too? */
1715             if (origenviron && (origenviron[0] == s + 1
1716 #ifdef OS2
1717                                 || (origenviron[0] == s + 9 && (s += 8))
1718 #endif 
1719                )) {
1720                 my_setenv("NoNe  SuCh", Nullch);
1721                                             /* force copy of environment */
1722                 for (i = 0; origenviron[i]; i++)
1723                     if (origenviron[i] == s + 1)
1724                         s += strlen(++s);
1725                     else
1726                         break;
1727             }
1728             origalen = s - origargv[0];
1729         }
1730         s = SvPV_force(sv,len);
1731         i = len;
1732         if (i >= origalen) {
1733             i = origalen;
1734             /* don't allow system to limit $0 seen by script */
1735             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
1736             Copy(s, origargv[0], i, char);
1737             s = origargv[0]+i;
1738             *s = '\0';
1739         }
1740         else {
1741             Copy(s, origargv[0], i, char);
1742             s = origargv[0]+i;
1743             *s++ = '\0';
1744             while (++i < origalen)
1745                 *s++ = ' ';
1746             s = origargv[0]+i;
1747             for (i = 1; i < origargc; i++)
1748                 origargv[i] = Nullch;
1749         }
1750         break;
1751 #ifdef USE_THREADS
1752     case '@':
1753         sv_setsv(thr->errsv, sv);
1754         break;
1755 #endif /* USE_THREADS */
1756     }
1757     return 0;
1758 }
1759
1760 #ifdef USE_THREADS
1761 int
1762 magic_mutexfree(SV *sv, MAGIC *mg)
1763 {
1764     dTHR;
1765     DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
1766                           (unsigned long)thr, (unsigned long)sv);)
1767     if (MgOWNER(mg))
1768         croak("panic: magic_mutexfree");
1769     MUTEX_DESTROY(MgMUTEXP(mg));
1770     COND_DESTROY(MgCONDP(mg));
1771     SvREFCNT_dec(sv);
1772     return 0;
1773 }
1774 #endif /* USE_THREADS */
1775
1776 I32
1777 whichsig(char *sig)
1778 {
1779     register char **sigv;
1780
1781     for (sigv = sig_name+1; *sigv; sigv++)
1782         if (strEQ(sig,*sigv))
1783             return sig_num[sigv - sig_name];
1784 #ifdef SIGCLD
1785     if (strEQ(sig,"CHLD"))
1786         return SIGCLD;
1787 #endif
1788 #ifdef SIGCHLD
1789     if (strEQ(sig,"CLD"))
1790         return SIGCHLD;
1791 #endif
1792     return 0;
1793 }
1794
1795 static SV* sig_sv;
1796
1797 static void
1798 unwind_handler_stack(void *p)
1799 {
1800     dTHR;
1801     U32 flags = *(U32*)p;
1802
1803     if (flags & 1)
1804         savestack_ix -= 5; /* Unprotect save in progress. */
1805     /* cxstack_ix-- Not needed, die already unwound it. */
1806     if (flags & 64)
1807         SvREFCNT_dec(sig_sv);
1808 }
1809
1810 Signal_t
1811 sighandler(int sig)
1812 {
1813     dSP;
1814     GV *gv = Nullgv;
1815     HV *st;
1816     SV *sv, *tSv = Sv;
1817     CV *cv = Nullcv;
1818     OP *myop = op;
1819     U32 flags = 0;
1820     I32 o_save_i = savestack_ix, type;
1821     XPV *tXpv = Xpv;
1822     
1823     if (savestack_ix + 15 <= savestack_max)
1824         flags |= 1;
1825     if (markstack_ptr < markstack_max - 2)
1826         flags |= 4;
1827     if (retstack_ix < retstack_max - 2)
1828         flags |= 8;
1829     if (scopestack_ix < scopestack_max - 3)
1830         flags |= 16;
1831
1832     if (!psig_ptr[sig])
1833         die("Signal SIG%s received, but no signal handler set.\n",
1834             sig_name[sig]);
1835
1836     /* Max number of items pushed there is 3*n or 4. We cannot fix
1837        infinity, so we fix 4 (in fact 5): */
1838     if (flags & 1) {
1839         savestack_ix += 5;              /* Protect save in progress. */
1840         o_save_i = savestack_ix;
1841         SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags);
1842     }
1843     if (flags & 4) 
1844         markstack_ptr++;                /* Protect mark. */
1845     if (flags & 8) {
1846         retstack_ix++;
1847         retstack[retstack_ix] = NULL;
1848     }
1849     if (flags & 16)
1850         scopestack_ix += 1;
1851     /* sv_2cv is too complicated, try a simpler variant first: */
1852     if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) 
1853         || SvTYPE(cv) != SVt_PVCV)
1854         cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1855
1856     if (!cv || !CvROOT(cv)) {
1857         if (dowarn)
1858             warn("SIG%s handler \"%s\" not defined.\n",
1859                 sig_name[sig], (gv ? GvENAME(gv)
1860                                 : ((cv && CvGV(cv))
1861                                    ? GvENAME(CvGV(cv))
1862                                    : "__ANON__")));
1863         goto cleanup;
1864     }
1865
1866     if(psig_name[sig]) {
1867         sv = SvREFCNT_inc(psig_name[sig]);
1868         flags |= 64;
1869         sig_sv = sv;
1870     } else {
1871         sv = sv_newmortal();
1872         sv_setpv(sv,sig_name[sig]);
1873     }
1874
1875     PUSHSTACK(SI_SIGNAL);
1876     PUSHMARK(SP);
1877     PUSHs(sv);
1878     PUTBACK;
1879
1880     perl_call_sv((SV*)cv, G_DISCARD);
1881
1882     POPSTACK();
1883 cleanup:
1884     if (flags & 1)
1885         savestack_ix -= 8; /* Unprotect save in progress. */
1886     if (flags & 4) 
1887         markstack_ptr--;
1888     if (flags & 8) 
1889         retstack_ix--;
1890     if (flags & 16)
1891         scopestack_ix -= 1;
1892     if (flags & 64)
1893         SvREFCNT_dec(sv);
1894     op = myop;                  /* Apparently not needed... */
1895     
1896     Sv = tSv;                   /* Restore global temporaries. */
1897     Xpv = tXpv;
1898     return;
1899 }
1900
1901