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