45ec354c46b63dd4d80956ccc835d236dd9bd577
[p5sagit/p5-mst-13.2.git] / mg.c
1 /*    mg.c
2  *
3  *    Copyright (c) 1991-1997, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * "Sam sat on the ground and put his head in his hands.  'I wish I had never
12  * come here, and I don't want to see no more magic,' he said, and fell silent."
13  */
14
15 #include "EXTERN.h"
16 #include "perl.h"
17
18 /* XXX If this causes problems, set i_unistd=undef in the hint file.  */
19 #ifdef I_UNISTD
20 # include <unistd.h>
21 #endif
22
23 #if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
24 #  ifndef NGROUPS
25 #    define NGROUPS 32
26 #  endif
27 #endif
28
29 /*
30  * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
31  */
32
33 #ifdef PERL_OBJECT
34
35 #define VTBL            this->*vtbl
36
37 #else
38 struct magic_state {
39     SV* mgs_sv;
40     U32 mgs_flags;
41 };
42 typedef struct magic_state MGS;
43
44 static void restore_magic _((void *p));
45 #define VTBL                    *vtbl
46
47 #endif
48
49 STATIC void
50 save_magic(MGS *mgs, 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(void *p)
65 {
66     MGS* mgs = (MGS*)p;
67     SV* sv = mgs->mgs_sv;
68
69     if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
70     {
71         if (mgs->mgs_flags)
72             SvFLAGS(sv) |= mgs->mgs_flags;
73         else
74             mg_magical(sv);
75         if (SvGMAGICAL(sv))
76             SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
77     }
78 }
79
80 void
81 mg_magical(SV *sv)
82 {
83     MAGIC* mg;
84     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
85         MGVTBL* vtbl = mg->mg_virtual;
86         if (vtbl) {
87             if ((vtbl->svt_get != NULL) && !(mg->mg_flags & MGf_GSKIP))
88                 SvGMAGICAL_on(sv);
89             if (vtbl->svt_set)
90                 SvSMAGICAL_on(sv);
91             if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || (vtbl->svt_clear != NULL))
92                 SvRMAGICAL_on(sv);
93         }
94     }
95 }
96
97 int
98 mg_get(SV *sv)
99 {
100     MGS mgs;
101     MAGIC* mg;
102     MAGIC** mgp;
103     int mgp_valid = 0;
104
105     ENTER;
106     save_magic(&mgs, sv);
107
108     mgp = &SvMAGIC(sv);
109     while ((mg = *mgp) != 0) {
110         MGVTBL* vtbl = mg->mg_virtual;
111         if (!(mg->mg_flags & MGf_GSKIP) && vtbl && (vtbl->svt_get != NULL)) {
112             (VTBL->svt_get)(sv, mg);
113             /* Ignore this magic if it's been deleted */
114             if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
115                   (mg->mg_flags & MGf_GSKIP))
116                 mgs.mgs_flags = 0;
117         }
118         /* Advance to next magic (complicated by possible deletion) */
119         if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
120             mgp = &mg->mg_moremagic;
121             mgp_valid = 1;
122         }
123         else
124             mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
125     }
126
127     LEAVE;
128     return 0;
129 }
130
131 int
132 mg_set(SV *sv)
133 {
134     MGS mgs;
135     MAGIC* mg;
136     MAGIC* nextmg;
137
138     ENTER;
139     save_magic(&mgs, sv);
140
141     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
142         MGVTBL* vtbl = mg->mg_virtual;
143         nextmg = mg->mg_moremagic;      /* it may delete itself */
144         if (mg->mg_flags & MGf_GSKIP) {
145             mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
146             mgs.mgs_flags = 0;
147         }
148         if (vtbl && (vtbl->svt_set != NULL))
149             (VTBL->svt_set)(sv, mg);
150     }
151
152     LEAVE;
153     return 0;
154 }
155
156 U32
157 mg_length(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 != NULL)) {
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 I32
182 mg_size(SV *sv)
183 {
184     MAGIC* mg;
185     I32 len;
186     
187     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
188         MGVTBL* vtbl = mg->mg_virtual;
189         if (vtbl && (vtbl->svt_len != NULL)) {
190             MGS mgs;
191             ENTER;
192             /* omit MGf_GSKIP -- not changed here */
193             len = (VTBL->svt_len)(sv, mg);
194             LEAVE;
195             return len;
196         }
197     }
198
199     switch(SvTYPE(sv)) {
200         case SVt_PVAV:
201             len = AvFILLp((AV *) sv); /* Fallback to non-tied array */
202             return len;
203         case SVt_PVHV:
204             /* FIXME */
205         default:
206             croak("Size magic not implemented");
207             break;
208     }
209     return 0;
210 }
211
212 int
213 mg_clear(SV *sv)
214 {
215     MGS mgs;
216     MAGIC* mg;
217
218     ENTER;
219     save_magic(&mgs, sv);
220
221     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
222         MGVTBL* vtbl = mg->mg_virtual;
223         /* omit GSKIP -- never set here */
224         
225         if (vtbl && (vtbl->svt_clear != NULL))
226             (VTBL->svt_clear)(sv, mg);
227     }
228
229     LEAVE;
230     return 0;
231 }
232
233 MAGIC*
234 mg_find(SV *sv, int type)
235 {
236     MAGIC* mg;
237     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
238         if (mg->mg_type == type)
239             return mg;
240     }
241     return 0;
242 }
243
244 int
245 mg_copy(SV *sv, SV *nsv, char *key, I32 klen)
246 {
247     int count = 0;
248     MAGIC* mg;
249     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
250         if (isUPPER(mg->mg_type)) {
251             sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
252             count++;
253         }
254     }
255     return count;
256 }
257
258 int
259 mg_free(SV *sv)
260 {
261     MAGIC* mg;
262     MAGIC* moremagic;
263     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
264         MGVTBL* vtbl = mg->mg_virtual;
265         moremagic = mg->mg_moremagic;
266         if (vtbl && (vtbl->svt_free != NULL))
267             (VTBL->svt_free)(sv, mg);
268         if (mg->mg_ptr && mg->mg_type != 'g')
269             if (mg->mg_len >= 0)
270                 Safefree(mg->mg_ptr);
271             else if (mg->mg_len == HEf_SVKEY)
272                 SvREFCNT_dec((SV*)mg->mg_ptr);
273         if (mg->mg_flags & MGf_REFCOUNTED)
274             SvREFCNT_dec(mg->mg_obj);
275         Safefree(mg);
276     }
277     SvMAGIC(sv) = 0;
278     return 0;
279 }
280
281 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
282 #include <signal.h>
283 #endif
284
285 U32
286 magic_len(SV *sv, MAGIC *mg)
287 {
288     dTHR;
289     register I32 paren;
290     register char *s;
291     register I32 i;
292     register REGEXP *rx;
293     char *t;
294
295     switch (*mg->mg_ptr) {
296     case '1': case '2': case '3': case '4':
297     case '5': case '6': case '7': case '8': case '9': case '&':
298         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
299             paren = atoi(mg->mg_ptr);
300           getparen:
301             if (paren <= rx->nparens &&
302                 (s = rx->startp[paren]) &&
303                 (t = rx->endp[paren]))
304             {
305                 i = t - s;
306                 if (i >= 0)
307                     return i;
308             }
309         }
310         return 0;
311     case '+':
312         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
313             paren = rx->lastparen;
314             if (paren)
315                 goto getparen;
316         }
317         return 0;
318     case '`':
319         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
320             if ((s = rx->subbeg) && rx->startp[0]) {
321                 i = rx->startp[0] - s;
322                 if (i >= 0)
323                     return i;
324             }
325         }
326         return 0;
327     case '\'':
328         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
329             if (rx->subend && (s = rx->endp[0])) {
330                 i = rx->subend - s;
331                 if (i >= 0)
332                     return i;
333             }
334         }
335         return 0;
336     case ',':
337         return (STRLEN)PL_ofslen;
338     case '\\':
339         return (STRLEN)PL_orslen;
340     }
341     magic_get(sv,mg);
342     if (!SvPOK(sv) && SvNIOK(sv))
343         sv_2pv(sv, &PL_na);
344     if (SvPOK(sv))
345         return SvCUR(sv);
346     return 0;
347 }
348
349 int
350 magic_get(SV *sv, MAGIC *mg)
351 {
352     dTHR;
353     register I32 paren;
354     register char *s;
355     register I32 i;
356     register REGEXP *rx;
357     char *t;
358
359     switch (*mg->mg_ptr) {
360     case '\001':                /* ^A */
361         sv_setsv(sv, PL_bodytarget);
362         break;
363     case '\004':                /* ^D */
364         sv_setiv(sv, (IV)(PL_debug & 32767));
365         break;
366     case '\005':  /* ^E */
367 #ifdef VMS
368         {
369 #           include <descrip.h>
370 #           include <starlet.h>
371             char msg[255];
372             $DESCRIPTOR(msgdsc,msg);
373             sv_setnv(sv,(double) vaxc$errno);
374             if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
375                 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
376             else
377                 sv_setpv(sv,"");
378         }
379 #else
380 #ifdef OS2
381         if (!(_emx_env & 0x200)) {      /* Under DOS */
382             sv_setnv(sv, (double)errno);
383             sv_setpv(sv, errno ? Strerror(errno) : "");
384         } else {
385             if (errno != errno_isOS2)
386                 Perl_rc = _syserrno();
387             sv_setnv(sv, (double)Perl_rc);
388             sv_setpv(sv, os2error(Perl_rc));
389         }
390 #else
391 #ifdef WIN32
392         {
393             DWORD dwErr = GetLastError();
394             sv_setnv(sv, (double)dwErr);
395             if (dwErr)
396             {
397 #ifdef PERL_OBJECT
398                 char *sMsg;
399                 DWORD dwLen;
400                 PerlProc_GetSysMsg(sMsg, dwLen, dwErr);
401                 sv_setpvn(sv, sMsg, dwLen);
402                 PerlProc_FreeBuf(sMsg);
403 #else
404                 win32_str_os_error(sv, dwErr);
405 #endif
406             }
407             else
408                 sv_setpv(sv, "");
409             SetLastError(dwErr);
410         }
411 #else
412         sv_setnv(sv, (double)errno);
413         sv_setpv(sv, errno ? Strerror(errno) : "");
414 #endif
415 #endif
416 #endif
417         SvNOK_on(sv);   /* what a wonderful hack! */
418         break;
419     case '\006':                /* ^F */
420         sv_setiv(sv, (IV)PL_maxsysfd);
421         break;
422     case '\010':                /* ^H */
423         sv_setiv(sv, (IV)PL_hints);
424         break;
425     case '\t':                  /* ^I */
426         if (PL_inplace)
427             sv_setpv(sv, PL_inplace);
428         else
429             sv_setsv(sv, &PL_sv_undef);
430         break;
431     case '\017':                /* ^O */
432         sv_setpv(sv, PL_osname);
433         break;
434     case '\020':                /* ^P */
435         sv_setiv(sv, (IV)PL_perldb);
436         break;
437     case '\023':                /* ^S */
438         {
439             dTHR;
440             if (PL_lex_state != LEX_NOTPARSING)
441                 SvOK_off(sv);
442             else if (PL_in_eval)
443                 sv_setiv(sv, 1);
444             else
445                 sv_setiv(sv, 0);
446         }
447         break;
448     case '\024':                /* ^T */
449 #ifdef BIG_TIME
450         sv_setnv(sv, PL_basetime);
451 #else
452         sv_setiv(sv, (IV)PL_basetime);
453 #endif
454         break;
455     case '\027':                /* ^W */
456         sv_setiv(sv, (IV)PL_dowarn);
457         break;
458     case '1': case '2': case '3': case '4':
459     case '5': case '6': case '7': case '8': case '9': case '&':
460         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
461             /*
462              * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
463              * XXX Does the new way break anything?
464              */
465             paren = atoi(mg->mg_ptr);
466           getparen:
467             if (paren <= rx->nparens &&
468                 (s = rx->startp[paren]) &&
469                 (t = rx->endp[paren]))
470             {
471                 i = t - s;
472               getrx:
473                 if (i >= 0) {
474                     bool was_tainted;
475                     if (PL_tainting) {
476                         was_tainted = PL_tainted;
477                         PL_tainted = FALSE;
478                     }
479                     sv_setpvn(sv,s,i);
480                     if (PL_tainting)
481                         PL_tainted = (was_tainted || RX_MATCH_TAINTED(rx));
482                     break;
483                 }
484             }
485         }
486         sv_setsv(sv,&PL_sv_undef);
487         break;
488     case '+':
489         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
490             paren = rx->lastparen;
491             if (paren)
492                 goto getparen;
493         }
494         sv_setsv(sv,&PL_sv_undef);
495         break;
496     case '`':
497         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
498             if ((s = rx->subbeg) && rx->startp[0]) {
499                 i = rx->startp[0] - s;
500                 goto getrx;
501             }
502         }
503         sv_setsv(sv,&PL_sv_undef);
504         break;
505     case '\'':
506         if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
507             if (rx->subend && (s = rx->endp[0])) {
508                 i = rx->subend - s;
509                 goto getrx;
510             }
511         }
512         sv_setsv(sv,&PL_sv_undef);
513         break;
514     case '.':
515 #ifndef lint
516         if (GvIO(PL_last_in_gv)) {
517             sv_setiv(sv, (IV)IoLINES(GvIO(PL_last_in_gv)));
518         }
519 #endif
520         break;
521     case '?':
522         {
523             dTHR;
524             sv_setiv(sv, (IV)STATUS_CURRENT);
525 #ifdef COMPLEX_STATUS
526             LvTARGOFF(sv) = PL_statusvalue;
527             LvTARGLEN(sv) = PL_statusvalue_vms;
528 #endif
529         }
530         break;
531     case '^':
532         s = IoTOP_NAME(GvIOp(PL_defoutgv));
533         if (s)
534             sv_setpv(sv,s);
535         else {
536             sv_setpv(sv,GvENAME(PL_defoutgv));
537             sv_catpv(sv,"_TOP");
538         }
539         break;
540     case '~':
541         s = IoFMT_NAME(GvIOp(PL_defoutgv));
542         if (!s)
543             s = GvENAME(PL_defoutgv);
544         sv_setpv(sv,s);
545         break;
546 #ifndef lint
547     case '=':
548         sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
549         break;
550     case '-':
551         sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
552         break;
553     case '%':
554         sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
555         break;
556 #endif
557     case ':':
558         break;
559     case '/':
560         break;
561     case '[':
562         WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
563         break;
564     case '|':
565         sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
566         break;
567     case ',':
568         sv_setpvn(sv,PL_ofs,PL_ofslen);
569         break;
570     case '\\':
571         sv_setpvn(sv,PL_ors,PL_orslen);
572         break;
573     case '#':
574         sv_setpv(sv,PL_ofmt);
575         break;
576     case '!':
577 #ifdef VMS
578         sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
579         sv_setpv(sv, errno ? Strerror(errno) : "");
580 #else
581         {
582         int saveerrno = errno;
583         sv_setnv(sv, (double)errno);
584 #ifdef OS2
585         if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
586         else
587 #endif
588         sv_setpv(sv, errno ? Strerror(errno) : "");
589         errno = saveerrno;
590         }
591 #endif
592         SvNOK_on(sv);   /* what a wonderful hack! */
593         break;
594     case '<':
595         sv_setiv(sv, (IV)PL_uid);
596         break;
597     case '>':
598         sv_setiv(sv, (IV)PL_euid);
599         break;
600     case '(':
601         sv_setiv(sv, (IV)PL_gid);
602         sv_setpvf(sv, "%Vd", (IV)PL_gid);
603         goto add_groups;
604     case ')':
605         sv_setiv(sv, (IV)PL_egid);
606         sv_setpvf(sv, "%Vd", (IV)PL_egid);
607       add_groups:
608 #ifdef HAS_GETGROUPS
609         {
610             Groups_t gary[NGROUPS];
611             i = getgroups(NGROUPS,gary);
612             while (--i >= 0)
613                 sv_catpvf(sv, " %Vd", (IV)gary[i]);
614         }
615 #endif
616         SvIOK_on(sv);   /* what a wonderful hack! */
617         break;
618     case '*':
619         break;
620     case '0':
621         break;
622 #ifdef USE_THREADS
623     case '@':
624         sv_setsv(sv, thr->errsv);
625         break;
626 #endif /* USE_THREADS */
627     }
628     return 0;
629 }
630
631 int
632 magic_getuvar(SV *sv, MAGIC *mg)
633 {
634     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
635
636     if (uf && uf->uf_val)
637         (*uf->uf_val)(uf->uf_index, sv);
638     return 0;
639 }
640
641 int
642 magic_setenv(SV *sv, MAGIC *mg)
643 {
644     register char *s;
645     char *ptr;
646     STRLEN len, klen;
647     I32 i;
648
649     s = SvPV(sv,len);
650     ptr = MgPV(mg,klen);
651     my_setenv(ptr, s);
652
653 #ifdef DYNAMIC_ENV_FETCH
654      /* We just undefd an environment var.  Is a replacement */
655      /* waiting in the wings? */
656     if (!len) {
657         SV **valp;
658         if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
659             s = SvPV(*valp, len);
660     }
661 #endif
662
663 #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
664                             /* And you'll never guess what the dog had */
665                             /*   in its mouth... */
666     if (PL_tainting) {
667         MgTAINTEDDIR_off(mg);
668 #ifdef VMS
669         if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
670             char pathbuf[256], eltbuf[256], *cp, *elt = s;
671             struct stat sbuf;
672             int i = 0, j = 0;
673
674             do {          /* DCL$PATH may be a search list */
675                 while (1) {   /* as may dev portion of any element */
676                     if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
677                         if ( *(cp+1) == '.' || *(cp+1) == '-' ||
678                              cando_by_name(S_IWUSR,0,elt) ) {
679                             MgTAINTEDDIR_on(mg);
680                             return 0;
681                         }
682                     }
683                     if ((cp = strchr(elt, ':')) != Nullch)
684                         *cp = '\0';
685                     if (my_trnlnm(elt, eltbuf, j++))
686                         elt = eltbuf;
687                     else
688                         break;
689                 }
690                 j = 0;
691             } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
692         }
693 #endif /* VMS */
694         if (s && klen == 4 && strEQ(ptr,"PATH")) {
695             char *strend = s + len;
696
697             while (s < strend) {
698                 char tmpbuf[256];
699                 struct stat st;
700                 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
701                              s, strend, ':', &i);
702                 s++;
703                 if (i >= sizeof tmpbuf   /* too long -- assume the worst */
704                       || *tmpbuf != '/'
705                       || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
706                     MgTAINTEDDIR_on(mg);
707                     return 0;
708                 }
709             }
710         }
711     }
712 #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
713
714     return 0;
715 }
716
717 int
718 magic_clearenv(SV *sv, MAGIC *mg)
719 {
720     my_setenv(MgPV(mg,PL_na),Nullch);
721     return 0;
722 }
723
724 int
725 magic_set_all_env(SV *sv, MAGIC *mg)
726 {
727 #if defined(VMS)
728     die("Can't make list assignment to %%ENV on this system");
729 #else
730     dTHR;
731     if (PL_localizing) {
732         HE* entry;
733         magic_clear_all_env(sv,mg);
734         hv_iterinit((HV*)sv);
735         while (entry = hv_iternext((HV*)sv)) {
736             I32 keylen;
737             my_setenv(hv_iterkey(entry, &keylen),
738                       SvPV(hv_iterval((HV*)sv, entry), PL_na));
739         }
740     }
741 #endif
742     return 0;
743 }
744
745 int
746 magic_clear_all_env(SV *sv, MAGIC *mg)
747 {
748 #if defined(VMS)
749     die("Can't make list assignment to %%ENV on this system");
750 #else
751 #ifdef WIN32
752     char *envv = GetEnvironmentStrings();
753     char *cur = envv;
754     STRLEN len;
755     while (*cur) {
756         char *end = strchr(cur,'=');
757         if (end && end != cur) {
758             *end = '\0';
759             my_setenv(cur,Nullch);
760             *end = '=';
761             cur += strlen(end+1)+1;
762         }
763         else if ((len = strlen(cur)))
764             cur += len+1;
765     }
766     FreeEnvironmentStrings(envv);
767 #else
768     I32 i;
769
770     if (environ == PL_origenviron)
771         New(901, environ, 1, char*);
772     else
773         for (i = 0; environ[i]; i++)
774             Safefree(environ[i]);
775     environ[0] = Nullch;
776
777 #endif
778 #endif
779     return 0;
780 }
781
782 int
783 magic_getsig(SV *sv, MAGIC *mg)
784 {
785     I32 i;
786     /* Are we fetching a signal entry? */
787     i = whichsig(MgPV(mg,PL_na));
788     if (i) {
789         if(psig_ptr[i])
790             sv_setsv(sv,psig_ptr[i]);
791         else {
792             Sighandler_t sigstate = rsignal_state(i);
793
794             /* cache state so we don't fetch it again */
795             if(sigstate == SIG_IGN)
796                 sv_setpv(sv,"IGNORE");
797             else
798                 sv_setsv(sv,&PL_sv_undef);
799             psig_ptr[i] = SvREFCNT_inc(sv);
800             SvTEMP_off(sv);
801         }
802     }
803     return 0;
804 }
805 int
806 magic_clearsig(SV *sv, MAGIC *mg)
807 {
808     I32 i;
809     /* Are we clearing a signal entry? */
810     i = whichsig(MgPV(mg,PL_na));
811     if (i) {
812         if(psig_ptr[i]) {
813             SvREFCNT_dec(psig_ptr[i]);
814             psig_ptr[i]=0;
815         }
816         if(psig_name[i]) {
817             SvREFCNT_dec(psig_name[i]);
818             psig_name[i]=0;
819         }
820     }
821     return 0;
822 }
823
824 int
825 magic_setsig(SV *sv, MAGIC *mg)
826 {
827     dTHR;
828     register char *s;
829     I32 i;
830     SV** svp;
831
832     s = MgPV(mg,PL_na);
833     if (*s == '_') {
834         if (strEQ(s,"__DIE__"))
835             svp = &PL_diehook;
836         else if (strEQ(s,"__WARN__"))
837             svp = &PL_warnhook;
838         else if (strEQ(s,"__PARSE__"))
839             svp = &PL_parsehook;
840         else
841             croak("No such hook: %s", s);
842         i = 0;
843         if (*svp) {
844             SvREFCNT_dec(*svp);
845             *svp = 0;
846         }
847     }
848     else {
849         i = whichsig(s);        /* ...no, a brick */
850         if (!i) {
851             if (PL_dowarn || strEQ(s,"ALARM"))
852                 warn("No such signal: SIG%s", s);
853             return 0;
854         }
855         SvREFCNT_dec(psig_name[i]);
856         SvREFCNT_dec(psig_ptr[i]);
857         psig_ptr[i] = SvREFCNT_inc(sv);
858         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
859         psig_name[i] = newSVpv(s, strlen(s));
860         SvREADONLY_on(psig_name[i]);
861     }
862     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
863         if (i)
864             (void)rsignal(i, PL_sighandlerp);
865         else
866             *svp = SvREFCNT_inc(sv);
867         return 0;
868     }
869     s = SvPV_force(sv,PL_na);
870     if (strEQ(s,"IGNORE")) {
871         if (i)
872             (void)rsignal(i, SIG_IGN);
873         else
874             *svp = 0;
875     }
876     else if (strEQ(s,"DEFAULT") || !*s) {
877         if (i)
878             (void)rsignal(i, SIG_DFL);
879         else
880             *svp = 0;
881     }
882     else {
883         /*
884          * We should warn if HINT_STRICT_REFS, but without
885          * access to a known hint bit in a known OP, we can't
886          * tell whether HINT_STRICT_REFS is in force or not.
887          */
888         if (!strchr(s,':') && !strchr(s,'\''))
889             sv_setpv(sv, form("main::%s", s));
890         if (i)
891             (void)rsignal(i, PL_sighandlerp);
892         else
893             *svp = SvREFCNT_inc(sv);
894     }
895     return 0;
896 }
897
898 int
899 magic_setisa(SV *sv, MAGIC *mg)
900 {
901     PL_sub_generation++;
902     return 0;
903 }
904
905 #ifdef OVERLOAD
906
907 int
908 magic_setamagic(SV *sv, MAGIC *mg)
909 {
910     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
911     PL_amagic_generation++;
912
913     return 0;
914 }
915 #endif /* OVERLOAD */
916
917 int
918 magic_getnkeys(SV *sv, MAGIC *mg)
919 {
920     HV *hv = (HV*)LvTARG(sv);
921     HE *entry;
922     I32 i = 0;
923
924     if (hv) {
925         (void) hv_iterinit(hv);
926         if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
927             i = HvKEYS(hv);
928         else {
929             /*SUPPRESS 560*/
930             while (entry = hv_iternext(hv)) {
931                 i++;
932             }
933         }
934     }
935
936     sv_setiv(sv, (IV)i);
937     return 0;
938 }
939
940 int
941 magic_setnkeys(SV *sv, MAGIC *mg)
942 {
943     if (LvTARG(sv)) {
944         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
945     }
946     return 0;
947 }          
948
949 /* caller is responsible for stack switching/cleanup */
950 STATIC int
951 magic_methcall(MAGIC *mg, char *meth, I32 flags, int n, SV *val)
952 {
953     dSP;
954
955     PUSHMARK(SP);
956     EXTEND(SP, n);
957     PUSHs(mg->mg_obj);
958     if (n > 1) { 
959         if (mg->mg_ptr) {
960             if (mg->mg_len >= 0)
961                 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
962             else if (mg->mg_len == HEf_SVKEY)
963                 PUSHs((SV*)mg->mg_ptr);
964         }
965         else if (mg->mg_type == 'p') {
966             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
967         }
968     }
969     if (n > 2) {
970         PUSHs(val);
971     }
972     PUTBACK;
973
974     return perl_call_method(meth, flags);
975 }
976
977 STATIC int
978 magic_methpack(SV *sv, MAGIC *mg, char *meth)
979 {
980     dSP;
981
982     ENTER;
983     SAVETMPS;
984     PUSHSTACKi(PERLSI_MAGIC);
985
986     if (magic_methcall(mg, meth, G_SCALAR, 2, NULL)) {
987         sv_setsv(sv, *PL_stack_sp--);
988     }
989
990     POPSTACK;
991     FREETMPS;
992     LEAVE;
993     return 0;
994 }
995
996 int
997 magic_getpack(SV *sv, MAGIC *mg)
998 {
999     magic_methpack(sv,mg,"FETCH");
1000     if (mg->mg_ptr)
1001         mg->mg_flags |= MGf_GSKIP;
1002     return 0;
1003 }
1004
1005 int
1006 magic_setpack(SV *sv, MAGIC *mg)
1007 {
1008     dSP;
1009     ENTER;
1010     PUSHSTACKi(PERLSI_MAGIC);
1011     magic_methcall(mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1012     POPSTACK;
1013     LEAVE;
1014     return 0;
1015 }
1016
1017 int
1018 magic_clearpack(SV *sv, MAGIC *mg)
1019 {
1020     return magic_methpack(sv,mg,"DELETE");
1021 }
1022
1023
1024 U32
1025 magic_sizepack(SV *sv, MAGIC *mg)
1026 {         
1027     dSP;
1028     U32 retval = 0;
1029
1030     ENTER;
1031     SAVETMPS;
1032     PUSHSTACKi(PERLSI_MAGIC);
1033     if (magic_methcall(mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1034         sv = *PL_stack_sp--;
1035         retval = (U32) SvIV(sv)-1;
1036     }
1037     POPSTACK;
1038     FREETMPS;
1039     LEAVE;
1040     return retval;
1041 }
1042
1043 int magic_wipepack(SV *sv, MAGIC *mg)
1044 {
1045     dSP;
1046
1047     ENTER;
1048     PUSHSTACKi(PERLSI_MAGIC);
1049     PUSHMARK(SP);
1050     XPUSHs(mg->mg_obj);
1051     PUTBACK;
1052     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
1053     POPSTACK;
1054     LEAVE;
1055     return 0;
1056 }
1057
1058 int
1059 magic_nextpack(SV *sv, MAGIC *mg, SV *key)
1060 {
1061     dSP;
1062     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1063
1064     ENTER;
1065     SAVETMPS;
1066     PUSHSTACKi(PERLSI_MAGIC);
1067     PUSHMARK(SP);
1068     EXTEND(SP, 2);
1069     PUSHs(mg->mg_obj);
1070     if (SvOK(key))
1071         PUSHs(key);
1072     PUTBACK;
1073
1074     if (perl_call_method(meth, G_SCALAR))
1075         sv_setsv(key, *PL_stack_sp--);
1076
1077     POPSTACK;
1078     FREETMPS;
1079     LEAVE;
1080     return 0;
1081 }
1082
1083 int
1084 magic_existspack(SV *sv, MAGIC *mg)
1085 {
1086     return magic_methpack(sv,mg,"EXISTS");
1087
1088
1089 int
1090 magic_setdbline(SV *sv, MAGIC *mg)
1091 {
1092     dTHR;
1093     OP *o;
1094     I32 i;
1095     GV* gv;
1096     SV** svp;
1097
1098     gv = PL_DBline;
1099     i = SvTRUE(sv);
1100     svp = av_fetch(GvAV(gv),
1101                      atoi(MgPV(mg,PL_na)), FALSE);
1102     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
1103         o->op_private = i;
1104     else
1105         warn("Can't break at that line\n");
1106     return 0;
1107 }
1108
1109 int
1110 magic_getarylen(SV *sv, MAGIC *mg)
1111 {
1112     dTHR;
1113     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
1114     return 0;
1115 }
1116
1117 int
1118 magic_setarylen(SV *sv, MAGIC *mg)
1119 {
1120     dTHR;
1121     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
1122     return 0;
1123 }
1124
1125 int
1126 magic_getpos(SV *sv, MAGIC *mg)
1127 {
1128     SV* lsv = LvTARG(sv);
1129     
1130     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1131         mg = mg_find(lsv, 'g');
1132         if (mg && mg->mg_len >= 0) {
1133             dTHR;
1134             I32 i = mg->mg_len;
1135             if (IN_UTF8)
1136                 sv_pos_b2u(lsv, &i);
1137             sv_setiv(sv, i + PL_curcop->cop_arybase);
1138             return 0;
1139         }
1140     }
1141     (void)SvOK_off(sv);
1142     return 0;
1143 }
1144
1145 int
1146 magic_setpos(SV *sv, MAGIC *mg)
1147 {
1148     SV* lsv = LvTARG(sv);
1149     SSize_t pos;
1150     STRLEN len;
1151     STRLEN ulen;
1152     dTHR;
1153
1154     mg = 0;
1155     
1156     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1157         mg = mg_find(lsv, 'g');
1158     if (!mg) {
1159         if (!SvOK(sv))
1160             return 0;
1161         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1162         mg = mg_find(lsv, 'g');
1163     }
1164     else if (!SvOK(sv)) {
1165         mg->mg_len = -1;
1166         return 0;
1167     }
1168     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1169
1170     pos = SvIV(sv) - PL_curcop->cop_arybase;
1171
1172     if (IN_UTF8) {
1173         ulen = sv_len_utf8(lsv);
1174         if (ulen)
1175             len = ulen;
1176         else
1177             ulen = 0;
1178     }
1179
1180     if (pos < 0) {
1181         pos += len;
1182         if (pos < 0)
1183             pos = 0;
1184     }
1185     else if (pos > len)
1186         pos = len;
1187
1188     if (ulen) {
1189         I32 p = pos;
1190         sv_pos_u2b(lsv, &p, 0);
1191         pos = p;
1192     }
1193         
1194     mg->mg_len = pos;
1195     mg->mg_flags &= ~MGf_MINMATCH;
1196
1197     return 0;
1198 }
1199
1200 int
1201 magic_getglob(SV *sv, MAGIC *mg)
1202 {
1203     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1204         SvFAKE_off(sv);
1205         gv_efullname3(sv,((GV*)sv), "*");
1206         SvFAKE_on(sv);
1207     }
1208     else
1209         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1210     return 0;
1211 }
1212
1213 int
1214 magic_setglob(SV *sv, MAGIC *mg)
1215 {
1216     register char *s;
1217     GV* gv;
1218
1219     if (!SvOK(sv))
1220         return 0;
1221     s = SvPV(sv, PL_na);
1222     if (*s == '*' && s[1])
1223         s++;
1224     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1225     if (sv == (SV*)gv)
1226         return 0;
1227     if (GvGP(sv))
1228         gp_free((GV*)sv);
1229     GvGP(sv) = gp_ref(GvGP(gv));
1230     return 0;
1231 }
1232
1233 int
1234 magic_getsubstr(SV *sv, MAGIC *mg)
1235 {
1236     STRLEN len;
1237     SV *lsv = LvTARG(sv);
1238     char *tmps = SvPV(lsv,len);
1239     I32 offs = LvTARGOFF(sv);
1240     I32 rem = LvTARGLEN(sv);
1241
1242     if (offs > len)
1243         offs = len;
1244     if (rem + offs > len)
1245         rem = len - offs;
1246     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
1247     return 0;
1248 }
1249
1250 int
1251 magic_setsubstr(SV *sv, MAGIC *mg)
1252 {
1253     STRLEN len;
1254     char *tmps = SvPV(sv,len);
1255     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1256     return 0;
1257 }
1258
1259 int
1260 magic_gettaint(SV *sv, MAGIC *mg)
1261 {
1262     dTHR;
1263     TAINT_IF((mg->mg_len & 1) ||
1264              (mg->mg_len & 2) && mg->mg_obj == sv);     /* kludge */
1265     return 0;
1266 }
1267
1268 int
1269 magic_settaint(SV *sv, MAGIC *mg)
1270 {
1271     dTHR;
1272     if (PL_localizing) {
1273         if (PL_localizing == 1)
1274             mg->mg_len <<= 1;
1275         else
1276             mg->mg_len >>= 1;
1277     }
1278     else if (PL_tainted)
1279         mg->mg_len |= 1;
1280     else
1281         mg->mg_len &= ~1;
1282     return 0;
1283 }
1284
1285 int
1286 magic_getvec(SV *sv, MAGIC *mg)
1287 {
1288     SV *lsv = LvTARG(sv);
1289     unsigned char *s;
1290     unsigned long retnum;
1291     STRLEN lsvlen;
1292     I32 len;
1293     I32 offset;
1294     I32 size;
1295
1296     if (!lsv) {
1297         SvOK_off(sv);
1298         return 0;
1299     }
1300     s = (unsigned char *) SvPV(lsv, lsvlen);
1301     offset = LvTARGOFF(sv);
1302     size = LvTARGLEN(sv);
1303     len = (offset + size + 7) / 8;
1304
1305     /* Copied from pp_vec() */
1306
1307     if (len > lsvlen) {
1308         if (size <= 8)
1309             retnum = 0;
1310         else {
1311             offset >>= 3;
1312             if (size == 16) {
1313                 if (offset >= lsvlen)
1314                     retnum = 0;
1315                 else
1316                     retnum = (unsigned long) s[offset] << 8;
1317             }
1318             else if (size == 32) {
1319                 if (offset >= lsvlen)
1320                     retnum = 0;
1321                 else if (offset + 1 >= lsvlen)
1322                     retnum = (unsigned long) s[offset] << 24;
1323                 else if (offset + 2 >= lsvlen)
1324                     retnum = ((unsigned long) s[offset] << 24) +
1325                         ((unsigned long) s[offset + 1] << 16);
1326                 else
1327                     retnum = ((unsigned long) s[offset] << 24) +
1328                         ((unsigned long) s[offset + 1] << 16) +
1329                         (s[offset + 2] << 8);
1330             }
1331         }
1332     }
1333     else if (size < 8)
1334         retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
1335     else {
1336         offset >>= 3;
1337         if (size == 8)
1338             retnum = s[offset];
1339         else if (size == 16)
1340             retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
1341         else if (size == 32)
1342             retnum = ((unsigned long) s[offset] << 24) +
1343                 ((unsigned long) s[offset + 1] << 16) +
1344                 (s[offset + 2] << 8) + s[offset+3];
1345     }
1346
1347     sv_setuv(sv, (UV)retnum);
1348     return 0;
1349 }
1350
1351 int
1352 magic_setvec(SV *sv, MAGIC *mg)
1353 {
1354     do_vecset(sv);      /* XXX slurp this routine */
1355     return 0;
1356 }
1357
1358 int
1359 magic_getdefelem(SV *sv, MAGIC *mg)
1360 {
1361     SV *targ = Nullsv;
1362     if (LvTARGLEN(sv)) {
1363         if (mg->mg_obj) {
1364             SV *ahv = LvTARG(sv);
1365             if (SvTYPE(ahv) == SVt_PVHV) {
1366                 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1367                 if (he)
1368                     targ = HeVAL(he);
1369             }
1370             else {
1371                 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1372                 if (svp)
1373                     targ = *svp;
1374             }
1375         }
1376         else {
1377             AV* av = (AV*)LvTARG(sv);
1378             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1379                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1380         }
1381         if (targ && targ != &PL_sv_undef) {
1382             dTHR;               /* just for SvREFCNT_dec */
1383             /* somebody else defined it for us */
1384             SvREFCNT_dec(LvTARG(sv));
1385             LvTARG(sv) = SvREFCNT_inc(targ);
1386             LvTARGLEN(sv) = 0;
1387             SvREFCNT_dec(mg->mg_obj);
1388             mg->mg_obj = Nullsv;
1389             mg->mg_flags &= ~MGf_REFCOUNTED;
1390         }
1391     }
1392     else
1393         targ = LvTARG(sv);
1394     sv_setsv(sv, targ ? targ : &PL_sv_undef);
1395     return 0;
1396 }
1397
1398 int
1399 magic_setdefelem(SV *sv, MAGIC *mg)
1400 {
1401     if (LvTARGLEN(sv))
1402         vivify_defelem(sv);
1403     if (LvTARG(sv)) {
1404         sv_setsv(LvTARG(sv), sv);
1405         SvSETMAGIC(LvTARG(sv));
1406     }
1407     return 0;
1408 }
1409
1410 void
1411 vivify_defelem(SV *sv)
1412 {
1413     dTHR;                       /* just for SvREFCNT_inc and SvREFCNT_dec*/
1414     MAGIC *mg;
1415     SV *value = Nullsv;
1416
1417     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
1418         return;
1419     if (mg->mg_obj) {
1420         SV *ahv = LvTARG(sv);
1421         if (SvTYPE(ahv) == SVt_PVHV) {
1422             HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1423             if (he)
1424                 value = HeVAL(he);
1425         }
1426         else {
1427             SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1428             if (svp)
1429                 value = *svp;
1430         }
1431         if (!value || value == &PL_sv_undef)
1432             croak(no_helem, SvPV(mg->mg_obj, PL_na));
1433     }
1434     else {
1435         AV* av = (AV*)LvTARG(sv);
1436         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1437             LvTARG(sv) = Nullsv;        /* array can't be extended */
1438         else {
1439             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1440             if (!svp || (value = *svp) == &PL_sv_undef)
1441                 croak(no_aelem, (I32)LvTARGOFF(sv));
1442         }
1443     }
1444     (void)SvREFCNT_inc(value);
1445     SvREFCNT_dec(LvTARG(sv));
1446     LvTARG(sv) = value;
1447     LvTARGLEN(sv) = 0;
1448     SvREFCNT_dec(mg->mg_obj);
1449     mg->mg_obj = Nullsv;
1450     mg->mg_flags &= ~MGf_REFCOUNTED;
1451 }
1452
1453 int
1454 magic_setmglob(SV *sv, MAGIC *mg)
1455 {
1456     mg->mg_len = -1;
1457     SvSCREAM_off(sv);
1458     return 0;
1459 }
1460
1461 int
1462 magic_setbm(SV *sv, MAGIC *mg)
1463 {
1464     sv_unmagic(sv, 'B');
1465     SvVALID_off(sv);
1466     return 0;
1467 }
1468
1469 int
1470 magic_setfm(SV *sv, MAGIC *mg)
1471 {
1472     sv_unmagic(sv, 'f');
1473     SvCOMPILED_off(sv);
1474     return 0;
1475 }
1476
1477 int
1478 magic_setuvar(SV *sv, MAGIC *mg)
1479 {
1480     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1481
1482     if (uf && uf->uf_set)
1483         (*uf->uf_set)(uf->uf_index, sv);
1484     return 0;
1485 }
1486
1487 int
1488 magic_freeregexp(SV *sv, MAGIC *mg)
1489 {
1490     regexp *re = (regexp *)mg->mg_obj;
1491     ReREFCNT_dec(re);
1492     return 0;
1493 }
1494
1495 #ifdef USE_LOCALE_COLLATE
1496 int
1497 magic_setcollxfrm(SV *sv, MAGIC *mg)
1498 {
1499     /*
1500      * René Descartes said "I think not."
1501      * and vanished with a faint plop.
1502      */
1503     if (mg->mg_ptr) {
1504         Safefree(mg->mg_ptr);
1505         mg->mg_ptr = NULL;
1506         mg->mg_len = -1;
1507     }
1508     return 0;
1509 }
1510 #endif /* USE_LOCALE_COLLATE */
1511
1512 int
1513 magic_set(SV *sv, MAGIC *mg)
1514 {
1515     dTHR;
1516     register char *s;
1517     I32 i;
1518     STRLEN len;
1519     switch (*mg->mg_ptr) {
1520     case '\001':        /* ^A */
1521         sv_setsv(PL_bodytarget, sv);
1522         break;
1523     case '\004':        /* ^D */
1524         PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1525         DEBUG_x(dump_all());
1526         break;
1527     case '\005':  /* ^E */
1528 #ifdef VMS
1529         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1530 #else
1531 #ifdef WIN32
1532         SetLastError( SvIV(sv) );
1533 #else
1534         /* will anyone ever use this? */
1535         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1536 #endif
1537 #endif
1538         break;
1539     case '\006':        /* ^F */
1540         PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1541         break;
1542     case '\010':        /* ^H */
1543         PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1544         break;
1545     case '\t':  /* ^I */
1546         if (PL_inplace)
1547             Safefree(PL_inplace);
1548         if (SvOK(sv))
1549             PL_inplace = savepv(SvPV(sv,PL_na));
1550         else
1551             PL_inplace = Nullch;
1552         break;
1553     case '\017':        /* ^O */
1554         if (PL_osname)
1555             Safefree(PL_osname);
1556         if (SvOK(sv))
1557             PL_osname = savepv(SvPV(sv,PL_na));
1558         else
1559             PL_osname = Nullch;
1560         break;
1561     case '\020':        /* ^P */
1562         PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1563         break;
1564     case '\024':        /* ^T */
1565 #ifdef BIG_TIME
1566         PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1567 #else
1568         PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1569 #endif
1570         break;
1571     case '\027':        /* ^W */
1572         PL_dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1573         break;
1574     case '.':
1575         if (PL_localizing) {
1576             if (PL_localizing == 1)
1577                 save_sptr((SV**)&PL_last_in_gv);
1578         }
1579         else if (SvOK(sv) && GvIO(PL_last_in_gv))
1580             IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv);
1581         break;
1582     case '^':
1583         Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
1584         IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
1585         IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1586         break;
1587     case '~':
1588         Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
1589         IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
1590         IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1591         break;
1592     case '=':
1593         IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1594         break;
1595     case '-':
1596         IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1597         if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
1598             IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
1599         break;
1600     case '%':
1601         IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1602         break;
1603     case '|':
1604         {
1605             IO *io = GvIOp(PL_defoutgv);
1606             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1607                 IoFLAGS(io) &= ~IOf_FLUSH;
1608             else {
1609                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1610                     PerlIO *ofp = IoOFP(io);
1611                     if (ofp)
1612                         (void)PerlIO_flush(ofp);
1613                     IoFLAGS(io) |= IOf_FLUSH;
1614                 }
1615             }
1616         }
1617         break;
1618     case '*':
1619         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1620         PL_multiline = (i != 0);
1621         break;
1622     case '/':
1623         SvREFCNT_dec(PL_nrs);
1624         PL_nrs = newSVsv(sv);
1625         SvREFCNT_dec(PL_rs);
1626         PL_rs = SvREFCNT_inc(PL_nrs);
1627         break;
1628     case '\\':
1629         if (PL_ors)
1630             Safefree(PL_ors);
1631         if (SvOK(sv) || SvGMAGICAL(sv))
1632             PL_ors = savepv(SvPV(sv,PL_orslen));
1633         else {
1634             PL_ors = Nullch;
1635             PL_orslen = 0;
1636         }
1637         break;
1638     case ',':
1639         if (PL_ofs)
1640             Safefree(PL_ofs);
1641         PL_ofs = savepv(SvPV(sv, PL_ofslen));
1642         break;
1643     case '#':
1644         if (PL_ofmt)
1645             Safefree(PL_ofmt);
1646         PL_ofmt = savepv(SvPV(sv,PL_na));
1647         break;
1648     case '[':
1649         PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1650         break;
1651     case '?':
1652 #ifdef COMPLEX_STATUS
1653         if (PL_localizing == 2) {
1654             PL_statusvalue = LvTARGOFF(sv);
1655             PL_statusvalue_vms = LvTARGLEN(sv);
1656         }
1657         else
1658 #endif
1659 #ifdef VMSISH_STATUS
1660         if (VMSISH_STATUS)
1661             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1662         else
1663 #endif
1664             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1665         break;
1666     case '!':
1667         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1668                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1669         break;
1670     case '<':
1671         PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1672         if (PL_delaymagic) {
1673             PL_delaymagic |= DM_RUID;
1674             break;                              /* don't do magic till later */
1675         }
1676 #ifdef HAS_SETRUID
1677         (void)setruid((Uid_t)PL_uid);
1678 #else
1679 #ifdef HAS_SETREUID
1680         (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
1681 #else
1682 #ifdef HAS_SETRESUID
1683       (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
1684 #else
1685         if (PL_uid == PL_euid)          /* special case $< = $> */
1686             (void)PerlProc_setuid(PL_uid);
1687         else {
1688             PL_uid = (I32)PerlProc_getuid();
1689             croak("setruid() not implemented");
1690         }
1691 #endif
1692 #endif
1693 #endif
1694         PL_uid = (I32)PerlProc_getuid();
1695         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1696         break;
1697     case '>':
1698         PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1699         if (PL_delaymagic) {
1700             PL_delaymagic |= DM_EUID;
1701             break;                              /* don't do magic till later */
1702         }
1703 #ifdef HAS_SETEUID
1704         (void)seteuid((Uid_t)PL_euid);
1705 #else
1706 #ifdef HAS_SETREUID
1707         (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
1708 #else
1709 #ifdef HAS_SETRESUID
1710         (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
1711 #else
1712         if (PL_euid == PL_uid)          /* special case $> = $< */
1713             PerlProc_setuid(PL_euid);
1714         else {
1715             PL_euid = (I32)PerlProc_geteuid();
1716             croak("seteuid() not implemented");
1717         }
1718 #endif
1719 #endif
1720 #endif
1721         PL_euid = (I32)PerlProc_geteuid();
1722         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1723         break;
1724     case '(':
1725         PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1726         if (PL_delaymagic) {
1727             PL_delaymagic |= DM_RGID;
1728             break;                              /* don't do magic till later */
1729         }
1730 #ifdef HAS_SETRGID
1731         (void)setrgid((Gid_t)PL_gid);
1732 #else
1733 #ifdef HAS_SETREGID
1734         (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
1735 #else
1736 #ifdef HAS_SETRESGID
1737       (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
1738 #else
1739         if (PL_gid == PL_egid)                  /* special case $( = $) */
1740             (void)PerlProc_setgid(PL_gid);
1741         else {
1742             PL_gid = (I32)PerlProc_getgid();
1743             croak("setrgid() not implemented");
1744         }
1745 #endif
1746 #endif
1747 #endif
1748         PL_gid = (I32)PerlProc_getgid();
1749         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1750         break;
1751     case ')':
1752 #ifdef HAS_SETGROUPS
1753         {
1754             char *p = SvPV(sv, PL_na);
1755             Groups_t gary[NGROUPS];
1756
1757             SET_NUMERIC_STANDARD();
1758             while (isSPACE(*p))
1759                 ++p;
1760             PL_egid = I_V(atof(p));
1761             for (i = 0; i < NGROUPS; ++i) {
1762                 while (*p && !isSPACE(*p))
1763                     ++p;
1764                 while (isSPACE(*p))
1765                     ++p;
1766                 if (!*p)
1767                     break;
1768                 gary[i] = I_V(atof(p));
1769             }
1770             if (i)
1771                 (void)setgroups(i, gary);
1772         }
1773 #else  /* HAS_SETGROUPS */
1774         PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1775 #endif /* HAS_SETGROUPS */
1776         if (PL_delaymagic) {
1777             PL_delaymagic |= DM_EGID;
1778             break;                              /* don't do magic till later */
1779         }
1780 #ifdef HAS_SETEGID
1781         (void)setegid((Gid_t)PL_egid);
1782 #else
1783 #ifdef HAS_SETREGID
1784         (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
1785 #else
1786 #ifdef HAS_SETRESGID
1787         (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
1788 #else
1789         if (PL_egid == PL_gid)                  /* special case $) = $( */
1790             (void)PerlProc_setgid(PL_egid);
1791         else {
1792             PL_egid = (I32)PerlProc_getegid();
1793             croak("setegid() not implemented");
1794         }
1795 #endif
1796 #endif
1797 #endif
1798         PL_egid = (I32)PerlProc_getegid();
1799         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1800         break;
1801     case ':':
1802         PL_chopset = SvPV_force(sv,PL_na);
1803         break;
1804     case '0':
1805         if (!PL_origalen) {
1806             s = PL_origargv[0];
1807             s += strlen(s);
1808             /* See if all the arguments are contiguous in memory */
1809             for (i = 1; i < PL_origargc; i++) {
1810                 if (PL_origargv[i] == s + 1
1811 #ifdef OS2
1812                     || PL_origargv[i] == s + 2
1813 #endif 
1814                    )
1815                     s += strlen(++s);   /* this one is ok too */
1816                 else
1817                     break;
1818             }
1819             /* can grab env area too? */
1820             if (PL_origenviron && (PL_origenviron[0] == s + 1
1821 #ifdef OS2
1822                                 || (PL_origenviron[0] == s + 9 && (s += 8))
1823 #endif 
1824                )) {
1825                 my_setenv("NoNe  SuCh", Nullch);
1826                                             /* force copy of environment */
1827                 for (i = 0; PL_origenviron[i]; i++)
1828                     if (PL_origenviron[i] == s + 1)
1829                         s += strlen(++s);
1830                     else
1831                         break;
1832             }
1833             PL_origalen = s - PL_origargv[0];
1834         }
1835         s = SvPV_force(sv,len);
1836         i = len;
1837         if (i >= PL_origalen) {
1838             i = PL_origalen;
1839             /* don't allow system to limit $0 seen by script */
1840             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
1841             Copy(s, PL_origargv[0], i, char);
1842             s = PL_origargv[0]+i;
1843             *s = '\0';
1844         }
1845         else {
1846             Copy(s, PL_origargv[0], i, char);
1847             s = PL_origargv[0]+i;
1848             *s++ = '\0';
1849             while (++i < PL_origalen)
1850                 *s++ = ' ';
1851             s = PL_origargv[0]+i;
1852             for (i = 1; i < PL_origargc; i++)
1853                 PL_origargv[i] = Nullch;
1854         }
1855         break;
1856 #ifdef USE_THREADS
1857     case '@':
1858         sv_setsv(thr->errsv, sv);
1859         break;
1860 #endif /* USE_THREADS */
1861     }
1862     return 0;
1863 }
1864
1865 #ifdef USE_THREADS
1866 int
1867 magic_mutexfree(SV *sv, MAGIC *mg)
1868 {
1869     dTHR;
1870     DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
1871                           (unsigned long)thr, (unsigned long)sv);)
1872     if (MgOWNER(mg))
1873         croak("panic: magic_mutexfree");
1874     MUTEX_DESTROY(MgMUTEXP(mg));
1875     COND_DESTROY(MgCONDP(mg));
1876     SvREFCNT_dec(sv);
1877     return 0;
1878 }
1879 #endif /* USE_THREADS */
1880
1881 I32
1882 whichsig(char *sig)
1883 {
1884     register char **sigv;
1885
1886     for (sigv = sig_name+1; *sigv; sigv++)
1887         if (strEQ(sig,*sigv))
1888             return sig_num[sigv - sig_name];
1889 #ifdef SIGCLD
1890     if (strEQ(sig,"CHLD"))
1891         return SIGCLD;
1892 #endif
1893 #ifdef SIGCHLD
1894     if (strEQ(sig,"CLD"))
1895         return SIGCHLD;
1896 #endif
1897     return 0;
1898 }
1899
1900 static SV* sig_sv;
1901
1902 STATIC void
1903 unwind_handler_stack(void *p)
1904 {
1905     dTHR;
1906     U32 flags = *(U32*)p;
1907
1908     if (flags & 1)
1909         PL_savestack_ix -= 5; /* Unprotect save in progress. */
1910     /* cxstack_ix-- Not needed, die already unwound it. */
1911     if (flags & 64)
1912         SvREFCNT_dec(sig_sv);
1913 }
1914
1915 Signal_t
1916 sighandler(int sig)
1917 {
1918     dSP;
1919     GV *gv = Nullgv;
1920     HV *st;
1921     SV *sv, *tSv = PL_Sv;
1922     CV *cv = Nullcv;
1923     OP *myop = PL_op;
1924     U32 flags = 0;
1925     I32 o_save_i = PL_savestack_ix, type;
1926     XPV *tXpv = PL_Xpv;
1927     
1928     if (PL_savestack_ix + 15 <= PL_savestack_max)
1929         flags |= 1;
1930     if (PL_markstack_ptr < PL_markstack_max - 2)
1931         flags |= 4;
1932     if (PL_retstack_ix < PL_retstack_max - 2)
1933         flags |= 8;
1934     if (PL_scopestack_ix < PL_scopestack_max - 3)
1935         flags |= 16;
1936
1937     if (!psig_ptr[sig])
1938         die("Signal SIG%s received, but no signal handler set.\n",
1939             sig_name[sig]);
1940
1941     /* Max number of items pushed there is 3*n or 4. We cannot fix
1942        infinity, so we fix 4 (in fact 5): */
1943     if (flags & 1) {
1944         PL_savestack_ix += 5;           /* Protect save in progress. */
1945         o_save_i = PL_savestack_ix;
1946         SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags);
1947     }
1948     if (flags & 4) 
1949         PL_markstack_ptr++;             /* Protect mark. */
1950     if (flags & 8) {
1951         PL_retstack_ix++;
1952         PL_retstack[PL_retstack_ix] = NULL;
1953     }
1954     if (flags & 16)
1955         PL_scopestack_ix += 1;
1956     /* sv_2cv is too complicated, try a simpler variant first: */
1957     if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) 
1958         || SvTYPE(cv) != SVt_PVCV)
1959         cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1960
1961     if (!cv || !CvROOT(cv)) {
1962         if (PL_dowarn)
1963             warn("SIG%s handler \"%s\" not defined.\n",
1964                 sig_name[sig], (gv ? GvENAME(gv)
1965                                 : ((cv && CvGV(cv))
1966                                    ? GvENAME(CvGV(cv))
1967                                    : "__ANON__")));
1968         goto cleanup;
1969     }
1970
1971     if(psig_name[sig]) {
1972         sv = SvREFCNT_inc(psig_name[sig]);
1973         flags |= 64;
1974         sig_sv = sv;
1975     } else {
1976         sv = sv_newmortal();
1977         sv_setpv(sv,sig_name[sig]);
1978     }
1979
1980     PUSHSTACKi(PERLSI_SIGNAL);
1981     PUSHMARK(SP);
1982     PUSHs(sv);
1983     PUTBACK;
1984
1985     perl_call_sv((SV*)cv, G_DISCARD);
1986
1987     POPSTACK;
1988 cleanup:
1989     if (flags & 1)
1990         PL_savestack_ix -= 8; /* Unprotect save in progress. */
1991     if (flags & 4) 
1992         PL_markstack_ptr--;
1993     if (flags & 8) 
1994         PL_retstack_ix--;
1995     if (flags & 16)
1996         PL_scopestack_ix -= 1;
1997     if (flags & 64)
1998         SvREFCNT_dec(sv);
1999     PL_op = myop;                       /* Apparently not needed... */
2000     
2001     PL_Sv = tSv;                        /* Restore global temporaries. */
2002     PL_Xpv = tXpv;
2003     return;
2004 }
2005
2006