Fix problems with each() on tied hashes.
[p5sagit/p5-mst-13.2.git] / mg.c
1 /*    mg.c
2  *
3  *    Copyright (c) 1991-1994, 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 /* Omit -- it causes too much grief on mixed systems.
19 #ifdef I_UNISTD
20 # include <unistd.h>
21 #endif
22 */
23
24 /*
25  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
26  */
27
28 struct magic_state {
29     SV* mgs_sv;
30     U32 mgs_flags;
31 };
32 typedef struct magic_state MGS;
33
34 static void restore_magic _((void *p));
35
36 static MGS *
37 save_magic(sv)
38 SV* sv;
39 {
40     MGS* mgs;
41
42     assert(SvMAGICAL(sv));
43
44     mgs = (MGS*)safemalloc(sizeof(MGS));
45     mgs->mgs_sv = sv;
46     mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
47     SAVEDESTRUCTOR(restore_magic, mgs);
48
49     SvMAGICAL_off(sv);
50     SvREADONLY_off(sv);
51     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
52
53     return mgs;
54 }
55
56 static void
57 restore_magic(p)
58 void* p;
59 {
60     MGS *mgs = (MGS*)p;
61     SV* sv = mgs->mgs_sv;
62
63     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
64     {
65         if (mgs->mgs_flags)
66             SvFLAGS(sv) |= mgs->mgs_flags;
67         else
68             mg_magical(sv);
69         if (SvGMAGICAL(sv))
70             SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
71     }
72
73     safefree((void *)mgs);
74 }
75
76
77 void
78 mg_magical(sv)
79 SV* sv;
80 {
81     MAGIC* mg;
82     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
83         MGVTBL* vtbl = mg->mg_virtual;
84         if (vtbl) {
85             if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
86                 SvGMAGICAL_on(sv);
87             if (vtbl->svt_set)
88                 SvSMAGICAL_on(sv);
89             if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
90                 SvRMAGICAL_on(sv);
91         }
92     }
93 }
94
95 int
96 mg_get(sv)
97 SV* sv;
98 {
99     MGS* mgs;
100     MAGIC* mg;
101     MAGIC** mgp;
102     int mgp_valid = 0;
103
104     ENTER;
105     mgs = save_magic(sv);
106
107     mgp = &SvMAGIC(sv);
108     while ((mg = *mgp) != 0) {
109         MGVTBL* vtbl = mg->mg_virtual;
110         if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
111             (*vtbl->svt_get)(sv, mg);
112             /* Ignore this magic if it's been deleted */
113             if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) && (mg->mg_flags & MGf_GSKIP))
114                 mgs->mgs_flags = 0;
115         }
116         /* Advance to next magic (complicated by possible deletion) */
117         if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
118             mgp = &mg->mg_moremagic;
119             mgp_valid = 1;
120         }
121         else
122             mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
123     }
124
125     LEAVE;
126     return 0;
127 }
128
129 int
130 mg_set(sv)
131 SV* sv;
132 {
133     MGS* mgs;
134     MAGIC* mg;
135     MAGIC* nextmg;
136
137     ENTER;
138     mgs = save_magic(sv);
139
140     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
141         MGVTBL* vtbl = mg->mg_virtual;
142         nextmg = mg->mg_moremagic;      /* it may delete itself */
143         if (mg->mg_flags & MGf_GSKIP) {
144             mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
145             mgs->mgs_flags = 0;
146         }
147         if (vtbl && vtbl->svt_set)
148             (*vtbl->svt_set)(sv, mg);
149     }
150
151     LEAVE;
152     return 0;
153 }
154
155 U32
156 mg_len(sv)
157 SV* sv;
158 {
159     MAGIC* mg;
160     char *junk;
161     STRLEN len;
162
163     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
164         MGVTBL* vtbl = mg->mg_virtual;
165         if (vtbl && vtbl->svt_len) {
166             ENTER;
167             save_magic(sv);
168             /* omit MGf_GSKIP -- not changed here */
169             len = (*vtbl->svt_len)(sv, mg);
170             LEAVE;
171             return len;
172         }
173     }
174
175     junk = SvPV(sv, len);
176     return len;
177 }
178
179 int
180 mg_clear(sv)
181 SV* sv;
182 {
183     MAGIC* mg;
184
185     ENTER;
186     save_magic(sv);
187
188     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
189         MGVTBL* vtbl = mg->mg_virtual;
190         /* omit GSKIP -- never set here */
191         
192         if (vtbl && vtbl->svt_clear)
193             (*vtbl->svt_clear)(sv, mg);
194     }
195
196     LEAVE;
197     return 0;
198 }
199
200 MAGIC*
201 mg_find(sv, type)
202 SV* sv;
203 int type;
204 {
205     MAGIC* mg;
206     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
207         if (mg->mg_type == type)
208             return mg;
209     }
210     return 0;
211 }
212
213 int
214 mg_copy(sv, nsv, key, klen)
215 SV* sv;
216 SV* nsv;
217 char *key;
218 I32 klen;
219 {
220     int count = 0;
221     MAGIC* mg;
222     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
223         if (isUPPER(mg->mg_type)) {
224             sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
225             count++;
226         }
227     }
228     return count;
229 }
230
231 int
232 mg_free(sv)
233 SV* sv;
234 {
235     MAGIC* mg;
236     MAGIC* moremagic;
237     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
238         MGVTBL* vtbl = mg->mg_virtual;
239         moremagic = mg->mg_moremagic;
240         if (vtbl && vtbl->svt_free)
241             (*vtbl->svt_free)(sv, mg);
242         if (mg->mg_ptr && mg->mg_type != 'g')
243             if (mg->mg_len >= 0)
244                 Safefree(mg->mg_ptr);
245             else if (mg->mg_len == HEf_SVKEY)
246                 SvREFCNT_dec((SV*)mg->mg_ptr);
247         if (mg->mg_flags & MGf_REFCOUNTED)
248             SvREFCNT_dec(mg->mg_obj);
249         Safefree(mg);
250     }
251     SvMAGIC(sv) = 0;
252     return 0;
253 }
254
255 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
256 #include <signal.h>
257 #endif
258
259 U32
260 magic_len(sv, mg)
261 SV *sv;
262 MAGIC *mg;
263 {
264     register I32 paren;
265     register char *s;
266     register I32 i;
267     char *t;
268
269     switch (*mg->mg_ptr) {
270     case '1': case '2': case '3': case '4':
271     case '5': case '6': case '7': case '8': case '9': case '&':
272         if (curpm) {
273             paren = atoi(mg->mg_ptr);
274           getparen:
275             if (curpm->op_pmregexp &&
276               paren <= curpm->op_pmregexp->nparens &&
277               (s = curpm->op_pmregexp->startp[paren]) &&
278               (t = curpm->op_pmregexp->endp[paren]) ) {
279                 i = t - s;
280                 if (i >= 0)
281                     return i;
282             }
283         }
284         return 0;
285         break;
286     case '+':
287         if (curpm) {
288             paren = curpm->op_pmregexp->lastparen;
289             if (!paren)
290                 return 0;
291             goto getparen;
292         }
293         return 0;
294         break;
295     case '`':
296         if (curpm) {
297             if (curpm->op_pmregexp &&
298               (s = curpm->op_pmregexp->subbeg) ) {
299                 i = curpm->op_pmregexp->startp[0] - s;
300                 if (i >= 0)
301                     return i;
302             }
303         }
304         return 0;
305     case '\'':
306         if (curpm) {
307             if (curpm->op_pmregexp &&
308               (s = curpm->op_pmregexp->endp[0]) ) {
309                 return (STRLEN) (curpm->op_pmregexp->subend - s);
310             }
311         }
312         return 0;
313     case ',':
314         return (STRLEN)ofslen;
315     case '\\':
316         return (STRLEN)orslen;
317     }
318     magic_get(sv,mg);
319     if (!SvPOK(sv) && SvNIOK(sv))
320         sv_2pv(sv, &na);
321     if (SvPOK(sv))
322         return SvCUR(sv);
323     return 0;
324 }
325
326 int
327 magic_get(sv, mg)
328 SV *sv;
329 MAGIC *mg;
330 {
331     register I32 paren;
332     register char *s;
333     register I32 i;
334     char *t;
335
336     switch (*mg->mg_ptr) {
337     case '\001':                /* ^A */
338         sv_setsv(sv, bodytarget);
339         break;
340     case '\004':                /* ^D */
341         sv_setiv(sv,(I32)(debug & 32767));
342         break;
343     case '\005':  /* ^E */
344 #ifdef VMS
345         {
346 #           include <descrip.h>
347 #           include <starlet.h>
348             char msg[255];
349             $DESCRIPTOR(msgdsc,msg);
350             sv_setnv(sv,(double)vaxc$errno);
351             if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
352                 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
353             else
354                 sv_setpv(sv,"");
355         }
356 #else
357 #ifdef OS2
358         sv_setnv(sv,(double)Perl_rc);
359         sv_setpv(sv, os2error(Perl_rc));
360 #else
361         sv_setnv(sv,(double)errno);
362         sv_setpv(sv, errno ? Strerror(errno) : "");
363 #endif
364 #endif
365         SvNOK_on(sv);   /* what a wonderful hack! */
366         break;
367     case '\006':                /* ^F */
368         sv_setiv(sv,(I32)maxsysfd);
369         break;
370     case '\010':                /* ^H */
371         sv_setiv(sv,(I32)hints);
372         break;
373     case '\t':                  /* ^I */
374         if (inplace)
375             sv_setpv(sv, inplace);
376         else
377             sv_setsv(sv,&sv_undef);
378         break;
379     case '\017':                /* ^O */
380         sv_setpv(sv,osname);
381         break;
382     case '\020':                /* ^P */
383         sv_setiv(sv,(I32)perldb);
384         break;
385     case '\024':                /* ^T */
386 #ifdef BIG_TIME
387         sv_setnv(sv,basetime);
388 #else
389         sv_setiv(sv,(I32)basetime);
390 #endif
391         break;
392     case '\027':                /* ^W */
393         sv_setiv(sv,(I32)dowarn);
394         break;
395     case '1': case '2': case '3': case '4':
396     case '5': case '6': case '7': case '8': case '9': case '&':
397         if (curpm) {
398             paren = atoi(GvENAME((GV*)mg->mg_obj));
399           getparen:
400             if (curpm->op_pmregexp &&
401               paren <= curpm->op_pmregexp->nparens &&
402               (s = curpm->op_pmregexp->startp[paren]) &&
403               (t = curpm->op_pmregexp->endp[paren]) ) {
404                 i = t - s;
405                 if (i >= 0) {
406                     MAGIC *tmg;
407                     sv_setpvn(sv,s,i);
408                     if (tainting && (tmg = mg_find(sv,'t')))
409                         tmg->mg_len = 0;        /* guarantee $1 untainted */
410                     break;
411                 }
412             }
413         }
414         sv_setsv(sv,&sv_undef);
415         break;
416     case '+':
417         if (curpm) {
418             paren = curpm->op_pmregexp->lastparen;
419             if (paren)
420                 goto getparen;
421         }
422         sv_setsv(sv,&sv_undef);
423         break;
424     case '`':
425         if (curpm) {
426             if (curpm->op_pmregexp &&
427               (s = curpm->op_pmregexp->subbeg) ) {
428                 i = curpm->op_pmregexp->startp[0] - s;
429                 if (i >= 0) {
430                     sv_setpvn(sv,s,i);
431                     break;
432                 }
433             }
434         }
435         sv_setsv(sv,&sv_undef);
436         break;
437     case '\'':
438         if (curpm) {
439             if (curpm->op_pmregexp &&
440               (s = curpm->op_pmregexp->endp[0]) ) {
441                 sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
442                 break;
443             }
444         }
445         sv_setsv(sv,&sv_undef);
446         break;
447     case '.':
448 #ifndef lint
449         if (GvIO(last_in_gv)) {
450             sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
451         }
452 #endif
453         break;
454     case '?':
455         sv_setiv(sv,(I32)statusvalue);
456         break;
457     case '^':
458         s = IoTOP_NAME(GvIOp(defoutgv));
459         if (s)
460             sv_setpv(sv,s);
461         else {
462             sv_setpv(sv,GvENAME(defoutgv));
463             sv_catpv(sv,"_TOP");
464         }
465         break;
466     case '~':
467         s = IoFMT_NAME(GvIOp(defoutgv));
468         if (!s)
469             s = GvENAME(defoutgv);
470         sv_setpv(sv,s);
471         break;
472 #ifndef lint
473     case '=':
474         sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
475         break;
476     case '-':
477         sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
478         break;
479     case '%':
480         sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
481         break;
482 #endif
483     case ':':
484         break;
485     case '/':
486         break;
487     case '[':
488         sv_setiv(sv,(I32)curcop->cop_arybase);
489         break;
490     case '|':
491         sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
492         break;
493     case ',':
494         sv_setpvn(sv,ofs,ofslen);
495         break;
496     case '\\':
497         sv_setpvn(sv,ors,orslen);
498         break;
499     case '#':
500         sv_setpv(sv,ofmt);
501         break;
502     case '!':
503 #ifdef VMS
504         sv_setnv(sv,(double)((errno == EVMSERR) ? vaxc$errno : errno));
505         sv_setpv(sv, errno ? Strerror(errno) : "");
506 #else
507         {
508         int saveerrno = errno;
509         sv_setnv(sv,(double)errno);
510 #ifdef OS2
511         if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
512         else
513 #endif
514         sv_setpv(sv, errno ? Strerror(errno) : "");
515         errno = saveerrno;
516         }
517 #endif
518         SvNOK_on(sv);   /* what a wonderful hack! */
519         break;
520     case '<':
521         sv_setiv(sv,(I32)uid);
522         break;
523     case '>':
524         sv_setiv(sv,(I32)euid);
525         break;
526     case '(':
527         s = buf;
528         (void)sprintf(s,"%d",(int)gid);
529         goto add_groups;
530     case ')':
531         s = buf;
532         (void)sprintf(s,"%d",(int)egid);
533       add_groups:
534         while (*s) s++;
535 #ifdef HAS_GETGROUPS
536 #ifndef NGROUPS
537 #define NGROUPS 32
538 #endif
539         {
540             Groups_t gary[NGROUPS];
541
542             i = getgroups(NGROUPS,gary);
543             while (--i >= 0) {
544                 (void)sprintf(s," %ld", (long)gary[i]);
545                 while (*s) s++;
546             }
547         }
548 #endif
549         sv_setpv(sv,buf);
550         break;
551     case '*':
552         break;
553     case '0':
554         break;
555     }
556     return 0;
557 }
558
559 int
560 magic_getuvar(sv, mg)
561 SV *sv;
562 MAGIC *mg;
563 {
564     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
565
566     if (uf && uf->uf_val)
567         (*uf->uf_val)(uf->uf_index, sv);
568     return 0;
569 }
570
571 int
572 magic_setenv(sv,mg)
573 SV* sv;
574 MAGIC* mg;
575 {
576     register char *s;
577     char *ptr;
578     STRLEN len;
579     I32 i;
580     s = SvPV(sv,len);
581     ptr = (mg->mg_len == HEf_SVKEY) ? SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr;
582     my_setenv(ptr, s);
583 #ifdef DYNAMIC_ENV_FETCH
584      /* We just undefd an environment var.  Is a replacement */
585      /* waiting in the wings? */
586     if (!len) {
587         HE *envhe;
588         if (envhe = hv_fetch_ent(GvHVn(envgv),HeSVKEY((HE*)(mg->mg_ptr)),FALSE,0))
589             s = SvPV(HeVAL(envhe),len);
590     }
591 #endif
592                             /* And you'll never guess what the dog had */
593                             /*   in its mouth... */
594     if (tainting) {
595         if (s && strEQ(ptr,"PATH")) {
596             char *strend = s + len;
597
598             while (s < strend) {
599                 s = cpytill(tokenbuf,s,strend,':',&i);
600                 s++;
601                 if (*tokenbuf != '/'
602                   || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
603                     MgTAINTEDDIR_on(mg);
604             }
605         }
606     }
607     return 0;
608 }
609
610 int
611 magic_clearenv(sv,mg)
612 SV* sv;
613 MAGIC* mg;
614 {
615     my_setenv(((mg->mg_len == HEf_SVKEY) ?
616                SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr),Nullch);
617     return 0;
618 }
619
620 #ifdef HAS_SIGACTION
621 /* set up reliable signal() clone */
622
623 typedef void (*Sigfunc) _((int));
624
625 static
626 Sigfunc rsignal(signo,handler)
627 int signo;
628 Sigfunc handler;
629 {
630     struct sigaction act,oact;
631     
632     act.sa_handler = handler;
633     sigemptyset(&act.sa_mask);
634     act.sa_flags = 0;
635 #ifdef SA_RESTART
636     act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
637 #endif
638     if (sigaction(signo, &act, &oact) < 0)
639         return(SIG_ERR);
640     else
641         return(oact.sa_handler);
642 }
643
644 #else
645
646 /* ah well, so much for reliability */
647
648 #define rsignal(x,y) signal(x,y)
649
650 #endif
651
652 static sig_trapped;
653 static
654 Signal_t
655 sig_trap(signo)
656 int signo;
657 {
658     sig_trapped++;
659 }
660 int
661 magic_getsig(sv,mg)
662 SV* sv;
663 MAGIC* mg;
664 {
665     I32 i;
666     /* Are we fetching a signal entry? */
667     i = whichsig(mg->mg_ptr);
668     if (i) {
669         if(psig_ptr[i])
670             sv_setsv(sv,psig_ptr[i]);
671         else {
672             void (*origsig) _((int));
673             /* get signal state without losing signals */
674             sig_trapped=0;
675             origsig = rsignal(i,sig_trap);
676             rsignal(i,origsig);
677             if(sig_trapped)
678                 kill(getpid(),i);
679             /* cache state so we don't fetch it again */
680             if(origsig == SIG_IGN)
681                 sv_setpv(sv,"IGNORE");
682             else
683                 sv_setsv(sv,&sv_undef);
684             psig_ptr[i] = SvREFCNT_inc(sv);
685             SvTEMP_off(sv);
686         }
687     }
688     return 0;
689 }
690 int
691 magic_clearsig(sv,mg)
692 SV* sv;
693 MAGIC* mg;
694 {
695     I32 i;
696     /* Are we clearing a signal entry? */
697     i = whichsig(mg->mg_ptr);
698     if (i) {
699         if(psig_ptr[i]) {
700             SvREFCNT_dec(psig_ptr[i]);
701             psig_ptr[i]=0;
702         }
703         if(psig_name[i]) {
704             SvREFCNT_dec(psig_name[i]);
705             psig_name[i]=0;
706         }
707     }
708     return 0;
709 }
710
711 int
712 magic_setsig(sv,mg)
713 SV* sv;
714 MAGIC* mg;
715 {
716     register char *s;
717     I32 i;
718     SV** svp;
719
720     s = (mg->mg_len == HEf_SVKEY) ? SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr;
721     if (*s == '_') {
722         if (strEQ(s,"__DIE__"))
723             svp = &diehook;
724         else if (strEQ(s,"__WARN__"))
725             svp = &warnhook;
726         else if (strEQ(s,"__PARSE__"))
727             svp = &parsehook;
728         else
729             croak("No such hook: %s", s);
730         i = 0;
731         if (*svp) {
732             SvREFCNT_dec(*svp);
733             *svp = 0;
734         }
735     }
736     else {
737         i = whichsig(s);        /* ...no, a brick */
738         if (!i) {
739             if (dowarn || strEQ(s,"ALARM"))
740                 warn("No such signal: SIG%s", s);
741             return 0;
742         }
743         if(psig_ptr[i])
744             SvREFCNT_dec(psig_ptr[i]);
745         psig_ptr[i] = SvREFCNT_inc(sv);
746         if(psig_name[i])
747             SvREFCNT_dec(psig_name[i]);
748         psig_name[i] = newSVpv(mg->mg_ptr,strlen(mg->mg_ptr));
749         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
750         SvREADONLY_on(psig_name[i]);
751     }
752     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
753         if (i)
754             (void)rsignal(i,sighandler);
755         else
756             *svp = SvREFCNT_inc(sv);
757         return 0;
758     }
759     s = SvPV_force(sv,na);
760     if (strEQ(s,"IGNORE")) {
761         if (i)
762             (void)rsignal(i,SIG_IGN);
763         else
764             *svp = 0;
765     }
766     else if (strEQ(s,"DEFAULT") || !*s) {
767         if (i)
768             (void)rsignal(i,SIG_DFL);
769         else
770             *svp = 0;
771     }
772     else {
773         if(hints & HINT_STRICT_REFS)
774                 die(no_symref,s,"a subroutine");
775         if (!strchr(s,':') && !strchr(s,'\'')) {
776             sprintf(tokenbuf, "main::%s",s);
777             sv_setpv(sv,tokenbuf);
778         }
779         if (i)
780             (void)rsignal(i,sighandler);
781         else
782             *svp = SvREFCNT_inc(sv);
783     }
784     return 0;
785 }
786
787 int
788 magic_setisa(sv,mg)
789 SV* sv;
790 MAGIC* mg;
791 {
792     sub_generation++;
793     return 0;
794 }
795
796 #ifdef OVERLOAD
797
798 int
799 magic_setamagic(sv,mg)
800 SV* sv;
801 MAGIC* mg;
802 {
803     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
804     amagic_generation++;
805
806     return 0;
807 }
808 #endif /* OVERLOAD */
809
810 static int
811 magic_methpack(sv,mg,meth)
812 SV* sv;
813 MAGIC* mg;
814 char *meth;
815 {
816     dSP;
817
818     ENTER;
819     SAVETMPS;
820     PUSHMARK(sp);
821     EXTEND(sp, 2);
822     PUSHs(mg->mg_obj);
823     if (mg->mg_ptr) {
824         if (mg->mg_len >= 0)
825             PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
826         else if (mg->mg_len == HEf_SVKEY)
827             PUSHs((SV*)mg->mg_ptr);
828     }
829     else if (mg->mg_type == 'p')
830         PUSHs(sv_2mortal(newSViv(mg->mg_len)));
831     PUTBACK;
832
833     if (perl_call_method(meth, G_SCALAR))
834         sv_setsv(sv, *stack_sp--);
835
836     FREETMPS;
837     LEAVE;
838     return 0;
839 }
840
841 int
842 magic_getpack(sv,mg)
843 SV* sv;
844 MAGIC* mg;
845 {
846     magic_methpack(sv,mg,"FETCH");
847     if (mg->mg_ptr)
848         mg->mg_flags |= MGf_GSKIP;
849     return 0;
850 }
851
852 int
853 magic_setpack(sv,mg)
854 SV* sv;
855 MAGIC* mg;
856 {
857     dSP;
858
859     PUSHMARK(sp);
860     EXTEND(sp, 3);
861     PUSHs(mg->mg_obj);
862     if (mg->mg_ptr) {
863         if (mg->mg_len >= 0)
864             PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
865         else if (mg->mg_len == HEf_SVKEY)
866             PUSHs((SV*)mg->mg_ptr);
867     }
868     else if (mg->mg_type == 'p')
869         PUSHs(sv_2mortal(newSViv(mg->mg_len)));
870     PUSHs(sv);
871     PUTBACK;
872
873     perl_call_method("STORE", G_SCALAR|G_DISCARD);
874
875     return 0;
876 }
877
878 int
879 magic_clearpack(sv,mg)
880 SV* sv;
881 MAGIC* mg;
882 {
883     return magic_methpack(sv,mg,"DELETE");
884 }
885
886 int magic_wipepack(sv,mg)
887 SV* sv;
888 MAGIC* mg;
889 {
890     dSP;
891
892     PUSHMARK(sp);
893     XPUSHs(mg->mg_obj);
894     PUTBACK;
895
896     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
897
898     return 0;
899 }
900
901 int
902 magic_nextpack(sv,mg,key)
903 SV* sv;
904 MAGIC* mg;
905 SV* key;
906 {
907     dSP;
908     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
909
910     ENTER;
911     SAVETMPS;
912     PUSHMARK(sp);
913     EXTEND(sp, 2);
914     PUSHs(mg->mg_obj);
915     if (SvOK(key))
916         PUSHs(key);
917     PUTBACK;
918
919     if (perl_call_method(meth, G_SCALAR))
920         sv_setsv(key, *stack_sp--);
921
922     FREETMPS;
923     LEAVE;
924     return 0;
925 }
926
927 int
928 magic_existspack(sv,mg)
929 SV* sv;
930 MAGIC* mg;
931 {
932     return magic_methpack(sv,mg,"EXISTS");
933
934
935 int
936 magic_setdbline(sv,mg)
937 SV* sv;
938 MAGIC* mg;
939 {
940     OP *o;
941     I32 i;
942     GV* gv;
943     SV** svp;
944
945     gv = DBline;
946     i = SvTRUE(sv);
947     svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
948     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
949         o->op_private = i;
950     else
951         warn("Can't break at that line\n");
952     return 0;
953 }
954
955 int
956 magic_getarylen(sv,mg)
957 SV* sv;
958 MAGIC* mg;
959 {
960     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
961     return 0;
962 }
963
964 int
965 magic_setarylen(sv,mg)
966 SV* sv;
967 MAGIC* mg;
968 {
969     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
970     return 0;
971 }
972
973 int
974 magic_getpos(sv,mg)
975 SV* sv;
976 MAGIC* mg;
977 {
978     SV* lsv = LvTARG(sv);
979     
980     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
981         mg = mg_find(lsv, 'g');
982         if (mg && mg->mg_len >= 0) {
983             sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
984             return 0;
985         }
986     }
987     (void)SvOK_off(sv);
988     return 0;
989 }
990
991 int
992 magic_setpos(sv,mg)
993 SV* sv;
994 MAGIC* mg;
995 {
996     SV* lsv = LvTARG(sv);
997     SSize_t pos;
998     STRLEN len;
999
1000     mg = 0;
1001     
1002     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1003         mg = mg_find(lsv, 'g');
1004     if (!mg) {
1005         if (!SvOK(sv))
1006             return 0;
1007         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1008         mg = mg_find(lsv, 'g');
1009     }
1010     else if (!SvOK(sv)) {
1011         mg->mg_len = -1;
1012         return 0;
1013     }
1014     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1015
1016     pos = SvIV(sv) - curcop->cop_arybase;
1017     if (pos < 0) {
1018         pos += len;
1019         if (pos < 0)
1020             pos = 0;
1021     }
1022     else if (pos > len)
1023         pos = len;
1024     mg->mg_len = pos;
1025
1026     return 0;
1027 }
1028
1029 int
1030 magic_getglob(sv,mg)
1031 SV* sv;
1032 MAGIC* mg;
1033 {
1034     gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
1035     return 0;
1036 }
1037
1038 int
1039 magic_setglob(sv,mg)
1040 SV* sv;
1041 MAGIC* mg;
1042 {
1043     register char *s;
1044     GV* gv;
1045
1046     if (!SvOK(sv))
1047         return 0;
1048     s = SvPV(sv, na);
1049     if (*s == '*' && s[1])
1050         s++;
1051     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1052     if (sv == (SV*)gv)
1053         return 0;
1054     if (GvGP(sv))
1055         gp_free((GV*)sv);
1056     GvGP(sv) = gp_ref(GvGP(gv));
1057     if (!GvAV(gv))
1058         gv_AVadd(gv);
1059     if (!GvHV(gv))
1060         gv_HVadd(gv);
1061     if (!GvIOp(gv))
1062         GvIOp(gv) = newIO();
1063     return 0;
1064 }
1065
1066 int
1067 magic_setsubstr(sv,mg)
1068 SV* sv;
1069 MAGIC* mg;
1070 {
1071     STRLEN len;
1072     char *tmps = SvPV(sv,len);
1073     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1074     return 0;
1075 }
1076
1077 int
1078 magic_gettaint(sv,mg)
1079 SV* sv;
1080 MAGIC* mg;
1081 {
1082     if (mg->mg_len & 1)
1083         tainted = TRUE;
1084     else if (mg->mg_len & 2 && mg->mg_obj == sv)        /* kludge */
1085         tainted = TRUE;
1086     return 0;
1087 }
1088
1089 int
1090 magic_settaint(sv,mg)
1091 SV* sv;
1092 MAGIC* mg;
1093 {
1094     if (localizing) {
1095         if (localizing == 1)
1096             mg->mg_len <<= 1;
1097         else
1098             mg->mg_len >>= 1;
1099     }
1100     else if (tainted)
1101         mg->mg_len |= 1;
1102     else
1103         mg->mg_len &= ~1;
1104     return 0;
1105 }
1106
1107 int
1108 magic_setvec(sv,mg)
1109 SV* sv;
1110 MAGIC* mg;
1111 {
1112     do_vecset(sv);      /* XXX slurp this routine */
1113     return 0;
1114 }
1115
1116 int
1117 magic_setmglob(sv,mg)
1118 SV* sv;
1119 MAGIC* mg;
1120 {
1121     mg->mg_len = -1;
1122     SvSCREAM_off(sv);
1123     return 0;
1124 }
1125
1126 int
1127 magic_setbm(sv,mg)
1128 SV* sv;
1129 MAGIC* mg;
1130 {
1131     sv_unmagic(sv, 'B');
1132     SvVALID_off(sv);
1133     return 0;
1134 }
1135
1136 int
1137 magic_setuvar(sv,mg)
1138 SV* sv;
1139 MAGIC* mg;
1140 {
1141     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1142
1143     if (uf && uf->uf_set)
1144         (*uf->uf_set)(uf->uf_index, sv);
1145     return 0;
1146 }
1147
1148 int
1149 magic_set(sv,mg)
1150 SV* sv;
1151 MAGIC* mg;
1152 {
1153     register char *s;
1154     I32 i;
1155     STRLEN len;
1156     switch (*mg->mg_ptr) {
1157     case '\001':        /* ^A */
1158         sv_setsv(bodytarget, sv);
1159         break;
1160     case '\004':        /* ^D */
1161         debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1162         DEBUG_x(dump_all());
1163         break;
1164     case '\005':  /* ^E */
1165 #ifdef VMS
1166         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1167 #else
1168         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),4);         /* will anyone ever use this? */
1169 #endif
1170         break;
1171     case '\006':        /* ^F */
1172         maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1173         break;
1174     case '\010':        /* ^H */
1175         hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1176         break;
1177     case '\t':  /* ^I */
1178         if (inplace)
1179             Safefree(inplace);
1180         if (SvOK(sv))
1181             inplace = savepv(SvPV(sv,na));
1182         else
1183             inplace = Nullch;
1184         break;
1185     case '\017':        /* ^O */
1186         if (osname)
1187             Safefree(osname);
1188         if (SvOK(sv))
1189             osname = savepv(SvPV(sv,na));
1190         else
1191             osname = Nullch;
1192         break;
1193     case '\020':        /* ^P */
1194         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1195         if (i != perldb) {
1196             if (perldb)
1197                 oldlastpm = curpm;
1198             else
1199                 curpm = oldlastpm;
1200         }
1201         perldb = i;
1202         break;
1203     case '\024':        /* ^T */
1204 #ifdef BIG_TIME
1205         basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1206 #else
1207         basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1208 #endif
1209         break;
1210     case '\027':        /* ^W */
1211         dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1212         break;
1213     case '.':
1214         if (localizing) {
1215             if (localizing == 1)
1216                 save_sptr((SV**)&last_in_gv);
1217         }
1218         else if (SvOK(sv) && GvIO(last_in_gv))
1219             IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
1220         break;
1221     case '^':
1222         Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1223         IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1224         IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1225         break;
1226     case '~':
1227         Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1228         IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1229         IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1230         break;
1231     case '=':
1232         IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1233         break;
1234     case '-':
1235         IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1236         if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1237             IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
1238         break;
1239     case '%':
1240         IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1241         break;
1242     case '|':
1243         IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
1244         if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
1245             IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
1246         }
1247         break;
1248     case '*':
1249         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1250         multiline = (i != 0);
1251         break;
1252     case '/':
1253         SvREFCNT_dec(nrs);
1254         nrs = newSVsv(sv);
1255         SvREFCNT_dec(rs);
1256         rs = SvREFCNT_inc(nrs);
1257         break;
1258     case '\\':
1259         if (ors)
1260             Safefree(ors);
1261         ors = savepv(SvPV(sv,orslen));
1262         break;
1263     case ',':
1264         if (ofs)
1265             Safefree(ofs);
1266         ofs = savepv(SvPV(sv, ofslen));
1267         break;
1268     case '#':
1269         if (ofmt)
1270             Safefree(ofmt);
1271         ofmt = savepv(SvPV(sv,na));
1272         break;
1273     case '[':
1274         compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1275         break;
1276     case '?':
1277         statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1278         break;
1279     case '!':
1280         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SvIV(sv) == EVMSERR ? 4 : vaxc$errno);              /* will anyone ever use this? */
1281         break;
1282     case '<':
1283         uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1284         if (delaymagic) {
1285             delaymagic |= DM_RUID;
1286             break;                              /* don't do magic till later */
1287         }
1288 #ifdef HAS_SETRUID
1289         (void)setruid((Uid_t)uid);
1290 #else
1291 #ifdef HAS_SETREUID
1292         (void)setreuid((Uid_t)uid, (Uid_t)-1);
1293 #else
1294 #ifdef HAS_SETRESUID
1295       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
1296 #else
1297         if (uid == euid)                /* special case $< = $> */
1298             (void)setuid(uid);
1299         else {
1300             uid = (I32)getuid();
1301             croak("setruid() not implemented");
1302         }
1303 #endif
1304 #endif
1305 #endif
1306         uid = (I32)getuid();
1307         tainting |= (uid && (euid != uid || egid != gid));
1308         break;
1309     case '>':
1310         euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1311         if (delaymagic) {
1312             delaymagic |= DM_EUID;
1313             break;                              /* don't do magic till later */
1314         }
1315 #ifdef HAS_SETEUID
1316         (void)seteuid((Uid_t)euid);
1317 #else
1318 #ifdef HAS_SETREUID
1319         (void)setreuid((Uid_t)-1, (Uid_t)euid);
1320 #else
1321 #ifdef HAS_SETRESUID
1322         (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
1323 #else
1324         if (euid == uid)                /* special case $> = $< */
1325             setuid(euid);
1326         else {
1327             euid = (I32)geteuid();
1328             croak("seteuid() not implemented");
1329         }
1330 #endif
1331 #endif
1332 #endif
1333         euid = (I32)geteuid();
1334         tainting |= (uid && (euid != uid || egid != gid));
1335         break;
1336     case '(':
1337         gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1338         if (delaymagic) {
1339             delaymagic |= DM_RGID;
1340             break;                              /* don't do magic till later */
1341         }
1342 #ifdef HAS_SETRGID
1343         (void)setrgid((Gid_t)gid);
1344 #else
1345 #ifdef HAS_SETREGID
1346         (void)setregid((Gid_t)gid, (Gid_t)-1);
1347 #else
1348 #ifdef HAS_SETRESGID
1349       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
1350 #else
1351         if (gid == egid)                        /* special case $( = $) */
1352             (void)setgid(gid);
1353         else {
1354             gid = (I32)getgid();
1355             croak("setrgid() not implemented");
1356         }
1357 #endif
1358 #endif
1359 #endif
1360         gid = (I32)getgid();
1361         tainting |= (uid && (euid != uid || egid != gid));
1362         break;
1363     case ')':
1364         egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1365         if (delaymagic) {
1366             delaymagic |= DM_EGID;
1367             break;                              /* don't do magic till later */
1368         }
1369 #ifdef HAS_SETEGID
1370         (void)setegid((Gid_t)egid);
1371 #else
1372 #ifdef HAS_SETREGID
1373         (void)setregid((Gid_t)-1, (Gid_t)egid);
1374 #else
1375 #ifdef HAS_SETRESGID
1376         (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
1377 #else
1378         if (egid == gid)                        /* special case $) = $( */
1379             (void)setgid(egid);
1380         else {
1381             egid = (I32)getegid();
1382             croak("setegid() not implemented");
1383         }
1384 #endif
1385 #endif
1386 #endif
1387         egid = (I32)getegid();
1388         tainting |= (uid && (euid != uid || egid != gid));
1389         break;
1390     case ':':
1391         chopset = SvPV_force(sv,na);
1392         break;
1393     case '0':
1394         if (!origalen) {
1395             s = origargv[0];
1396             s += strlen(s);
1397             /* See if all the arguments are contiguous in memory */
1398             for (i = 1; i < origargc; i++) {
1399                 if (origargv[i] == s + 1)
1400                     s += strlen(++s);   /* this one is ok too */
1401             }
1402             if (origenviron[0] == s + 1) {      /* can grab env area too? */
1403                 my_setenv("NoNeSuCh", Nullch);
1404                                             /* force copy of environment */
1405                 for (i = 0; origenviron[i]; i++)
1406                     if (origenviron[i] == s + 1)
1407                         s += strlen(++s);
1408             }
1409             origalen = s - origargv[0];
1410         }
1411         s = SvPV_force(sv,len);
1412         i = len;
1413         if (i >= origalen) {
1414             i = origalen;
1415             SvCUR_set(sv, i);
1416             *SvEND(sv) = '\0';
1417             Copy(s, origargv[0], i, char);
1418         }
1419         else {
1420             Copy(s, origargv[0], i, char);
1421             s = origargv[0]+i;
1422             *s++ = '\0';
1423             while (++i < origalen)
1424                 *s++ = ' ';
1425             s = origargv[0]+i;
1426             for (i = 1; i < origargc; i++)
1427                 origargv[i] = Nullch;
1428         }
1429         break;
1430     }
1431     return 0;
1432 }
1433
1434 I32
1435 whichsig(sig)
1436 char *sig;
1437 {
1438     register char **sigv;
1439
1440     for (sigv = sig_name+1; *sigv; sigv++)
1441         if (strEQ(sig,*sigv))
1442             return sig_num[sigv - sig_name];
1443 #ifdef SIGCLD
1444     if (strEQ(sig,"CHLD"))
1445         return SIGCLD;
1446 #endif
1447 #ifdef SIGCHLD
1448     if (strEQ(sig,"CLD"))
1449         return SIGCHLD;
1450 #endif
1451     return 0;
1452 }
1453
1454 Signal_t
1455 sighandler(sig)
1456 int sig;
1457 {
1458     dSP;
1459     GV *gv;
1460     HV *st;
1461     SV *sv;
1462     CV *cv;
1463     AV *oldstack;
1464     
1465     if(!psig_ptr[sig])
1466         die("Signal SIG%s received, but no signal handler set.\n",
1467         sig_name[sig]);
1468
1469     cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1470     if (!cv || !CvROOT(cv)) {
1471         if (dowarn)
1472             warn("SIG%s handler \"%s\" not defined.\n",
1473                 sig_name[sig], GvENAME(gv) );
1474         return;
1475     }
1476
1477     oldstack = curstack;
1478     if (curstack != signalstack)
1479         AvFILL(signalstack) = 0;
1480     SWITCHSTACK(curstack, signalstack);
1481
1482     if(psig_name[sig])
1483         sv = SvREFCNT_inc(psig_name[sig]);
1484     else {
1485         sv = sv_newmortal();
1486         sv_setpv(sv,sig_name[sig]);
1487     }
1488     PUSHMARK(sp);
1489     PUSHs(sv);
1490     PUTBACK;
1491
1492     perl_call_sv((SV*)cv, G_DISCARD);
1493
1494     SWITCHSTACK(signalstack, oldstack);
1495
1496     return;
1497 }