Integrate win32 branch into mainline.
[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_getnkeys(SV *sv, MAGIC *mg)
950 {
951     HV *hv = (HV*)LvTARG(sv);
952     HE *entry;
953     I32 i = 0;
954
955     if (hv) {
956         (void) hv_iterinit(hv);
957         if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
958             i = HvKEYS(hv);
959         else {
960             /*SUPPRESS 560*/
961             while (entry = hv_iternext(hv)) {
962                 i++;
963             }
964         }
965     }
966
967     sv_setiv(sv, (IV)i);
968     return 0;
969 }
970
971 int
972 magic_setnkeys(SV *sv, MAGIC *mg)
973 {
974     if (LvTARG(sv)) {
975         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
976     }
977     return 0;
978 }          
979
980 /* caller is responsible for stack switching/cleanup */
981 static int
982 magic_methcall(MAGIC *mg, char *meth, I32 flags, int n, SV *val)
983 {
984     dSP;
985
986     PUSHMARK(SP);
987     EXTEND(SP, n);
988     PUSHs(mg->mg_obj);
989     if (n > 1) { 
990         if (mg->mg_ptr) {
991             if (mg->mg_len >= 0)
992                 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
993             else if (mg->mg_len == HEf_SVKEY)
994                 PUSHs((SV*)mg->mg_ptr);
995         }
996         else if (mg->mg_type == 'p') {
997             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
998         }
999     }
1000     if (n > 2) {
1001         PUSHs(val);
1002     }
1003     PUTBACK;
1004
1005     return perl_call_method(meth, flags);
1006 }
1007
1008 static int
1009 magic_methpack(SV *sv, MAGIC *mg, char *meth)
1010 {
1011     dSP;
1012
1013     ENTER;
1014     SAVETMPS;
1015     PUSHSTACK(SI_MAGIC);
1016
1017     if (magic_methcall(mg, meth, G_SCALAR, 2, NULL)) {
1018         sv_setsv(sv, *stack_sp--);
1019     }
1020
1021     POPSTACK();
1022     FREETMPS;
1023     LEAVE;
1024     return 0;
1025 }
1026
1027 int
1028 magic_getpack(SV *sv, MAGIC *mg)
1029 {
1030     magic_methpack(sv,mg,"FETCH");
1031     if (mg->mg_ptr)
1032         mg->mg_flags |= MGf_GSKIP;
1033     return 0;
1034 }
1035
1036 int
1037 magic_setpack(SV *sv, MAGIC *mg)
1038 {
1039     dSP;
1040     ENTER;
1041     PUSHSTACK(SI_MAGIC);
1042     magic_methcall(mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1043     POPSTACK();
1044     LEAVE;
1045     return 0;
1046 }
1047
1048 int
1049 magic_clearpack(SV *sv, MAGIC *mg)
1050 {
1051     return magic_methpack(sv,mg,"DELETE");
1052 }
1053
1054
1055 U32
1056 magic_sizepack(SV *sv, MAGIC *mg)
1057 {         
1058     dSP;
1059     U32 retval = 0;
1060
1061     ENTER;
1062     SAVETMPS;
1063     PUSHSTACK(SI_MAGIC);
1064     if (magic_methcall(mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1065         sv = *stack_sp--;
1066         retval = (U32) SvIV(sv)-1;
1067     }
1068     POPSTACK();
1069     FREETMPS;
1070     LEAVE;
1071     return retval;
1072 }
1073
1074 int magic_wipepack(SV *sv, MAGIC *mg)
1075 {
1076     dSP;
1077
1078     ENTER;
1079     PUSHSTACK(SI_MAGIC);
1080     PUSHMARK(SP);
1081     XPUSHs(mg->mg_obj);
1082     PUTBACK;
1083     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
1084     POPSTACK();
1085     LEAVE;
1086     return 0;
1087 }
1088
1089 int
1090 magic_nextpack(SV *sv, MAGIC *mg, SV *key)
1091 {
1092     dSP;
1093     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1094
1095     ENTER;
1096     SAVETMPS;
1097     PUSHSTACK(SI_MAGIC);
1098     PUSHMARK(SP);
1099     EXTEND(SP, 2);
1100     PUSHs(mg->mg_obj);
1101     if (SvOK(key))
1102         PUSHs(key);
1103     PUTBACK;
1104
1105     if (perl_call_method(meth, G_SCALAR))
1106         sv_setsv(key, *stack_sp--);
1107
1108     POPSTACK();
1109     FREETMPS;
1110     LEAVE;
1111     return 0;
1112 }
1113
1114 int
1115 magic_existspack(SV *sv, MAGIC *mg)
1116 {
1117     return magic_methpack(sv,mg,"EXISTS");
1118
1119
1120 int
1121 magic_setdbline(SV *sv, MAGIC *mg)
1122 {
1123     dTHR;
1124     OP *o;
1125     I32 i;
1126     GV* gv;
1127     SV** svp;
1128
1129     gv = DBline;
1130     i = SvTRUE(sv);
1131     svp = av_fetch(GvAV(gv),
1132                      atoi(MgPV(mg,na)), FALSE);
1133     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
1134         o->op_private = i;
1135     else
1136         warn("Can't break at that line\n");
1137     return 0;
1138 }
1139
1140 int
1141 magic_getarylen(SV *sv, MAGIC *mg)
1142 {
1143     dTHR;
1144     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
1145     return 0;
1146 }
1147
1148 int
1149 magic_setarylen(SV *sv, MAGIC *mg)
1150 {
1151     dTHR;
1152     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
1153     return 0;
1154 }
1155
1156 int
1157 magic_getpos(SV *sv, MAGIC *mg)
1158 {
1159     SV* lsv = LvTARG(sv);
1160     
1161     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1162         mg = mg_find(lsv, 'g');
1163         if (mg && mg->mg_len >= 0) {
1164             dTHR;
1165             sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
1166             return 0;
1167         }
1168     }
1169     (void)SvOK_off(sv);
1170     return 0;
1171 }
1172
1173 int
1174 magic_setpos(SV *sv, MAGIC *mg)
1175 {
1176     SV* lsv = LvTARG(sv);
1177     SSize_t pos;
1178     STRLEN len;
1179
1180     mg = 0;
1181     
1182     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1183         mg = mg_find(lsv, 'g');
1184     if (!mg) {
1185         if (!SvOK(sv))
1186             return 0;
1187         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1188         mg = mg_find(lsv, 'g');
1189     }
1190     else if (!SvOK(sv)) {
1191         mg->mg_len = -1;
1192         return 0;
1193     }
1194     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1195
1196     WITH_THR(pos = SvIV(sv) - curcop->cop_arybase);
1197     if (pos < 0) {
1198         pos += len;
1199         if (pos < 0)
1200             pos = 0;
1201     }
1202     else if (pos > len)
1203         pos = len;
1204     mg->mg_len = pos;
1205     mg->mg_flags &= ~MGf_MINMATCH;
1206
1207     return 0;
1208 }
1209
1210 int
1211 magic_getglob(SV *sv, MAGIC *mg)
1212 {
1213     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1214         SvFAKE_off(sv);
1215         gv_efullname3(sv,((GV*)sv), "*");
1216         SvFAKE_on(sv);
1217     }
1218     else
1219         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1220     return 0;
1221 }
1222
1223 int
1224 magic_setglob(SV *sv, MAGIC *mg)
1225 {
1226     register char *s;
1227     GV* gv;
1228
1229     if (!SvOK(sv))
1230         return 0;
1231     s = SvPV(sv, na);
1232     if (*s == '*' && s[1])
1233         s++;
1234     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1235     if (sv == (SV*)gv)
1236         return 0;
1237     if (GvGP(sv))
1238         gp_free((GV*)sv);
1239     GvGP(sv) = gp_ref(GvGP(gv));
1240     return 0;
1241 }
1242
1243 int
1244 magic_getsubstr(SV *sv, MAGIC *mg)
1245 {
1246     STRLEN len;
1247     SV *lsv = LvTARG(sv);
1248     char *tmps = SvPV(lsv,len);
1249     I32 offs = LvTARGOFF(sv);
1250     I32 rem = LvTARGLEN(sv);
1251
1252     if (offs > len)
1253         offs = len;
1254     if (rem + offs > len)
1255         rem = len - offs;
1256     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
1257     return 0;
1258 }
1259
1260 int
1261 magic_setsubstr(SV *sv, MAGIC *mg)
1262 {
1263     STRLEN len;
1264     char *tmps = SvPV(sv,len);
1265     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1266     return 0;
1267 }
1268
1269 int
1270 magic_gettaint(SV *sv, MAGIC *mg)
1271 {
1272     dTHR;
1273     TAINT_IF((mg->mg_len & 1) ||
1274              (mg->mg_len & 2) && mg->mg_obj == sv);     /* kludge */
1275     return 0;
1276 }
1277
1278 int
1279 magic_settaint(SV *sv, MAGIC *mg)
1280 {
1281     dTHR;
1282     if (localizing) {
1283         if (localizing == 1)
1284             mg->mg_len <<= 1;
1285         else
1286             mg->mg_len >>= 1;
1287     }
1288     else if (tainted)
1289         mg->mg_len |= 1;
1290     else
1291         mg->mg_len &= ~1;
1292     return 0;
1293 }
1294
1295 int
1296 magic_getvec(SV *sv, MAGIC *mg)
1297 {
1298     SV *lsv = LvTARG(sv);
1299     unsigned char *s;
1300     unsigned long retnum;
1301     STRLEN lsvlen;
1302     I32 len;
1303     I32 offset;
1304     I32 size;
1305
1306     if (!lsv) {
1307         SvOK_off(sv);
1308         return 0;
1309     }
1310     s = (unsigned char *) SvPV(lsv, lsvlen);
1311     offset = LvTARGOFF(sv);
1312     size = LvTARGLEN(sv);
1313     len = (offset + size + 7) / 8;
1314
1315     /* Copied from pp_vec() */
1316
1317     if (len > lsvlen) {
1318         if (size <= 8)
1319             retnum = 0;
1320         else {
1321             offset >>= 3;
1322             if (size == 16) {
1323                 if (offset >= lsvlen)
1324                     retnum = 0;
1325                 else
1326                     retnum = (unsigned long) s[offset] << 8;
1327             }
1328             else if (size == 32) {
1329                 if (offset >= lsvlen)
1330                     retnum = 0;
1331                 else if (offset + 1 >= lsvlen)
1332                     retnum = (unsigned long) s[offset] << 24;
1333                 else if (offset + 2 >= lsvlen)
1334                     retnum = ((unsigned long) s[offset] << 24) +
1335                         ((unsigned long) s[offset + 1] << 16);
1336                 else
1337                     retnum = ((unsigned long) s[offset] << 24) +
1338                         ((unsigned long) s[offset + 1] << 16) +
1339                         (s[offset + 2] << 8);
1340             }
1341         }
1342     }
1343     else if (size < 8)
1344         retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
1345     else {
1346         offset >>= 3;
1347         if (size == 8)
1348             retnum = s[offset];
1349         else if (size == 16)
1350             retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
1351         else if (size == 32)
1352             retnum = ((unsigned long) s[offset] << 24) +
1353                 ((unsigned long) s[offset + 1] << 16) +
1354                 (s[offset + 2] << 8) + s[offset+3];
1355     }
1356
1357     sv_setuv(sv, (UV)retnum);
1358     return 0;
1359 }
1360
1361 int
1362 magic_setvec(SV *sv, MAGIC *mg)
1363 {
1364     do_vecset(sv);      /* XXX slurp this routine */
1365     return 0;
1366 }
1367
1368 int
1369 magic_getdefelem(SV *sv, MAGIC *mg)
1370 {
1371     SV *targ = Nullsv;
1372     if (LvTARGLEN(sv)) {
1373         if (mg->mg_obj) {
1374             HV* hv = (HV*)LvTARG(sv);
1375             HE* he = hv_fetch_ent(hv, mg->mg_obj, FALSE, 0);
1376             if (he)
1377                 targ = HeVAL(he);
1378         }
1379         else {
1380             AV* av = (AV*)LvTARG(sv); 
1381             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1382                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1383         }
1384         if (targ && targ != &sv_undef) {
1385             dTHR;               /* just for SvREFCNT_dec */
1386             /* somebody else defined it for us */
1387             SvREFCNT_dec(LvTARG(sv));
1388             LvTARG(sv) = SvREFCNT_inc(targ);
1389             LvTARGLEN(sv) = 0;
1390             SvREFCNT_dec(mg->mg_obj);
1391             mg->mg_obj = Nullsv;
1392             mg->mg_flags &= ~MGf_REFCOUNTED;
1393         }
1394     }
1395     else
1396         targ = LvTARG(sv);
1397     sv_setsv(sv, targ ? targ : &sv_undef);
1398     return 0;
1399 }
1400
1401 int
1402 magic_setdefelem(SV *sv, MAGIC *mg)
1403 {
1404     if (LvTARGLEN(sv))
1405         vivify_defelem(sv);
1406     if (LvTARG(sv)) {
1407         sv_setsv(LvTARG(sv), sv);
1408         SvSETMAGIC(LvTARG(sv));
1409     }
1410     return 0;
1411 }
1412
1413 int
1414 magic_freedefelem(SV *sv, MAGIC *mg)
1415 {
1416     SvREFCNT_dec(LvTARG(sv));
1417     return 0;
1418 }
1419
1420 void
1421 vivify_defelem(SV *sv)
1422 {
1423     dTHR;                       /* just for SvREFCNT_inc and SvREFCNT_dec*/
1424     MAGIC* mg;
1425     SV* value;
1426
1427     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
1428         return;
1429     if (mg->mg_obj) {
1430         HV* hv = (HV*)LvTARG(sv);
1431         HE* he = hv_fetch_ent(hv, mg->mg_obj, TRUE, 0);
1432         if (!he || (value = HeVAL(he)) == &sv_undef)
1433             croak(no_helem, SvPV(mg->mg_obj, na));
1434     }
1435     else {
1436         AV* av = (AV*)LvTARG(sv);
1437         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1438             LvTARG(sv) = Nullsv;        /* array can't be extended */
1439         else {
1440             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1441             if (!svp || (value = *svp) == &sv_undef)
1442                 croak(no_aelem, (I32)LvTARGOFF(sv));
1443         }
1444     }
1445     (void)SvREFCNT_inc(value);
1446     SvREFCNT_dec(LvTARG(sv));
1447     LvTARG(sv) = value;
1448     LvTARGLEN(sv) = 0;
1449     SvREFCNT_dec(mg->mg_obj);
1450     mg->mg_obj = Nullsv;
1451     mg->mg_flags &= ~MGf_REFCOUNTED;
1452 }
1453
1454 int
1455 magic_setmglob(SV *sv, MAGIC *mg)
1456 {
1457     mg->mg_len = -1;
1458     SvSCREAM_off(sv);
1459     return 0;
1460 }
1461
1462 int
1463 magic_setbm(SV *sv, MAGIC *mg)
1464 {
1465     sv_unmagic(sv, 'B');
1466     SvVALID_off(sv);
1467     return 0;
1468 }
1469
1470 int
1471 magic_setfm(SV *sv, MAGIC *mg)
1472 {
1473     sv_unmagic(sv, 'f');
1474     SvCOMPILED_off(sv);
1475     return 0;
1476 }
1477
1478 int
1479 magic_setuvar(SV *sv, MAGIC *mg)
1480 {
1481     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1482
1483     if (uf && uf->uf_set)
1484         (*uf->uf_set)(uf->uf_index, sv);
1485     return 0;
1486 }
1487
1488 int
1489 magic_freeregexp(SV *sv, MAGIC *mg)
1490 {
1491     regexp *re = (regexp *)mg->mg_obj;
1492     ReREFCNT_dec(re);
1493     return 0;
1494 }
1495
1496 #ifdef USE_LOCALE_COLLATE
1497 int
1498 magic_setcollxfrm(SV *sv, MAGIC *mg)
1499 {
1500     /*
1501      * René Descartes said "I think not."
1502      * and vanished with a faint plop.
1503      */
1504     if (mg->mg_ptr) {
1505         Safefree(mg->mg_ptr);
1506         mg->mg_ptr = NULL;
1507         mg->mg_len = -1;
1508     }
1509     return 0;
1510 }
1511 #endif /* USE_LOCALE_COLLATE */
1512
1513 int
1514 magic_set(SV *sv, MAGIC *mg)
1515 {
1516     dTHR;
1517     register char *s;
1518     I32 i;
1519     STRLEN len;
1520     switch (*mg->mg_ptr) {
1521     case '\001':        /* ^A */
1522         sv_setsv(bodytarget, sv);
1523         break;
1524     case '\004':        /* ^D */
1525         debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1526         DEBUG_x(dump_all());
1527         break;
1528     case '\005':  /* ^E */
1529 #ifdef VMS
1530         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1531 #else
1532 #ifdef WIN32
1533         SetLastError( SvIV(sv) );
1534 #else
1535         /* will anyone ever use this? */
1536         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1537 #endif
1538 #endif
1539         break;
1540     case '\006':        /* ^F */
1541         maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1542         break;
1543     case '\010':        /* ^H */
1544         hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1545         break;
1546     case '\t':  /* ^I */
1547         if (inplace)
1548             Safefree(inplace);
1549         if (SvOK(sv))
1550             inplace = savepv(SvPV(sv,na));
1551         else
1552             inplace = Nullch;
1553         break;
1554     case '\017':        /* ^O */
1555         if (osname)
1556             Safefree(osname);
1557         if (SvOK(sv))
1558             osname = savepv(SvPV(sv,na));
1559         else
1560             osname = Nullch;
1561         break;
1562     case '\020':        /* ^P */
1563         perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1564         break;
1565     case '\024':        /* ^T */
1566 #ifdef BIG_TIME
1567         basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1568 #else
1569         basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1570 #endif
1571         break;
1572     case '\027':        /* ^W */
1573         dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1574         break;
1575     case '.':
1576         if (localizing) {
1577             if (localizing == 1)
1578                 save_sptr((SV**)&last_in_gv);
1579         }
1580         else if (SvOK(sv) && GvIO(last_in_gv))
1581             IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
1582         break;
1583     case '^':
1584         Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1585         IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1586         IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1587         break;
1588     case '~':
1589         Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1590         IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1591         IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1592         break;
1593     case '=':
1594         IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1595         break;
1596     case '-':
1597         IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1598         if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1599             IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
1600         break;
1601     case '%':
1602         IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1603         break;
1604     case '|':
1605         {
1606             IO *io = GvIOp(defoutgv);
1607             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1608                 IoFLAGS(io) &= ~IOf_FLUSH;
1609             else {
1610                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1611                     PerlIO *ofp = IoOFP(io);
1612                     if (ofp)
1613                         (void)PerlIO_flush(ofp);
1614                     IoFLAGS(io) |= IOf_FLUSH;
1615                 }
1616             }
1617         }
1618         break;
1619     case '*':
1620         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1621         multiline = (i != 0);
1622         break;
1623     case '/':
1624         SvREFCNT_dec(nrs);
1625         nrs = newSVsv(sv);
1626         SvREFCNT_dec(rs);
1627         rs = SvREFCNT_inc(nrs);
1628         break;
1629     case '\\':
1630         if (ors)
1631             Safefree(ors);
1632         if (SvOK(sv) || SvGMAGICAL(sv))
1633             ors = savepv(SvPV(sv,orslen));
1634         else {
1635             ors = Nullch;
1636             orslen = 0;
1637         }
1638         break;
1639     case ',':
1640         if (ofs)
1641             Safefree(ofs);
1642         ofs = savepv(SvPV(sv, ofslen));
1643         break;
1644     case '#':
1645         if (ofmt)
1646             Safefree(ofmt);
1647         ofmt = savepv(SvPV(sv,na));
1648         break;
1649     case '[':
1650         compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1651         break;
1652     case '?':
1653 #ifdef COMPLEX_STATUS
1654         if (localizing == 2) {
1655             statusvalue = LvTARGOFF(sv);
1656             statusvalue_vms = LvTARGLEN(sv);
1657         }
1658         else
1659 #endif
1660 #ifdef VMSISH_STATUS
1661         if (VMSISH_STATUS)
1662             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1663         else
1664 #endif
1665             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1666         break;
1667     case '!':
1668         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1669                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1670         break;
1671     case '<':
1672         uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1673         if (delaymagic) {
1674             delaymagic |= DM_RUID;
1675             break;                              /* don't do magic till later */
1676         }
1677 #ifdef HAS_SETRUID
1678         (void)setruid((Uid_t)uid);
1679 #else
1680 #ifdef HAS_SETREUID
1681         (void)setreuid((Uid_t)uid, (Uid_t)-1);
1682 #else
1683 #ifdef HAS_SETRESUID
1684       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
1685 #else
1686         if (uid == euid)                /* special case $< = $> */
1687             (void)setuid(uid);
1688         else {
1689             uid = (I32)getuid();
1690             croak("setruid() not implemented");
1691         }
1692 #endif
1693 #endif
1694 #endif
1695         uid = (I32)getuid();
1696         tainting |= (uid && (euid != uid || egid != gid));
1697         break;
1698     case '>':
1699         euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1700         if (delaymagic) {
1701             delaymagic |= DM_EUID;
1702             break;                              /* don't do magic till later */
1703         }
1704 #ifdef HAS_SETEUID
1705         (void)seteuid((Uid_t)euid);
1706 #else
1707 #ifdef HAS_SETREUID
1708         (void)setreuid((Uid_t)-1, (Uid_t)euid);
1709 #else
1710 #ifdef HAS_SETRESUID
1711         (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
1712 #else
1713         if (euid == uid)                /* special case $> = $< */
1714             setuid(euid);
1715         else {
1716             euid = (I32)geteuid();
1717             croak("seteuid() not implemented");
1718         }
1719 #endif
1720 #endif
1721 #endif
1722         euid = (I32)geteuid();
1723         tainting |= (uid && (euid != uid || egid != gid));
1724         break;
1725     case '(':
1726         gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1727         if (delaymagic) {
1728             delaymagic |= DM_RGID;
1729             break;                              /* don't do magic till later */
1730         }
1731 #ifdef HAS_SETRGID
1732         (void)setrgid((Gid_t)gid);
1733 #else
1734 #ifdef HAS_SETREGID
1735         (void)setregid((Gid_t)gid, (Gid_t)-1);
1736 #else
1737 #ifdef HAS_SETRESGID
1738       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
1739 #else
1740         if (gid == egid)                        /* special case $( = $) */
1741             (void)setgid(gid);
1742         else {
1743             gid = (I32)getgid();
1744             croak("setrgid() not implemented");
1745         }
1746 #endif
1747 #endif
1748 #endif
1749         gid = (I32)getgid();
1750         tainting |= (uid && (euid != uid || egid != gid));
1751         break;
1752     case ')':
1753 #ifdef HAS_SETGROUPS
1754         {
1755             char *p = SvPV(sv, na);
1756             Groups_t gary[NGROUPS];
1757
1758             SET_NUMERIC_STANDARD();
1759             while (isSPACE(*p))
1760                 ++p;
1761             egid = I_V(atof(p));
1762             for (i = 0; i < NGROUPS; ++i) {
1763                 while (*p && !isSPACE(*p))
1764                     ++p;
1765                 while (isSPACE(*p))
1766                     ++p;
1767                 if (!*p)
1768                     break;
1769                 gary[i] = I_V(atof(p));
1770             }
1771             if (i)
1772                 (void)setgroups(i, gary);
1773         }
1774 #else  /* HAS_SETGROUPS */
1775         egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1776 #endif /* HAS_SETGROUPS */
1777         if (delaymagic) {
1778             delaymagic |= DM_EGID;
1779             break;                              /* don't do magic till later */
1780         }
1781 #ifdef HAS_SETEGID
1782         (void)setegid((Gid_t)egid);
1783 #else
1784 #ifdef HAS_SETREGID
1785         (void)setregid((Gid_t)-1, (Gid_t)egid);
1786 #else
1787 #ifdef HAS_SETRESGID
1788         (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
1789 #else
1790         if (egid == gid)                        /* special case $) = $( */
1791             (void)setgid(egid);
1792         else {
1793             egid = (I32)getegid();
1794             croak("setegid() not implemented");
1795         }
1796 #endif
1797 #endif
1798 #endif
1799         egid = (I32)getegid();
1800         tainting |= (uid && (euid != uid || egid != gid));
1801         break;
1802     case ':':
1803         chopset = SvPV_force(sv,na);
1804         break;
1805     case '0':
1806         if (!origalen) {
1807             s = origargv[0];
1808             s += strlen(s);
1809             /* See if all the arguments are contiguous in memory */
1810             for (i = 1; i < origargc; i++) {
1811                 if (origargv[i] == s + 1
1812 #ifdef OS2
1813                     || origargv[i] == s + 2
1814 #endif 
1815                    )
1816                     s += strlen(++s);   /* this one is ok too */
1817                 else
1818                     break;
1819             }
1820             /* can grab env area too? */
1821             if (origenviron && (origenviron[0] == s + 1
1822 #ifdef OS2
1823                                 || (origenviron[0] == s + 9 && (s += 8))
1824 #endif 
1825                )) {
1826                 my_setenv("NoNe  SuCh", Nullch);
1827                                             /* force copy of environment */
1828                 for (i = 0; origenviron[i]; i++)
1829                     if (origenviron[i] == s + 1)
1830                         s += strlen(++s);
1831                     else
1832                         break;
1833             }
1834             origalen = s - origargv[0];
1835         }
1836         s = SvPV_force(sv,len);
1837         i = len;
1838         if (i >= origalen) {
1839             i = origalen;
1840             /* don't allow system to limit $0 seen by script */
1841             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
1842             Copy(s, origargv[0], i, char);
1843             s = origargv[0]+i;
1844             *s = '\0';
1845         }
1846         else {
1847             Copy(s, origargv[0], i, char);
1848             s = origargv[0]+i;
1849             *s++ = '\0';
1850             while (++i < origalen)
1851                 *s++ = ' ';
1852             s = origargv[0]+i;
1853             for (i = 1; i < origargc; i++)
1854                 origargv[i] = Nullch;
1855         }
1856         break;
1857 #ifdef USE_THREADS
1858     case '@':
1859         sv_setsv(thr->errsv, sv);
1860         break;
1861 #endif /* USE_THREADS */
1862     }
1863     return 0;
1864 }
1865
1866 #ifdef USE_THREADS
1867 int
1868 magic_mutexfree(SV *sv, MAGIC *mg)
1869 {
1870     dTHR;
1871     DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
1872                           (unsigned long)thr, (unsigned long)sv);)
1873     if (MgOWNER(mg))
1874         croak("panic: magic_mutexfree");
1875     MUTEX_DESTROY(MgMUTEXP(mg));
1876     COND_DESTROY(MgCONDP(mg));
1877     SvREFCNT_dec(sv);
1878     return 0;
1879 }
1880 #endif /* USE_THREADS */
1881
1882 I32
1883 whichsig(char *sig)
1884 {
1885     register char **sigv;
1886
1887     for (sigv = sig_name+1; *sigv; sigv++)
1888         if (strEQ(sig,*sigv))
1889             return sig_num[sigv - sig_name];
1890 #ifdef SIGCLD
1891     if (strEQ(sig,"CHLD"))
1892         return SIGCLD;
1893 #endif
1894 #ifdef SIGCHLD
1895     if (strEQ(sig,"CLD"))
1896         return SIGCHLD;
1897 #endif
1898     return 0;
1899 }
1900
1901 static SV* sig_sv;
1902
1903 static void
1904 unwind_handler_stack(void *p)
1905 {
1906     dTHR;
1907     U32 flags = *(U32*)p;
1908
1909     if (flags & 1)
1910         savestack_ix -= 5; /* Unprotect save in progress. */
1911     /* cxstack_ix-- Not needed, die already unwound it. */
1912     if (flags & 64)
1913         SvREFCNT_dec(sig_sv);
1914 }
1915
1916 Signal_t
1917 sighandler(int sig)
1918 {
1919     dSP;
1920     GV *gv = Nullgv;
1921     HV *st;
1922     SV *sv, *tSv = Sv;
1923     CV *cv = Nullcv;
1924     OP *myop = op;
1925     U32 flags = 0;
1926     I32 o_save_i = savestack_ix, type;
1927     XPV *tXpv = Xpv;
1928     
1929     if (savestack_ix + 15 <= savestack_max)
1930         flags |= 1;
1931     if (markstack_ptr < markstack_max - 2)
1932         flags |= 4;
1933     if (retstack_ix < retstack_max - 2)
1934         flags |= 8;
1935     if (scopestack_ix < scopestack_max - 3)
1936         flags |= 16;
1937
1938     if (!psig_ptr[sig])
1939         die("Signal SIG%s received, but no signal handler set.\n",
1940             sig_name[sig]);
1941
1942     /* Max number of items pushed there is 3*n or 4. We cannot fix
1943        infinity, so we fix 4 (in fact 5): */
1944     if (flags & 1) {
1945         savestack_ix += 5;              /* Protect save in progress. */
1946         o_save_i = savestack_ix;
1947         SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags);
1948     }
1949     if (flags & 4) 
1950         markstack_ptr++;                /* Protect mark. */
1951     if (flags & 8) {
1952         retstack_ix++;
1953         retstack[retstack_ix] = NULL;
1954     }
1955     if (flags & 16)
1956         scopestack_ix += 1;
1957     /* sv_2cv is too complicated, try a simpler variant first: */
1958     if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) 
1959         || SvTYPE(cv) != SVt_PVCV)
1960         cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1961
1962     if (!cv || !CvROOT(cv)) {
1963         if (dowarn)
1964             warn("SIG%s handler \"%s\" not defined.\n",
1965                 sig_name[sig], (gv ? GvENAME(gv)
1966                                 : ((cv && CvGV(cv))
1967                                    ? GvENAME(CvGV(cv))
1968                                    : "__ANON__")));
1969         goto cleanup;
1970     }
1971
1972     if(psig_name[sig]) {
1973         sv = SvREFCNT_inc(psig_name[sig]);
1974         flags |= 64;
1975         sig_sv = sv;
1976     } else {
1977         sv = sv_newmortal();
1978         sv_setpv(sv,sig_name[sig]);
1979     }
1980
1981     PUSHSTACK(SI_SIGNAL);
1982     PUSHMARK(SP);
1983     PUSHs(sv);
1984     PUTBACK;
1985
1986     perl_call_sv((SV*)cv, G_DISCARD);
1987
1988     POPSTACK();
1989 cleanup:
1990     if (flags & 1)
1991         savestack_ix -= 8; /* Unprotect save in progress. */
1992     if (flags & 4) 
1993         markstack_ptr--;
1994     if (flags & 8) 
1995         retstack_ix--;
1996     if (flags & 16)
1997         scopestack_ix -= 1;
1998     if (flags & 64)
1999         SvREFCNT_dec(sv);
2000     op = myop;                  /* Apparently not needed... */
2001     
2002     Sv = tSv;                   /* Restore global temporaries. */
2003     Xpv = tXpv;
2004     return;
2005 }
2006
2007