integrate maint-5.005 changes into mainline
[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 '\011':                /* ^I */ /* NOT \t in EBCDIC */
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             sv_setiv(sv, (IV)STATUS_CURRENT);
524 #ifdef COMPLEX_STATUS
525             LvTARGOFF(sv) = PL_statusvalue;
526             LvTARGLEN(sv) = PL_statusvalue_vms;
527 #endif
528         }
529         break;
530     case '^':
531         s = IoTOP_NAME(GvIOp(PL_defoutgv));
532         if (s)
533             sv_setpv(sv,s);
534         else {
535             sv_setpv(sv,GvENAME(PL_defoutgv));
536             sv_catpv(sv,"_TOP");
537         }
538         break;
539     case '~':
540         s = IoFMT_NAME(GvIOp(PL_defoutgv));
541         if (!s)
542             s = GvENAME(PL_defoutgv);
543         sv_setpv(sv,s);
544         break;
545 #ifndef lint
546     case '=':
547         sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
548         break;
549     case '-':
550         sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
551         break;
552     case '%':
553         sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
554         break;
555 #endif
556     case ':':
557         break;
558     case '/':
559         break;
560     case '[':
561         WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
562         break;
563     case '|':
564         sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
565         break;
566     case ',':
567         sv_setpvn(sv,PL_ofs,PL_ofslen);
568         break;
569     case '\\':
570         sv_setpvn(sv,PL_ors,PL_orslen);
571         break;
572     case '#':
573         sv_setpv(sv,PL_ofmt);
574         break;
575     case '!':
576 #ifdef VMS
577         sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
578         sv_setpv(sv, errno ? Strerror(errno) : "");
579 #else
580         {
581         int saveerrno = errno;
582         sv_setnv(sv, (double)errno);
583 #ifdef OS2
584         if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
585         else
586 #endif
587         sv_setpv(sv, errno ? Strerror(errno) : "");
588         errno = saveerrno;
589         }
590 #endif
591         SvNOK_on(sv);   /* what a wonderful hack! */
592         break;
593     case '<':
594         sv_setiv(sv, (IV)PL_uid);
595         break;
596     case '>':
597         sv_setiv(sv, (IV)PL_euid);
598         break;
599     case '(':
600         sv_setiv(sv, (IV)PL_gid);
601         sv_setpvf(sv, "%Vd", (IV)PL_gid);
602         goto add_groups;
603     case ')':
604         sv_setiv(sv, (IV)PL_egid);
605         sv_setpvf(sv, "%Vd", (IV)PL_egid);
606       add_groups:
607 #ifdef HAS_GETGROUPS
608         {
609             Groups_t gary[NGROUPS];
610             i = getgroups(NGROUPS,gary);
611             while (--i >= 0)
612                 sv_catpvf(sv, " %Vd", (IV)gary[i]);
613         }
614 #endif
615         SvIOK_on(sv);   /* what a wonderful hack! */
616         break;
617     case '*':
618         break;
619     case '0':
620         break;
621 #ifdef USE_THREADS
622     case '@':
623         sv_setsv(sv, thr->errsv);
624         break;
625 #endif /* USE_THREADS */
626     }
627     return 0;
628 }
629
630 int
631 magic_getuvar(SV *sv, MAGIC *mg)
632 {
633     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
634
635     if (uf && uf->uf_val)
636         (*uf->uf_val)(uf->uf_index, sv);
637     return 0;
638 }
639
640 int
641 magic_setenv(SV *sv, MAGIC *mg)
642 {
643     register char *s;
644     char *ptr;
645     STRLEN len, klen;
646     I32 i;
647
648     s = SvPV(sv,len);
649     ptr = MgPV(mg,klen);
650     my_setenv(ptr, s);
651
652 #ifdef DYNAMIC_ENV_FETCH
653      /* We just undefd an environment var.  Is a replacement */
654      /* waiting in the wings? */
655     if (!len) {
656         SV **valp;
657         if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
658             s = SvPV(*valp, len);
659     }
660 #endif
661
662 #if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
663                             /* And you'll never guess what the dog had */
664                             /*   in its mouth... */
665     if (PL_tainting) {
666         MgTAINTEDDIR_off(mg);
667 #ifdef VMS
668         if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
669             char pathbuf[256], eltbuf[256], *cp, *elt = s;
670             struct stat sbuf;
671             int i = 0, j = 0;
672
673             do {          /* DCL$PATH may be a search list */
674                 while (1) {   /* as may dev portion of any element */
675                     if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
676                         if ( *(cp+1) == '.' || *(cp+1) == '-' ||
677                              cando_by_name(S_IWUSR,0,elt) ) {
678                             MgTAINTEDDIR_on(mg);
679                             return 0;
680                         }
681                     }
682                     if ((cp = strchr(elt, ':')) != Nullch)
683                         *cp = '\0';
684                     if (my_trnlnm(elt, eltbuf, j++))
685                         elt = eltbuf;
686                     else
687                         break;
688                 }
689                 j = 0;
690             } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
691         }
692 #endif /* VMS */
693         if (s && klen == 4 && strEQ(ptr,"PATH")) {
694             char *strend = s + len;
695
696             while (s < strend) {
697                 char tmpbuf[256];
698                 struct stat st;
699                 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
700                              s, strend, ':', &i);
701                 s++;
702                 if (i >= sizeof tmpbuf   /* too long -- assume the worst */
703                       || *tmpbuf != '/'
704                       || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
705                     MgTAINTEDDIR_on(mg);
706                     return 0;
707                 }
708             }
709         }
710     }
711 #endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
712
713     return 0;
714 }
715
716 int
717 magic_clearenv(SV *sv, MAGIC *mg)
718 {
719     my_setenv(MgPV(mg,PL_na),Nullch);
720     return 0;
721 }
722
723 int
724 magic_set_all_env(SV *sv, MAGIC *mg)
725 {
726 #if defined(VMS)
727     die("Can't make list assignment to %%ENV on this system");
728 #else
729     dTHR;
730     if (PL_localizing) {
731         HE* entry;
732         magic_clear_all_env(sv,mg);
733         hv_iterinit((HV*)sv);
734         while (entry = hv_iternext((HV*)sv)) {
735             I32 keylen;
736             my_setenv(hv_iterkey(entry, &keylen),
737                       SvPV(hv_iterval((HV*)sv, entry), PL_na));
738         }
739     }
740 #endif
741     return 0;
742 }
743
744 int
745 magic_clear_all_env(SV *sv, MAGIC *mg)
746 {
747 #if defined(VMS)
748     die("Can't make list assignment to %%ENV on this system");
749 #else
750 #ifdef WIN32
751     char *envv = GetEnvironmentStrings();
752     char *cur = envv;
753     STRLEN len;
754     while (*cur) {
755         char *end = strchr(cur,'=');
756         if (end && end != cur) {
757             *end = '\0';
758             my_setenv(cur,Nullch);
759             *end = '=';
760             cur += strlen(end+1)+1;
761         }
762         else if ((len = strlen(cur)))
763             cur += len+1;
764     }
765     FreeEnvironmentStrings(envv);
766 #else
767     I32 i;
768
769     if (environ == PL_origenviron)
770         New(901, environ, 1, char*);
771     else
772         for (i = 0; environ[i]; i++)
773             Safefree(environ[i]);
774     environ[0] = Nullch;
775
776 #endif
777 #endif
778     return 0;
779 }
780
781 int
782 magic_getsig(SV *sv, MAGIC *mg)
783 {
784     I32 i;
785     /* Are we fetching a signal entry? */
786     i = whichsig(MgPV(mg,PL_na));
787     if (i) {
788         if(psig_ptr[i])
789             sv_setsv(sv,psig_ptr[i]);
790         else {
791             Sighandler_t sigstate = rsignal_state(i);
792
793             /* cache state so we don't fetch it again */
794             if(sigstate == SIG_IGN)
795                 sv_setpv(sv,"IGNORE");
796             else
797                 sv_setsv(sv,&PL_sv_undef);
798             psig_ptr[i] = SvREFCNT_inc(sv);
799             SvTEMP_off(sv);
800         }
801     }
802     return 0;
803 }
804 int
805 magic_clearsig(SV *sv, MAGIC *mg)
806 {
807     I32 i;
808     /* Are we clearing a signal entry? */
809     i = whichsig(MgPV(mg,PL_na));
810     if (i) {
811         if(psig_ptr[i]) {
812             SvREFCNT_dec(psig_ptr[i]);
813             psig_ptr[i]=0;
814         }
815         if(psig_name[i]) {
816             SvREFCNT_dec(psig_name[i]);
817             psig_name[i]=0;
818         }
819     }
820     return 0;
821 }
822
823 int
824 magic_setsig(SV *sv, MAGIC *mg)
825 {
826     dTHR;
827     register char *s;
828     I32 i;
829     SV** svp;
830
831     s = MgPV(mg,PL_na);
832     if (*s == '_') {
833         if (strEQ(s,"__DIE__"))
834             svp = &PL_diehook;
835         else if (strEQ(s,"__WARN__"))
836             svp = &PL_warnhook;
837         else if (strEQ(s,"__PARSE__"))
838             svp = &PL_parsehook;
839         else
840             croak("No such hook: %s", s);
841         i = 0;
842         if (*svp) {
843             SvREFCNT_dec(*svp);
844             *svp = 0;
845         }
846     }
847     else {
848         i = whichsig(s);        /* ...no, a brick */
849         if (!i) {
850             if (PL_dowarn || strEQ(s,"ALARM"))
851                 warn("No such signal: SIG%s", s);
852             return 0;
853         }
854         SvREFCNT_dec(psig_name[i]);
855         SvREFCNT_dec(psig_ptr[i]);
856         psig_ptr[i] = SvREFCNT_inc(sv);
857         SvTEMP_off(sv); /* Make sure it doesn't go away on us */
858         psig_name[i] = newSVpv(s, strlen(s));
859         SvREADONLY_on(psig_name[i]);
860     }
861     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
862         if (i)
863             (void)rsignal(i, PL_sighandlerp);
864         else
865             *svp = SvREFCNT_inc(sv);
866         return 0;
867     }
868     s = SvPV_force(sv,PL_na);
869     if (strEQ(s,"IGNORE")) {
870         if (i)
871             (void)rsignal(i, SIG_IGN);
872         else
873             *svp = 0;
874     }
875     else if (strEQ(s,"DEFAULT") || !*s) {
876         if (i)
877             (void)rsignal(i, SIG_DFL);
878         else
879             *svp = 0;
880     }
881     else {
882         /*
883          * We should warn if HINT_STRICT_REFS, but without
884          * access to a known hint bit in a known OP, we can't
885          * tell whether HINT_STRICT_REFS is in force or not.
886          */
887         if (!strchr(s,':') && !strchr(s,'\''))
888             sv_setpv(sv, form("main::%s", s));
889         if (i)
890             (void)rsignal(i, PL_sighandlerp);
891         else
892             *svp = SvREFCNT_inc(sv);
893     }
894     return 0;
895 }
896
897 int
898 magic_setisa(SV *sv, MAGIC *mg)
899 {
900     PL_sub_generation++;
901     return 0;
902 }
903
904 #ifdef OVERLOAD
905
906 int
907 magic_setamagic(SV *sv, MAGIC *mg)
908 {
909     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
910     PL_amagic_generation++;
911
912     return 0;
913 }
914 #endif /* OVERLOAD */
915
916 int
917 magic_getnkeys(SV *sv, MAGIC *mg)
918 {
919     HV *hv = (HV*)LvTARG(sv);
920     HE *entry;
921     I32 i = 0;
922
923     if (hv) {
924         (void) hv_iterinit(hv);
925         if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
926             i = HvKEYS(hv);
927         else {
928             /*SUPPRESS 560*/
929             while (entry = hv_iternext(hv)) {
930                 i++;
931             }
932         }
933     }
934
935     sv_setiv(sv, (IV)i);
936     return 0;
937 }
938
939 int
940 magic_setnkeys(SV *sv, MAGIC *mg)
941 {
942     if (LvTARG(sv)) {
943         hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
944     }
945     return 0;
946 }          
947
948 /* caller is responsible for stack switching/cleanup */
949 STATIC int
950 magic_methcall(MAGIC *mg, char *meth, I32 flags, int n, SV *val)
951 {
952     dSP;
953
954     PUSHMARK(SP);
955     EXTEND(SP, n);
956     PUSHs(mg->mg_obj);
957     if (n > 1) { 
958         if (mg->mg_ptr) {
959             if (mg->mg_len >= 0)
960                 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
961             else if (mg->mg_len == HEf_SVKEY)
962                 PUSHs((SV*)mg->mg_ptr);
963         }
964         else if (mg->mg_type == 'p') {
965             PUSHs(sv_2mortal(newSViv(mg->mg_len)));
966         }
967     }
968     if (n > 2) {
969         PUSHs(val);
970     }
971     PUTBACK;
972
973     return perl_call_method(meth, flags);
974 }
975
976 STATIC int
977 magic_methpack(SV *sv, MAGIC *mg, char *meth)
978 {
979     dSP;
980
981     ENTER;
982     SAVETMPS;
983     PUSHSTACKi(PERLSI_MAGIC);
984
985     if (magic_methcall(mg, meth, G_SCALAR, 2, NULL)) {
986         sv_setsv(sv, *PL_stack_sp--);
987     }
988
989     POPSTACK;
990     FREETMPS;
991     LEAVE;
992     return 0;
993 }
994
995 int
996 magic_getpack(SV *sv, MAGIC *mg)
997 {
998     magic_methpack(sv,mg,"FETCH");
999     if (mg->mg_ptr)
1000         mg->mg_flags |= MGf_GSKIP;
1001     return 0;
1002 }
1003
1004 int
1005 magic_setpack(SV *sv, MAGIC *mg)
1006 {
1007     dSP;
1008     ENTER;
1009     PUSHSTACKi(PERLSI_MAGIC);
1010     magic_methcall(mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
1011     POPSTACK;
1012     LEAVE;
1013     return 0;
1014 }
1015
1016 int
1017 magic_clearpack(SV *sv, MAGIC *mg)
1018 {
1019     return magic_methpack(sv,mg,"DELETE");
1020 }
1021
1022
1023 U32
1024 magic_sizepack(SV *sv, MAGIC *mg)
1025 {         
1026     dSP;
1027     U32 retval = 0;
1028
1029     ENTER;
1030     SAVETMPS;
1031     PUSHSTACKi(PERLSI_MAGIC);
1032     if (magic_methcall(mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
1033         sv = *PL_stack_sp--;
1034         retval = (U32) SvIV(sv)-1;
1035     }
1036     POPSTACK;
1037     FREETMPS;
1038     LEAVE;
1039     return retval;
1040 }
1041
1042 int magic_wipepack(SV *sv, MAGIC *mg)
1043 {
1044     dSP;
1045
1046     ENTER;
1047     PUSHSTACKi(PERLSI_MAGIC);
1048     PUSHMARK(SP);
1049     XPUSHs(mg->mg_obj);
1050     PUTBACK;
1051     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
1052     POPSTACK;
1053     LEAVE;
1054     return 0;
1055 }
1056
1057 int
1058 magic_nextpack(SV *sv, MAGIC *mg, SV *key)
1059 {
1060     dSP;
1061     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
1062
1063     ENTER;
1064     SAVETMPS;
1065     PUSHSTACKi(PERLSI_MAGIC);
1066     PUSHMARK(SP);
1067     EXTEND(SP, 2);
1068     PUSHs(mg->mg_obj);
1069     if (SvOK(key))
1070         PUSHs(key);
1071     PUTBACK;
1072
1073     if (perl_call_method(meth, G_SCALAR))
1074         sv_setsv(key, *PL_stack_sp--);
1075
1076     POPSTACK;
1077     FREETMPS;
1078     LEAVE;
1079     return 0;
1080 }
1081
1082 int
1083 magic_existspack(SV *sv, MAGIC *mg)
1084 {
1085     return magic_methpack(sv,mg,"EXISTS");
1086
1087
1088 int
1089 magic_setdbline(SV *sv, MAGIC *mg)
1090 {
1091     dTHR;
1092     OP *o;
1093     I32 i;
1094     GV* gv;
1095     SV** svp;
1096
1097     gv = PL_DBline;
1098     i = SvTRUE(sv);
1099     svp = av_fetch(GvAV(gv),
1100                      atoi(MgPV(mg,PL_na)), FALSE);
1101     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
1102         o->op_private = i;
1103     else
1104         warn("Can't break at that line\n");
1105     return 0;
1106 }
1107
1108 int
1109 magic_getarylen(SV *sv, MAGIC *mg)
1110 {
1111     dTHR;
1112     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
1113     return 0;
1114 }
1115
1116 int
1117 magic_setarylen(SV *sv, MAGIC *mg)
1118 {
1119     dTHR;
1120     av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
1121     return 0;
1122 }
1123
1124 int
1125 magic_getpos(SV *sv, MAGIC *mg)
1126 {
1127     SV* lsv = LvTARG(sv);
1128     
1129     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1130         mg = mg_find(lsv, 'g');
1131         if (mg && mg->mg_len >= 0) {
1132             dTHR;
1133             I32 i = mg->mg_len;
1134             if (IN_UTF8)
1135                 sv_pos_b2u(lsv, &i);
1136             sv_setiv(sv, i + PL_curcop->cop_arybase);
1137             return 0;
1138         }
1139     }
1140     (void)SvOK_off(sv);
1141     return 0;
1142 }
1143
1144 int
1145 magic_setpos(SV *sv, MAGIC *mg)
1146 {
1147     SV* lsv = LvTARG(sv);
1148     SSize_t pos;
1149     STRLEN len;
1150     STRLEN ulen;
1151     dTHR;
1152
1153     mg = 0;
1154     
1155     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1156         mg = mg_find(lsv, 'g');
1157     if (!mg) {
1158         if (!SvOK(sv))
1159             return 0;
1160         sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1161         mg = mg_find(lsv, 'g');
1162     }
1163     else if (!SvOK(sv)) {
1164         mg->mg_len = -1;
1165         return 0;
1166     }
1167     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1168
1169     pos = SvIV(sv) - PL_curcop->cop_arybase;
1170
1171     if (IN_UTF8) {
1172         ulen = sv_len_utf8(lsv);
1173         if (ulen)
1174             len = ulen;
1175         else
1176             ulen = 0;
1177     }
1178
1179     if (pos < 0) {
1180         pos += len;
1181         if (pos < 0)
1182             pos = 0;
1183     }
1184     else if (pos > len)
1185         pos = len;
1186
1187     if (ulen) {
1188         I32 p = pos;
1189         sv_pos_u2b(lsv, &p, 0);
1190         pos = p;
1191     }
1192         
1193     mg->mg_len = pos;
1194     mg->mg_flags &= ~MGf_MINMATCH;
1195
1196     return 0;
1197 }
1198
1199 int
1200 magic_getglob(SV *sv, MAGIC *mg)
1201 {
1202     if (SvFAKE(sv)) {                   /* FAKE globs can get coerced */
1203         SvFAKE_off(sv);
1204         gv_efullname3(sv,((GV*)sv), "*");
1205         SvFAKE_on(sv);
1206     }
1207     else
1208         gv_efullname3(sv,((GV*)sv), "*");       /* a gv value, be nice */
1209     return 0;
1210 }
1211
1212 int
1213 magic_setglob(SV *sv, MAGIC *mg)
1214 {
1215     register char *s;
1216     GV* gv;
1217
1218     if (!SvOK(sv))
1219         return 0;
1220     s = SvPV(sv, PL_na);
1221     if (*s == '*' && s[1])
1222         s++;
1223     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
1224     if (sv == (SV*)gv)
1225         return 0;
1226     if (GvGP(sv))
1227         gp_free((GV*)sv);
1228     GvGP(sv) = gp_ref(GvGP(gv));
1229     return 0;
1230 }
1231
1232 int
1233 magic_getsubstr(SV *sv, MAGIC *mg)
1234 {
1235     STRLEN len;
1236     SV *lsv = LvTARG(sv);
1237     char *tmps = SvPV(lsv,len);
1238     I32 offs = LvTARGOFF(sv);
1239     I32 rem = LvTARGLEN(sv);
1240
1241     if (offs > len)
1242         offs = len;
1243     if (rem + offs > len)
1244         rem = len - offs;
1245     sv_setpvn(sv, tmps + offs, (STRLEN)rem);
1246     return 0;
1247 }
1248
1249 int
1250 magic_setsubstr(SV *sv, MAGIC *mg)
1251 {
1252     STRLEN len;
1253     char *tmps = SvPV(sv,len);
1254     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
1255     return 0;
1256 }
1257
1258 int
1259 magic_gettaint(SV *sv, MAGIC *mg)
1260 {
1261     dTHR;
1262     TAINT_IF((mg->mg_len & 1) ||
1263              (mg->mg_len & 2) && mg->mg_obj == sv);     /* kludge */
1264     return 0;
1265 }
1266
1267 int
1268 magic_settaint(SV *sv, MAGIC *mg)
1269 {
1270     dTHR;
1271     if (PL_localizing) {
1272         if (PL_localizing == 1)
1273             mg->mg_len <<= 1;
1274         else
1275             mg->mg_len >>= 1;
1276     }
1277     else if (PL_tainted)
1278         mg->mg_len |= 1;
1279     else
1280         mg->mg_len &= ~1;
1281     return 0;
1282 }
1283
1284 int
1285 magic_getvec(SV *sv, MAGIC *mg)
1286 {
1287     SV *lsv = LvTARG(sv);
1288     unsigned char *s;
1289     unsigned long retnum;
1290     STRLEN lsvlen;
1291     I32 len;
1292     I32 offset;
1293     I32 size;
1294
1295     if (!lsv) {
1296         SvOK_off(sv);
1297         return 0;
1298     }
1299     s = (unsigned char *) SvPV(lsv, lsvlen);
1300     offset = LvTARGOFF(sv);
1301     size = LvTARGLEN(sv);
1302     len = (offset + size + 7) / 8;
1303
1304     /* Copied from pp_vec() */
1305
1306     if (len > lsvlen) {
1307         if (size <= 8)
1308             retnum = 0;
1309         else {
1310             offset >>= 3;
1311             if (size == 16) {
1312                 if (offset >= lsvlen)
1313                     retnum = 0;
1314                 else
1315                     retnum = (unsigned long) s[offset] << 8;
1316             }
1317             else if (size == 32) {
1318                 if (offset >= lsvlen)
1319                     retnum = 0;
1320                 else if (offset + 1 >= lsvlen)
1321                     retnum = (unsigned long) s[offset] << 24;
1322                 else if (offset + 2 >= lsvlen)
1323                     retnum = ((unsigned long) s[offset] << 24) +
1324                         ((unsigned long) s[offset + 1] << 16);
1325                 else
1326                     retnum = ((unsigned long) s[offset] << 24) +
1327                         ((unsigned long) s[offset + 1] << 16) +
1328                         (s[offset + 2] << 8);
1329             }
1330         }
1331     }
1332     else if (size < 8)
1333         retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
1334     else {
1335         offset >>= 3;
1336         if (size == 8)
1337             retnum = s[offset];
1338         else if (size == 16)
1339             retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
1340         else if (size == 32)
1341             retnum = ((unsigned long) s[offset] << 24) +
1342                 ((unsigned long) s[offset + 1] << 16) +
1343                 (s[offset + 2] << 8) + s[offset+3];
1344     }
1345
1346     sv_setuv(sv, (UV)retnum);
1347     return 0;
1348 }
1349
1350 int
1351 magic_setvec(SV *sv, MAGIC *mg)
1352 {
1353     do_vecset(sv);      /* XXX slurp this routine */
1354     return 0;
1355 }
1356
1357 int
1358 magic_getdefelem(SV *sv, MAGIC *mg)
1359 {
1360     SV *targ = Nullsv;
1361     if (LvTARGLEN(sv)) {
1362         if (mg->mg_obj) {
1363             SV *ahv = LvTARG(sv);
1364             if (SvTYPE(ahv) == SVt_PVHV) {
1365                 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1366                 if (he)
1367                     targ = HeVAL(he);
1368             }
1369             else {
1370                 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1371                 if (svp)
1372                     targ = *svp;
1373             }
1374         }
1375         else {
1376             AV* av = (AV*)LvTARG(sv);
1377             if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1378                 targ = AvARRAY(av)[LvTARGOFF(sv)];
1379         }
1380         if (targ && targ != &PL_sv_undef) {
1381             dTHR;               /* just for SvREFCNT_dec */
1382             /* somebody else defined it for us */
1383             SvREFCNT_dec(LvTARG(sv));
1384             LvTARG(sv) = SvREFCNT_inc(targ);
1385             LvTARGLEN(sv) = 0;
1386             SvREFCNT_dec(mg->mg_obj);
1387             mg->mg_obj = Nullsv;
1388             mg->mg_flags &= ~MGf_REFCOUNTED;
1389         }
1390     }
1391     else
1392         targ = LvTARG(sv);
1393     sv_setsv(sv, targ ? targ : &PL_sv_undef);
1394     return 0;
1395 }
1396
1397 int
1398 magic_setdefelem(SV *sv, MAGIC *mg)
1399 {
1400     if (LvTARGLEN(sv))
1401         vivify_defelem(sv);
1402     if (LvTARG(sv)) {
1403         sv_setsv(LvTARG(sv), sv);
1404         SvSETMAGIC(LvTARG(sv));
1405     }
1406     return 0;
1407 }
1408
1409 void
1410 vivify_defelem(SV *sv)
1411 {
1412     dTHR;                       /* just for SvREFCNT_inc and SvREFCNT_dec*/
1413     MAGIC *mg;
1414     SV *value = Nullsv;
1415
1416     if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
1417         return;
1418     if (mg->mg_obj) {
1419         SV *ahv = LvTARG(sv);
1420         if (SvTYPE(ahv) == SVt_PVHV) {
1421             HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
1422             if (he)
1423                 value = HeVAL(he);
1424         }
1425         else {
1426             SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, TRUE, 0);
1427             if (svp)
1428                 value = *svp;
1429         }
1430         if (!value || value == &PL_sv_undef)
1431             croak(no_helem, SvPV(mg->mg_obj, PL_na));
1432     }
1433     else {
1434         AV* av = (AV*)LvTARG(sv);
1435         if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
1436             LvTARG(sv) = Nullsv;        /* array can't be extended */
1437         else {
1438             SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1439             if (!svp || (value = *svp) == &PL_sv_undef)
1440                 croak(no_aelem, (I32)LvTARGOFF(sv));
1441         }
1442     }
1443     (void)SvREFCNT_inc(value);
1444     SvREFCNT_dec(LvTARG(sv));
1445     LvTARG(sv) = value;
1446     LvTARGLEN(sv) = 0;
1447     SvREFCNT_dec(mg->mg_obj);
1448     mg->mg_obj = Nullsv;
1449     mg->mg_flags &= ~MGf_REFCOUNTED;
1450 }
1451
1452 int
1453 magic_setmglob(SV *sv, MAGIC *mg)
1454 {
1455     mg->mg_len = -1;
1456     SvSCREAM_off(sv);
1457     return 0;
1458 }
1459
1460 int
1461 magic_setbm(SV *sv, MAGIC *mg)
1462 {
1463     sv_unmagic(sv, 'B');
1464     SvVALID_off(sv);
1465     return 0;
1466 }
1467
1468 int
1469 magic_setfm(SV *sv, MAGIC *mg)
1470 {
1471     sv_unmagic(sv, 'f');
1472     SvCOMPILED_off(sv);
1473     return 0;
1474 }
1475
1476 int
1477 magic_setuvar(SV *sv, MAGIC *mg)
1478 {
1479     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1480
1481     if (uf && uf->uf_set)
1482         (*uf->uf_set)(uf->uf_index, sv);
1483     return 0;
1484 }
1485
1486 int
1487 magic_freeregexp(SV *sv, MAGIC *mg)
1488 {
1489     regexp *re = (regexp *)mg->mg_obj;
1490     ReREFCNT_dec(re);
1491     return 0;
1492 }
1493
1494 #ifdef USE_LOCALE_COLLATE
1495 int
1496 magic_setcollxfrm(SV *sv, MAGIC *mg)
1497 {
1498     /*
1499      * René Descartes said "I think not."
1500      * and vanished with a faint plop.
1501      */
1502     if (mg->mg_ptr) {
1503         Safefree(mg->mg_ptr);
1504         mg->mg_ptr = NULL;
1505         mg->mg_len = -1;
1506     }
1507     return 0;
1508 }
1509 #endif /* USE_LOCALE_COLLATE */
1510
1511 int
1512 magic_set(SV *sv, MAGIC *mg)
1513 {
1514     dTHR;
1515     register char *s;
1516     I32 i;
1517     STRLEN len;
1518     switch (*mg->mg_ptr) {
1519     case '\001':        /* ^A */
1520         sv_setsv(PL_bodytarget, sv);
1521         break;
1522     case '\004':        /* ^D */
1523         PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
1524         DEBUG_x(dump_all());
1525         break;
1526     case '\005':  /* ^E */
1527 #ifdef VMS
1528         set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1529 #else
1530 #ifdef WIN32
1531         SetLastError( SvIV(sv) );
1532 #else
1533         /* will anyone ever use this? */
1534         SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
1535 #endif
1536 #endif
1537         break;
1538     case '\006':        /* ^F */
1539         PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1540         break;
1541     case '\010':        /* ^H */
1542         PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1543         break;
1544     case '\011':        /* ^I */ /* NOT \t in EBCDIC */
1545         if (PL_inplace)
1546             Safefree(PL_inplace);
1547         if (SvOK(sv))
1548             PL_inplace = savepv(SvPV(sv,PL_na));
1549         else
1550             PL_inplace = Nullch;
1551         break;
1552     case '\017':        /* ^O */
1553         if (PL_osname)
1554             Safefree(PL_osname);
1555         if (SvOK(sv))
1556             PL_osname = savepv(SvPV(sv,PL_na));
1557         else
1558             PL_osname = Nullch;
1559         break;
1560     case '\020':        /* ^P */
1561         PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1562         break;
1563     case '\024':        /* ^T */
1564 #ifdef BIG_TIME
1565         PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1566 #else
1567         PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1568 #endif
1569         break;
1570     case '\027':        /* ^W */
1571         PL_dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1572         break;
1573     case '.':
1574         if (PL_localizing) {
1575             if (PL_localizing == 1)
1576                 save_sptr((SV**)&PL_last_in_gv);
1577         }
1578         else if (SvOK(sv) && GvIO(PL_last_in_gv))
1579             IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv);
1580         break;
1581     case '^':
1582         Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
1583         IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
1584         IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1585         break;
1586     case '~':
1587         Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
1588         IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,PL_na));
1589         IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
1590         break;
1591     case '=':
1592         IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1593         break;
1594     case '-':
1595         IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1596         if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
1597             IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
1598         break;
1599     case '%':
1600         IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1601         break;
1602     case '|':
1603         {
1604             IO *io = GvIOp(PL_defoutgv);
1605             if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1606                 IoFLAGS(io) &= ~IOf_FLUSH;
1607             else {
1608                 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1609                     PerlIO *ofp = IoOFP(io);
1610                     if (ofp)
1611                         (void)PerlIO_flush(ofp);
1612                     IoFLAGS(io) |= IOf_FLUSH;
1613                 }
1614             }
1615         }
1616         break;
1617     case '*':
1618         i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1619         PL_multiline = (i != 0);
1620         break;
1621     case '/':
1622         SvREFCNT_dec(PL_nrs);
1623         PL_nrs = newSVsv(sv);
1624         SvREFCNT_dec(PL_rs);
1625         PL_rs = SvREFCNT_inc(PL_nrs);
1626         break;
1627     case '\\':
1628         if (PL_ors)
1629             Safefree(PL_ors);
1630         if (SvOK(sv) || SvGMAGICAL(sv))
1631             PL_ors = savepv(SvPV(sv,PL_orslen));
1632         else {
1633             PL_ors = Nullch;
1634             PL_orslen = 0;
1635         }
1636         break;
1637     case ',':
1638         if (PL_ofs)
1639             Safefree(PL_ofs);
1640         PL_ofs = savepv(SvPV(sv, PL_ofslen));
1641         break;
1642     case '#':
1643         if (PL_ofmt)
1644             Safefree(PL_ofmt);
1645         PL_ofmt = savepv(SvPV(sv,PL_na));
1646         break;
1647     case '[':
1648         PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1649         break;
1650     case '?':
1651 #ifdef COMPLEX_STATUS
1652         if (PL_localizing == 2) {
1653             PL_statusvalue = LvTARGOFF(sv);
1654             PL_statusvalue_vms = LvTARGLEN(sv);
1655         }
1656         else
1657 #endif
1658 #ifdef VMSISH_STATUS
1659         if (VMSISH_STATUS)
1660             STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1661         else
1662 #endif
1663             STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1664         break;
1665     case '!':
1666         SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
1667                  (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
1668         break;
1669     case '<':
1670         PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1671         if (PL_delaymagic) {
1672             PL_delaymagic |= DM_RUID;
1673             break;                              /* don't do magic till later */
1674         }
1675 #ifdef HAS_SETRUID
1676         (void)setruid((Uid_t)PL_uid);
1677 #else
1678 #ifdef HAS_SETREUID
1679         (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
1680 #else
1681 #ifdef HAS_SETRESUID
1682       (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
1683 #else
1684         if (PL_uid == PL_euid)          /* special case $< = $> */
1685             (void)PerlProc_setuid(PL_uid);
1686         else {
1687             PL_uid = (I32)PerlProc_getuid();
1688             croak("setruid() not implemented");
1689         }
1690 #endif
1691 #endif
1692 #endif
1693         PL_uid = (I32)PerlProc_getuid();
1694         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1695         break;
1696     case '>':
1697         PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1698         if (PL_delaymagic) {
1699             PL_delaymagic |= DM_EUID;
1700             break;                              /* don't do magic till later */
1701         }
1702 #ifdef HAS_SETEUID
1703         (void)seteuid((Uid_t)PL_euid);
1704 #else
1705 #ifdef HAS_SETREUID
1706         (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
1707 #else
1708 #ifdef HAS_SETRESUID
1709         (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
1710 #else
1711         if (PL_euid == PL_uid)          /* special case $> = $< */
1712             PerlProc_setuid(PL_euid);
1713         else {
1714             PL_euid = (I32)PerlProc_geteuid();
1715             croak("seteuid() not implemented");
1716         }
1717 #endif
1718 #endif
1719 #endif
1720         PL_euid = (I32)PerlProc_geteuid();
1721         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1722         break;
1723     case '(':
1724         PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1725         if (PL_delaymagic) {
1726             PL_delaymagic |= DM_RGID;
1727             break;                              /* don't do magic till later */
1728         }
1729 #ifdef HAS_SETRGID
1730         (void)setrgid((Gid_t)PL_gid);
1731 #else
1732 #ifdef HAS_SETREGID
1733         (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
1734 #else
1735 #ifdef HAS_SETRESGID
1736       (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
1737 #else
1738         if (PL_gid == PL_egid)                  /* special case $( = $) */
1739             (void)PerlProc_setgid(PL_gid);
1740         else {
1741             PL_gid = (I32)PerlProc_getgid();
1742             croak("setrgid() not implemented");
1743         }
1744 #endif
1745 #endif
1746 #endif
1747         PL_gid = (I32)PerlProc_getgid();
1748         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1749         break;
1750     case ')':
1751 #ifdef HAS_SETGROUPS
1752         {
1753             char *p = SvPV(sv, PL_na);
1754             Groups_t gary[NGROUPS];
1755
1756             SET_NUMERIC_STANDARD();
1757             while (isSPACE(*p))
1758                 ++p;
1759             PL_egid = I_V(atof(p));
1760             for (i = 0; i < NGROUPS; ++i) {
1761                 while (*p && !isSPACE(*p))
1762                     ++p;
1763                 while (isSPACE(*p))
1764                     ++p;
1765                 if (!*p)
1766                     break;
1767                 gary[i] = I_V(atof(p));
1768             }
1769             if (i)
1770                 (void)setgroups(i, gary);
1771         }
1772 #else  /* HAS_SETGROUPS */
1773         PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1774 #endif /* HAS_SETGROUPS */
1775         if (PL_delaymagic) {
1776             PL_delaymagic |= DM_EGID;
1777             break;                              /* don't do magic till later */
1778         }
1779 #ifdef HAS_SETEGID
1780         (void)setegid((Gid_t)PL_egid);
1781 #else
1782 #ifdef HAS_SETREGID
1783         (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
1784 #else
1785 #ifdef HAS_SETRESGID
1786         (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
1787 #else
1788         if (PL_egid == PL_gid)                  /* special case $) = $( */
1789             (void)PerlProc_setgid(PL_egid);
1790         else {
1791             PL_egid = (I32)PerlProc_getegid();
1792             croak("setegid() not implemented");
1793         }
1794 #endif
1795 #endif
1796 #endif
1797         PL_egid = (I32)PerlProc_getegid();
1798         PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
1799         break;
1800     case ':':
1801         PL_chopset = SvPV_force(sv,PL_na);
1802         break;
1803     case '0':
1804         if (!PL_origalen) {
1805             s = PL_origargv[0];
1806             s += strlen(s);
1807             /* See if all the arguments are contiguous in memory */
1808             for (i = 1; i < PL_origargc; i++) {
1809                 if (PL_origargv[i] == s + 1
1810 #ifdef OS2
1811                     || PL_origargv[i] == s + 2
1812 #endif 
1813                    )
1814                     s += strlen(++s);   /* this one is ok too */
1815                 else
1816                     break;
1817             }
1818             /* can grab env area too? */
1819             if (PL_origenviron && (PL_origenviron[0] == s + 1
1820 #ifdef OS2
1821                                 || (PL_origenviron[0] == s + 9 && (s += 8))
1822 #endif 
1823                )) {
1824                 my_setenv("NoNe  SuCh", Nullch);
1825                                             /* force copy of environment */
1826                 for (i = 0; PL_origenviron[i]; i++)
1827                     if (PL_origenviron[i] == s + 1)
1828                         s += strlen(++s);
1829                     else
1830                         break;
1831             }
1832             PL_origalen = s - PL_origargv[0];
1833         }
1834         s = SvPV_force(sv,len);
1835         i = len;
1836         if (i >= PL_origalen) {
1837             i = PL_origalen;
1838             /* don't allow system to limit $0 seen by script */
1839             /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
1840             Copy(s, PL_origargv[0], i, char);
1841             s = PL_origargv[0]+i;
1842             *s = '\0';
1843         }
1844         else {
1845             Copy(s, PL_origargv[0], i, char);
1846             s = PL_origargv[0]+i;
1847             *s++ = '\0';
1848             while (++i < PL_origalen)
1849                 *s++ = ' ';
1850             s = PL_origargv[0]+i;
1851             for (i = 1; i < PL_origargc; i++)
1852                 PL_origargv[i] = Nullch;
1853         }
1854         break;
1855 #ifdef USE_THREADS
1856     case '@':
1857         sv_setsv(thr->errsv, sv);
1858         break;
1859 #endif /* USE_THREADS */
1860     }
1861     return 0;
1862 }
1863
1864 #ifdef USE_THREADS
1865 int
1866 magic_mutexfree(SV *sv, MAGIC *mg)
1867 {
1868     dTHR;
1869     DEBUG_S(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
1870                           (unsigned long)thr, (unsigned long)sv);)
1871     if (MgOWNER(mg))
1872         croak("panic: magic_mutexfree");
1873     MUTEX_DESTROY(MgMUTEXP(mg));
1874     COND_DESTROY(MgCONDP(mg));
1875     SvREFCNT_dec(sv);
1876     return 0;
1877 }
1878 #endif /* USE_THREADS */
1879
1880 I32
1881 whichsig(char *sig)
1882 {
1883     register char **sigv;
1884
1885     for (sigv = sig_name+1; *sigv; sigv++)
1886         if (strEQ(sig,*sigv))
1887             return sig_num[sigv - sig_name];
1888 #ifdef SIGCLD
1889     if (strEQ(sig,"CHLD"))
1890         return SIGCLD;
1891 #endif
1892 #ifdef SIGCHLD
1893     if (strEQ(sig,"CLD"))
1894         return SIGCHLD;
1895 #endif
1896     return 0;
1897 }
1898
1899 static SV* sig_sv;
1900
1901 STATIC void
1902 unwind_handler_stack(void *p)
1903 {
1904     dTHR;
1905     U32 flags = *(U32*)p;
1906
1907     if (flags & 1)
1908         PL_savestack_ix -= 5; /* Unprotect save in progress. */
1909     /* cxstack_ix-- Not needed, die already unwound it. */
1910     if (flags & 64)
1911         SvREFCNT_dec(sig_sv);
1912 }
1913
1914 Signal_t
1915 sighandler(int sig)
1916 {
1917     dSP;
1918     GV *gv = Nullgv;
1919     HV *st;
1920     SV *sv, *tSv = PL_Sv;
1921     CV *cv = Nullcv;
1922     OP *myop = PL_op;
1923     U32 flags = 0;
1924     I32 o_save_i = PL_savestack_ix, type;
1925     XPV *tXpv = PL_Xpv;
1926     
1927     if (PL_savestack_ix + 15 <= PL_savestack_max)
1928         flags |= 1;
1929     if (PL_markstack_ptr < PL_markstack_max - 2)
1930         flags |= 4;
1931     if (PL_retstack_ix < PL_retstack_max - 2)
1932         flags |= 8;
1933     if (PL_scopestack_ix < PL_scopestack_max - 3)
1934         flags |= 16;
1935
1936     if (!psig_ptr[sig])
1937         die("Signal SIG%s received, but no signal handler set.\n",
1938             sig_name[sig]);
1939
1940     /* Max number of items pushed there is 3*n or 4. We cannot fix
1941        infinity, so we fix 4 (in fact 5): */
1942     if (flags & 1) {
1943         PL_savestack_ix += 5;           /* Protect save in progress. */
1944         o_save_i = PL_savestack_ix;
1945         SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags);
1946     }
1947     if (flags & 4) 
1948         PL_markstack_ptr++;             /* Protect mark. */
1949     if (flags & 8) {
1950         PL_retstack_ix++;
1951         PL_retstack[PL_retstack_ix] = NULL;
1952     }
1953     if (flags & 16)
1954         PL_scopestack_ix += 1;
1955     /* sv_2cv is too complicated, try a simpler variant first: */
1956     if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) 
1957         || SvTYPE(cv) != SVt_PVCV)
1958         cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1959
1960     if (!cv || !CvROOT(cv)) {
1961         if (PL_dowarn)
1962             warn("SIG%s handler \"%s\" not defined.\n",
1963                 sig_name[sig], (gv ? GvENAME(gv)
1964                                 : ((cv && CvGV(cv))
1965                                    ? GvENAME(CvGV(cv))
1966                                    : "__ANON__")));
1967         goto cleanup;
1968     }
1969
1970     if(psig_name[sig]) {
1971         sv = SvREFCNT_inc(psig_name[sig]);
1972         flags |= 64;
1973         sig_sv = sv;
1974     } else {
1975         sv = sv_newmortal();
1976         sv_setpv(sv,sig_name[sig]);
1977     }
1978
1979     PUSHSTACKi(PERLSI_SIGNAL);
1980     PUSHMARK(SP);
1981     PUSHs(sv);
1982     PUTBACK;
1983
1984     perl_call_sv((SV*)cv, G_DISCARD);
1985
1986     POPSTACK;
1987 cleanup:
1988     if (flags & 1)
1989         PL_savestack_ix -= 8; /* Unprotect save in progress. */
1990     if (flags & 4) 
1991         PL_markstack_ptr--;
1992     if (flags & 8) 
1993         PL_retstack_ix--;
1994     if (flags & 16)
1995         PL_scopestack_ix -= 1;
1996     if (flags & 64)
1997         SvREFCNT_dec(sv);
1998     PL_op = myop;                       /* Apparently not needed... */
1999     
2000     PL_Sv = tSv;                        /* Restore global temporaries. */
2001     PL_Xpv = tXpv;
2002     return;
2003 }
2004
2005