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