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