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