This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.0 alpha 6
[perl5.git] / mg.c
CommitLineData
79072805
LW
1/* $RCSfile: hash.c,v $$Revision: 4.1 $$Date: 92/08/07 18:21:48 $
2 *
3 * Copyright (c) 1993, 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 * $Log: hash.c,v $
9 */
10
11#include "EXTERN.h"
12#include "perl.h"
13
8990e307
LW
14void
15mg_magical(sv)
16SV* sv;
17{
18 MAGIC* mg;
19 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
20 MGVTBL* vtbl = mg->mg_virtual;
21 if (vtbl) {
22 if (vtbl->svt_get)
23 SvGMAGICAL_on(sv);
24 if (vtbl->svt_set)
25 SvSMAGICAL_on(sv);
26 if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
27 SvRMAGICAL_on(sv);
28 }
29 }
30}
31
79072805
LW
32int
33mg_get(sv)
34SV* sv;
35{
36 MAGIC* mg;
8990e307 37 U32 savemagic = SvMAGICAL(sv);
463ee0b2
LW
38
39 SvMAGICAL_off(sv);
8990e307 40 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
463ee0b2 41
79072805
LW
42 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
43 MGVTBL* vtbl = mg->mg_virtual;
44 if (vtbl && vtbl->svt_get)
45 (*vtbl->svt_get)(sv, mg);
46 }
463ee0b2 47
8990e307
LW
48 SvFLAGS(sv) |= savemagic;
49 assert(SvGMAGICAL(sv));
463ee0b2
LW
50 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
51
79072805
LW
52 return 0;
53}
54
55int
56mg_set(sv)
57SV* sv;
58{
59 MAGIC* mg;
463ee0b2 60 MAGIC* nextmg;
8990e307 61 U32 savemagic = SvMAGICAL(sv);
463ee0b2
LW
62
63 SvMAGICAL_off(sv);
64
65 for (mg = SvMAGIC(sv); mg; mg = nextmg) {
79072805 66 MGVTBL* vtbl = mg->mg_virtual;
463ee0b2 67 nextmg = mg->mg_moremagic; /* it may delete itself */
79072805
LW
68 if (vtbl && vtbl->svt_set)
69 (*vtbl->svt_set)(sv, mg);
70 }
463ee0b2
LW
71
72 if (SvMAGIC(sv)) {
8990e307
LW
73 SvFLAGS(sv) |= savemagic;
74 if (SvGMAGICAL(sv))
75 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
463ee0b2
LW
76 }
77
79072805
LW
78 return 0;
79}
80
81U32
82mg_len(sv)
83SV* sv;
84{
85 MAGIC* mg;
463ee0b2
LW
86 char *s;
87 STRLEN len;
8990e307 88 U32 savemagic = SvMAGICAL(sv);
463ee0b2
LW
89
90 SvMAGICAL_off(sv);
8990e307 91 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
463ee0b2 92
79072805
LW
93 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
94 MGVTBL* vtbl = mg->mg_virtual;
95 if (vtbl && vtbl->svt_len)
96 return (*vtbl->svt_len)(sv, mg);
97 }
93a17b20 98 mg_get(sv);
463ee0b2
LW
99 s = SvPV(sv, len);
100
8990e307
LW
101 SvFLAGS(sv) |= savemagic;
102 if (SvGMAGICAL(sv))
103 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
463ee0b2
LW
104
105 return len;
79072805
LW
106}
107
108int
109mg_clear(sv)
110SV* sv;
111{
112 MAGIC* mg;
8990e307 113 U32 savemagic = SvMAGICAL(sv);
463ee0b2
LW
114
115 SvMAGICAL_off(sv);
8990e307 116 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
463ee0b2 117
79072805
LW
118 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
119 MGVTBL* vtbl = mg->mg_virtual;
120 if (vtbl && vtbl->svt_clear)
121 (*vtbl->svt_clear)(sv, mg);
122 }
463ee0b2 123
8990e307
LW
124 SvFLAGS(sv) |= savemagic;
125 if (SvGMAGICAL(sv))
126 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
463ee0b2 127
79072805
LW
128 return 0;
129}
130
93a17b20 131MAGIC*
8990e307 132#ifndef STANDARD_C
93a17b20
LW
133mg_find(sv, type)
134SV* sv;
135char type;
8990e307
LW
136#else
137mg_find(SV *sv, char type)
138#endif /* STANDARD_C */
93a17b20
LW
139{
140 MAGIC* mg;
93a17b20
LW
141 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
142 if (mg->mg_type == type)
143 return mg;
144 }
145 return 0;
146}
147
79072805 148int
463ee0b2 149mg_copy(sv, nsv, key, klen)
79072805 150SV* sv;
463ee0b2
LW
151SV* nsv;
152char *key;
153STRLEN klen;
79072805 154{
463ee0b2 155 int count = 0;
79072805 156 MAGIC* mg;
463ee0b2
LW
157 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
158 if (isUPPER(mg->mg_type)) {
159 sv_magic(nsv, mg->mg_obj, tolower(mg->mg_type), key, klen);
160 count++;
79072805 161 }
79072805 162 }
463ee0b2 163 return count;
79072805
LW
164}
165
166int
463ee0b2 167mg_free(sv)
79072805
LW
168SV* sv;
169{
170 MAGIC* mg;
171 MAGIC* moremagic;
172 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
173 MGVTBL* vtbl = mg->mg_virtual;
174 moremagic = mg->mg_moremagic;
175 if (vtbl && vtbl->svt_free)
176 (*vtbl->svt_free)(sv, mg);
93a17b20 177 if (mg->mg_ptr && mg->mg_type != 'g')
79072805 178 Safefree(mg->mg_ptr);
8990e307
LW
179 if (mg->mg_obj != sv)
180 SvREFCNT_dec(mg->mg_obj);
79072805
LW
181 Safefree(mg);
182 }
183 SvMAGIC(sv) = 0;
184 return 0;
185}
186
187#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
188#include <signal.h>
189#endif
190
191#ifdef VOIDSIG
192#define handlertype void
193#else
194#define handlertype int
195#endif
196
197static handlertype sighandler();
198
93a17b20
LW
199U32
200magic_len(sv, mg)
201SV *sv;
202MAGIC *mg;
203{
204 register I32 paren;
205 register char *s;
206 register I32 i;
207
208 switch (*mg->mg_ptr) {
209 case '1': case '2': case '3': case '4':
210 case '5': case '6': case '7': case '8': case '9': case '&':
211 if (curpm) {
212 paren = atoi(mg->mg_ptr);
213 getparen:
214 if (curpm->op_pmregexp &&
215 paren <= curpm->op_pmregexp->nparens &&
216 (s = curpm->op_pmregexp->startp[paren]) ) {
217 i = curpm->op_pmregexp->endp[paren] - s;
218 if (i >= 0)
219 return i;
220 else
221 return 0;
222 }
223 else
224 return 0;
225 }
226 break;
227 case '+':
228 if (curpm) {
229 paren = curpm->op_pmregexp->lastparen;
230 goto getparen;
231 }
232 break;
233 case '`':
234 if (curpm) {
235 if (curpm->op_pmregexp &&
236 (s = curpm->op_pmregexp->subbeg) ) {
237 i = curpm->op_pmregexp->startp[0] - s;
238 if (i >= 0)
239 return i;
240 else
241 return 0;
242 }
243 else
244 return 0;
245 }
246 break;
247 case '\'':
248 if (curpm) {
249 if (curpm->op_pmregexp &&
250 (s = curpm->op_pmregexp->endp[0]) ) {
251 return (STRLEN) (curpm->op_pmregexp->subend - s);
252 }
253 else
254 return 0;
255 }
256 break;
257 case ',':
258 return (STRLEN)ofslen;
259 case '\\':
260 return (STRLEN)orslen;
261 }
262 magic_get(sv,mg);
263 if (!SvPOK(sv) && SvNIOK(sv))
463ee0b2 264 sv_2pv(sv, &na);
93a17b20
LW
265 if (SvPOK(sv))
266 return SvCUR(sv);
267 return 0;
268}
269
79072805
LW
270int
271magic_get(sv, mg)
272SV *sv;
273MAGIC *mg;
274{
275 register I32 paren;
276 register char *s;
277 register I32 i;
278
279 switch (*mg->mg_ptr) {
280 case '\004': /* ^D */
281 sv_setiv(sv,(I32)(debug & 32767));
282 break;
283 case '\006': /* ^F */
284 sv_setiv(sv,(I32)maxsysfd);
285 break;
286 case '\t': /* ^I */
287 if (inplace)
288 sv_setpv(sv, inplace);
289 else
290 sv_setsv(sv,&sv_undef);
291 break;
292 case '\020': /* ^P */
293 sv_setiv(sv,(I32)perldb);
294 break;
295 case '\024': /* ^T */
296 sv_setiv(sv,(I32)basetime);
297 break;
298 case '\027': /* ^W */
299 sv_setiv(sv,(I32)dowarn);
300 break;
301 case '1': case '2': case '3': case '4':
302 case '5': case '6': case '7': case '8': case '9': case '&':
303 if (curpm) {
304 paren = atoi(GvENAME(mg->mg_obj));
305 getparen:
306 if (curpm->op_pmregexp &&
307 paren <= curpm->op_pmregexp->nparens &&
308 (s = curpm->op_pmregexp->startp[paren]) ) {
309 i = curpm->op_pmregexp->endp[paren] - s;
310 if (i >= 0)
311 sv_setpvn(sv,s,i);
312 else
313 sv_setsv(sv,&sv_undef);
314 }
315 else
316 sv_setsv(sv,&sv_undef);
317 }
318 break;
319 case '+':
320 if (curpm) {
321 paren = curpm->op_pmregexp->lastparen;
322 goto getparen;
323 }
324 break;
325 case '`':
326 if (curpm) {
327 if (curpm->op_pmregexp &&
328 (s = curpm->op_pmregexp->subbeg) ) {
329 i = curpm->op_pmregexp->startp[0] - s;
330 if (i >= 0)
331 sv_setpvn(sv,s,i);
332 else
333 sv_setpvn(sv,"",0);
334 }
335 else
336 sv_setpvn(sv,"",0);
337 }
338 break;
339 case '\'':
340 if (curpm) {
341 if (curpm->op_pmregexp &&
342 (s = curpm->op_pmregexp->endp[0]) ) {
343 sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
344 }
345 else
346 sv_setpvn(sv,"",0);
347 }
348 break;
349 case '.':
350#ifndef lint
351 if (last_in_gv && GvIO(last_in_gv)) {
8990e307 352 sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
79072805
LW
353 }
354#endif
355 break;
356 case '?':
357 sv_setiv(sv,(I32)statusvalue);
358 break;
359 case '^':
8990e307 360 s = IoTOP_NAME(GvIO(defoutgv));
79072805
LW
361 if (s)
362 sv_setpv(sv,s);
363 else {
364 sv_setpv(sv,GvENAME(defoutgv));
365 sv_catpv(sv,"_TOP");
366 }
367 break;
368 case '~':
8990e307 369 s = IoFMT_NAME(GvIO(defoutgv));
79072805
LW
370 if (!s)
371 s = GvENAME(defoutgv);
372 sv_setpv(sv,s);
373 break;
374#ifndef lint
375 case '=':
8990e307 376 sv_setiv(sv,(I32)IoPAGE_LEN(GvIO(defoutgv)));
79072805
LW
377 break;
378 case '-':
8990e307 379 sv_setiv(sv,(I32)IoLINES_LEFT(GvIO(defoutgv)));
79072805
LW
380 break;
381 case '%':
8990e307 382 sv_setiv(sv,(I32)IoPAGE(GvIO(defoutgv)));
79072805
LW
383 break;
384#endif
385 case ':':
386 break;
387 case '/':
388 break;
389 case '[':
390 sv_setiv(sv,(I32)arybase);
391 break;
392 case '|':
393 if (!GvIO(defoutgv))
394 GvIO(defoutgv) = newIO();
8990e307 395 sv_setiv(sv, (IoFLAGS(GvIO(defoutgv)) & IOf_FLUSH) != 0 );
79072805
LW
396 break;
397 case ',':
398 sv_setpvn(sv,ofs,ofslen);
399 break;
400 case '\\':
401 sv_setpvn(sv,ors,orslen);
402 break;
403 case '#':
404 sv_setpv(sv,ofmt);
405 break;
406 case '!':
407 sv_setnv(sv,(double)errno);
408 sv_setpv(sv, errno ? strerror(errno) : "");
409 SvNOK_on(sv); /* what a wonderful hack! */
410 break;
411 case '<':
412 sv_setiv(sv,(I32)uid);
413 break;
414 case '>':
415 sv_setiv(sv,(I32)euid);
416 break;
417 case '(':
418 s = buf;
419 (void)sprintf(s,"%d",(int)gid);
420 goto add_groups;
421 case ')':
422 s = buf;
423 (void)sprintf(s,"%d",(int)egid);
424 add_groups:
425 while (*s) s++;
426#ifdef HAS_GETGROUPS
427#ifndef NGROUPS
428#define NGROUPS 32
429#endif
430 {
431 GROUPSTYPE gary[NGROUPS];
432
433 i = getgroups(NGROUPS,gary);
434 while (--i >= 0) {
435 (void)sprintf(s," %ld", (long)gary[i]);
436 while (*s) s++;
437 }
438 }
439#endif
440 sv_setpv(sv,buf);
441 break;
442 case '*':
443 break;
444 case '0':
445 break;
446 }
447}
448
449int
450magic_getuvar(sv, mg)
451SV *sv;
452MAGIC *mg;
453{
454 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
455
456 if (uf && uf->uf_val)
457 (*uf->uf_val)(uf->uf_index, sv);
458 return 0;
459}
460
461int
462magic_setenv(sv,mg)
463SV* sv;
464MAGIC* mg;
465{
466 register char *s;
467 I32 i;
8990e307 468 s = SvPV(sv,na);
79072805
LW
469 my_setenv(mg->mg_ptr,s);
470 /* And you'll never guess what the dog had */
471 /* in its mouth... */
463ee0b2
LW
472 if (tainting) {
473 if (s && strEQ(mg->mg_ptr,"PATH")) {
474 char *strend = SvEND(sv);
475
476 while (s < strend) {
477 s = cpytill(tokenbuf,s,strend,':',&i);
478 s++;
479 if (*tokenbuf != '/'
480 || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
8990e307 481 MgTAINTEDDIR_on(mg);
463ee0b2 482 }
79072805
LW
483 }
484 }
79072805
LW
485 return 0;
486}
487
488int
489magic_setsig(sv,mg)
490SV* sv;
491MAGIC* mg;
492{
493 register char *s;
494 I32 i;
8990e307 495 s = SvPV(sv,na);
79072805
LW
496 i = whichsig(mg->mg_ptr); /* ...no, a brick */
497 if (!i && (dowarn || strEQ(mg->mg_ptr,"ALARM")))
498 warn("No such signal: SIG%s", mg->mg_ptr);
499 if (strEQ(s,"IGNORE"))
500#ifndef lint
501 (void)signal(i,SIG_IGN);
502#else
503 ;
504#endif
505 else if (strEQ(s,"DEFAULT") || !*s)
506 (void)signal(i,SIG_DFL);
507 else {
508 (void)signal(i,sighandler);
93a17b20 509 if (!strchr(s,'\'')) {
79072805
LW
510 sprintf(tokenbuf, "main'%s",s);
511 sv_setpv(sv,tokenbuf);
512 }
513 }
514 return 0;
515}
516
517int
463ee0b2 518magic_setisa(sv,mg)
79072805
LW
519SV* sv;
520MAGIC* mg;
521{
463ee0b2
LW
522 sub_generation++;
523 return 0;
524}
525
526int
527magic_getpack(sv,mg)
528SV* sv;
529MAGIC* mg;
530{
531 SV* rv = mg->mg_obj;
ed6116ce 532 HV* stash = SvSTASH(SvRV(rv));
463ee0b2
LW
533 GV* gv = gv_fetchmethod(stash, "fetch");
534 dSP;
535 BINOP myop;
536
537 if (!gv || !GvCV(gv)) {
538 croak("No fetch method for magical variable in package \"%s\"",
539 HvNAME(stash));
540 }
541 Zero(&myop, 1, BINOP);
542 myop.op_last = (OP *) &myop;
543 myop.op_next = Nullop;
544 myop.op_flags = OPf_STACKED;
545
546 ENTER;
547 SAVESPTR(op);
548 op = (OP *) &myop;
549 PUTBACK;
550 pp_pushmark();
551
552 EXTEND(sp, 4);
553 PUSHs(gv);
554 PUSHs(rv);
555 if (mg->mg_ptr)
556 PUSHs(sv_mortalcopy(newSVpv(mg->mg_ptr, mg->mg_len)));
557 else if (mg->mg_len >= 0)
558 PUSHs(sv_mortalcopy(newSViv(mg->mg_len)));
559 PUTBACK;
560
561 if (op = pp_entersubr())
562 run();
563 LEAVE;
564 SPAGAIN;
565
566 sv_setsv(sv, POPs);
567 PUTBACK;
568
569 return 0;
570}
571
572int
573magic_setpack(sv,mg)
574SV* sv;
575MAGIC* mg;
576{
577 SV* rv = mg->mg_obj;
ed6116ce 578 HV* stash = SvSTASH(SvRV(rv));
463ee0b2
LW
579 GV* gv = gv_fetchmethod(stash, "store");
580 dSP;
581 BINOP myop;
582
583 if (!gv || !GvCV(gv)) {
584 croak("No store method for magical variable in package \"%s\"",
585 HvNAME(stash));
586 }
587 Zero(&myop, 1, BINOP);
588 myop.op_last = (OP *) &myop;
589 myop.op_next = Nullop;
590 myop.op_flags = OPf_STACKED;
591
592 ENTER;
593 SAVESPTR(op);
594 op = (OP *) &myop;
595 PUTBACK;
596 pp_pushmark();
597
598 EXTEND(sp, 4);
599 PUSHs(gv);
600 PUSHs(rv);
601 if (mg->mg_ptr)
602 PUSHs(sv_mortalcopy(newSVpv(mg->mg_ptr, mg->mg_len)));
603 else if (mg->mg_len >= 0)
604 PUSHs(sv_mortalcopy(newSViv(mg->mg_len)));
605 PUSHs(sv);
606 PUTBACK;
607
608 if (op = pp_entersubr())
609 run();
610 LEAVE;
611 SPAGAIN;
612
613 POPs;
614 PUTBACK;
615
616 return 0;
617}
618
619int
620magic_clearpack(sv,mg)
621SV* sv;
622MAGIC* mg;
623{
624 SV* rv = mg->mg_obj;
ed6116ce 625 HV* stash = SvSTASH(SvRV(rv));
463ee0b2
LW
626 GV* gv = gv_fetchmethod(stash, "delete");
627 dSP;
628 BINOP myop;
629
630 if (!gv || !GvCV(gv)) {
631 croak("No delete method for magical variable in package \"%s\"",
632 HvNAME(stash));
633 }
634 Zero(&myop, 1, BINOP);
635 myop.op_last = (OP *) &myop;
636 myop.op_next = Nullop;
637 myop.op_flags = OPf_STACKED;
638
639 ENTER;
640 SAVESPTR(op);
641 op = (OP *) &myop;
642 PUTBACK;
643 pp_pushmark();
644
645 EXTEND(sp, 4);
646 PUSHs(gv);
647 PUSHs(rv);
648 if (mg->mg_ptr)
649 PUSHs(sv_mortalcopy(newSVpv(mg->mg_ptr, mg->mg_len)));
650 else
651 PUSHs(sv_mortalcopy(newSViv(mg->mg_len)));
652 PUTBACK;
653
654 if (op = pp_entersubr())
655 run();
656 LEAVE;
657 SPAGAIN;
658
659 sv_setsv(sv, POPs);
660 PUTBACK;
661
662 return 0;
663}
664
665int
666magic_nextpack(sv,mg,key)
667SV* sv;
668MAGIC* mg;
669SV* key;
670{
671 SV* rv = mg->mg_obj;
ed6116ce 672 HV* stash = SvSTASH(SvRV(rv));
463ee0b2
LW
673 GV* gv = gv_fetchmethod(stash, SvOK(key) ? "nextkey" : "firstkey");
674 dSP;
675 BINOP myop;
676
677 if (!gv || !GvCV(gv)) {
678 croak("No fetch method for magical variable in package \"%s\"",
679 HvNAME(stash));
680 }
681 Zero(&myop, 1, BINOP);
682 myop.op_last = (OP *) &myop;
683 myop.op_next = Nullop;
684 myop.op_flags = OPf_STACKED;
685
686 ENTER;
687 SAVESPTR(op);
688 op = (OP *) &myop;
689 PUTBACK;
690 pp_pushmark();
691
692 EXTEND(sp, 4);
693 PUSHs(gv);
694 PUSHs(rv);
695 if (SvOK(key))
696 PUSHs(key);
697 PUTBACK;
698
699 if (op = pp_entersubr())
700 run();
701 LEAVE;
702 SPAGAIN;
703
704 sv_setsv(key, POPs);
705 PUTBACK;
706
79072805
LW
707 return 0;
708}
709
710int
711magic_setdbline(sv,mg)
712SV* sv;
713MAGIC* mg;
714{
715 OP *o;
716 I32 i;
717 GV* gv;
718 SV** svp;
719
720 gv = DBline;
721 i = SvTRUE(sv);
722 svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
8990e307 723 if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
93a17b20 724 o->op_private = i;
79072805
LW
725 else
726 warn("Can't break at that line\n");
727 return 0;
728}
729
730int
731magic_getarylen(sv,mg)
732SV* sv;
733MAGIC* mg;
734{
735 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + arybase);
736 return 0;
737}
738
739int
740magic_setarylen(sv,mg)
741SV* sv;
742MAGIC* mg;
743{
463ee0b2 744 av_fill((AV*)mg->mg_obj, (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) - arybase);
79072805
LW
745 return 0;
746}
747
748int
749magic_getglob(sv,mg)
750SV* sv;
751MAGIC* mg;
752{
753 gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
754 return 0;
755}
756
757int
758magic_setglob(sv,mg)
759SV* sv;
760MAGIC* mg;
761{
762 register char *s;
763 GV* gv;
764
765 if (!SvOK(sv))
766 return 0;
463ee0b2 767 s = SvPV(sv, na);
79072805
LW
768 if (*s == '*' && s[1])
769 s++;
770 gv = gv_fetchpv(s,TRUE);
771 if (sv == (SV*)gv)
772 return 0;
773 if (GvGP(sv))
774 gp_free(sv);
775 GvGP(sv) = gp_ref(GvGP(gv));
776 if (!GvAV(gv))
777 gv_AVadd(gv);
778 if (!GvHV(gv))
779 gv_HVadd(gv);
780 if (!GvIO(gv))
781 GvIO(gv) = newIO();
782 return 0;
783}
784
785int
786magic_setsubstr(sv,mg)
787SV* sv;
788MAGIC* mg;
789{
8990e307
LW
790 STRLEN len;
791 char *tmps = SvPV(sv,len);
792 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
79072805
LW
793 return 0;
794}
795
796int
463ee0b2
LW
797magic_gettaint(sv,mg)
798SV* sv;
799MAGIC* mg;
800{
801 tainted = TRUE;
802 return 0;
803}
804
805int
806magic_settaint(sv,mg)
807SV* sv;
808MAGIC* mg;
809{
810 if (!tainted)
811 sv_unmagic(sv, 't');
812 return 0;
813}
814
815int
79072805
LW
816magic_setvec(sv,mg)
817SV* sv;
818MAGIC* mg;
819{
820 do_vecset(sv); /* XXX slurp this routine */
821 return 0;
822}
823
824int
93a17b20
LW
825magic_setmglob(sv,mg)
826SV* sv;
827MAGIC* mg;
828{
829 mg->mg_ptr = 0;
830 mg->mg_len = 0;
831 return 0;
832}
833
834int
79072805
LW
835magic_setbm(sv,mg)
836SV* sv;
837MAGIC* mg;
838{
463ee0b2 839 sv_unmagic(sv, 'B');
79072805
LW
840 SvVALID_off(sv);
841 return 0;
842}
843
844int
845magic_setuvar(sv,mg)
846SV* sv;
847MAGIC* mg;
848{
849 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
850
851 if (uf && uf->uf_set)
852 (*uf->uf_set)(uf->uf_index, sv);
853 return 0;
854}
855
856int
857magic_set(sv,mg)
858SV* sv;
859MAGIC* mg;
860{
861 register char *s;
862 I32 i;
8990e307 863 STRLEN len;
79072805
LW
864 switch (*mg->mg_ptr) {
865 case '\004': /* ^D */
8990e307 866 debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
79072805
LW
867 DEBUG_x(dump_all());
868 break;
869 case '\006': /* ^F */
463ee0b2 870 maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
871 break;
872 case '\t': /* ^I */
873 if (inplace)
874 Safefree(inplace);
875 if (SvOK(sv))
8990e307 876 inplace = savestr(SvPV(sv,na));
79072805
LW
877 else
878 inplace = Nullch;
879 break;
880 case '\020': /* ^P */
463ee0b2 881 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
882 if (i != perldb) {
883 if (perldb)
884 oldlastpm = curpm;
885 else
886 curpm = oldlastpm;
887 }
888 perldb = i;
889 break;
890 case '\024': /* ^T */
463ee0b2 891 basetime = (time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
892 break;
893 case '\027': /* ^W */
463ee0b2 894 dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
895 break;
896 case '.':
897 if (localizing)
898 save_sptr((SV**)&last_in_gv);
899 break;
900 case '^':
8990e307
LW
901 Safefree(IoTOP_NAME(GvIO(defoutgv)));
902 IoTOP_NAME(GvIO(defoutgv)) = s = savestr(SvPV(sv,na));
903 IoTOP_GV(GvIO(defoutgv)) = gv_fetchpv(s,TRUE);
79072805
LW
904 break;
905 case '~':
8990e307
LW
906 Safefree(IoFMT_NAME(GvIO(defoutgv)));
907 IoFMT_NAME(GvIO(defoutgv)) = s = savestr(SvPV(sv,na));
908 IoFMT_GV(GvIO(defoutgv)) = gv_fetchpv(s,TRUE);
79072805
LW
909 break;
910 case '=':
8990e307 911 IoPAGE_LEN(GvIO(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
912 break;
913 case '-':
8990e307
LW
914 IoLINES_LEFT(GvIO(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
915 if (IoLINES_LEFT(GvIO(defoutgv)) < 0L)
916 IoLINES_LEFT(GvIO(defoutgv)) = 0L;
79072805
LW
917 break;
918 case '%':
8990e307 919 IoPAGE(GvIO(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
920 break;
921 case '|':
922 if (!GvIO(defoutgv))
923 GvIO(defoutgv) = newIO();
8990e307 924 IoFLAGS(GvIO(defoutgv)) &= ~IOf_FLUSH;
463ee0b2 925 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
8990e307 926 IoFLAGS(GvIO(defoutgv)) |= IOf_FLUSH;
79072805
LW
927 }
928 break;
929 case '*':
463ee0b2 930 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
931 multiline = (i != 0);
932 break;
933 case '/':
934 if (SvPOK(sv)) {
8990e307
LW
935 nrs = rs = SvPV(sv,rslen);
936 nrslen = rslen;
79072805 937 if (rspara = !rslen) {
93a17b20
LW
938 nrs = rs = "\n\n";
939 nrslen = rslen = 2;
79072805 940 }
93a17b20 941 nrschar = rschar = rs[rslen - 1];
79072805
LW
942 }
943 else {
93a17b20
LW
944 nrschar = rschar = 0777; /* fake a non-existent char */
945 nrslen = rslen = 1;
79072805
LW
946 }
947 break;
948 case '\\':
949 if (ors)
950 Safefree(ors);
8990e307 951 ors = savestr(SvPV(sv,orslen));
79072805
LW
952 break;
953 case ',':
954 if (ofs)
955 Safefree(ofs);
8990e307 956 ofs = savestr(SvPV(sv, ofslen));
79072805
LW
957 break;
958 case '#':
959 if (ofmt)
960 Safefree(ofmt);
8990e307 961 ofmt = savestr(SvPV(sv,na));
79072805
LW
962 break;
963 case '[':
463ee0b2 964 arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
965 break;
966 case '?':
463ee0b2 967 statusvalue = U_S(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
968 break;
969 case '!':
463ee0b2 970 errno = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); /* will anyone ever use this? */
79072805
LW
971 break;
972 case '<':
463ee0b2 973 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
974 if (delaymagic) {
975 delaymagic |= DM_RUID;
976 break; /* don't do magic till later */
977 }
978#ifdef HAS_SETRUID
979 (void)setruid((UIDTYPE)uid);
980#else
981#ifdef HAS_SETREUID
982 (void)setreuid((UIDTYPE)uid, (UIDTYPE)-1);
983#else
984 if (uid == euid) /* special case $< = $> */
985 (void)setuid(uid);
986 else
463ee0b2 987 croak("setruid() not implemented");
79072805
LW
988#endif
989#endif
463ee0b2
LW
990 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
991 tainting |= (euid != uid || egid != gid);
79072805
LW
992 break;
993 case '>':
463ee0b2 994 euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
995 if (delaymagic) {
996 delaymagic |= DM_EUID;
997 break; /* don't do magic till later */
998 }
999#ifdef HAS_SETEUID
1000 (void)seteuid((UIDTYPE)euid);
1001#else
1002#ifdef HAS_SETREUID
1003 (void)setreuid((UIDTYPE)-1, (UIDTYPE)euid);
1004#else
1005 if (euid == uid) /* special case $> = $< */
1006 setuid(euid);
1007 else
463ee0b2 1008 croak("seteuid() not implemented");
79072805
LW
1009#endif
1010#endif
1011 euid = (I32)geteuid();
463ee0b2 1012 tainting |= (euid != uid || egid != gid);
79072805
LW
1013 break;
1014 case '(':
463ee0b2 1015 gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1016 if (delaymagic) {
1017 delaymagic |= DM_RGID;
1018 break; /* don't do magic till later */
1019 }
1020#ifdef HAS_SETRGID
1021 (void)setrgid((GIDTYPE)gid);
1022#else
1023#ifdef HAS_SETREGID
1024 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
1025#else
1026 if (gid == egid) /* special case $( = $) */
1027 (void)setgid(gid);
1028 else
463ee0b2 1029 croak("setrgid() not implemented");
79072805
LW
1030#endif
1031#endif
1032 gid = (I32)getgid();
463ee0b2 1033 tainting |= (euid != uid || egid != gid);
79072805
LW
1034 break;
1035 case ')':
463ee0b2 1036 egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1037 if (delaymagic) {
1038 delaymagic |= DM_EGID;
1039 break; /* don't do magic till later */
1040 }
1041#ifdef HAS_SETEGID
1042 (void)setegid((GIDTYPE)egid);
1043#else
1044#ifdef HAS_SETREGID
1045 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
1046#else
1047 if (egid == gid) /* special case $) = $( */
1048 (void)setgid(egid);
1049 else
463ee0b2 1050 croak("setegid() not implemented");
79072805
LW
1051#endif
1052#endif
1053 egid = (I32)getegid();
463ee0b2 1054 tainting |= (euid != uid || egid != gid);
79072805
LW
1055 break;
1056 case ':':
8990e307 1057 chopset = SvPV(sv,na);
79072805
LW
1058 break;
1059 case '0':
1060 if (!origalen) {
1061 s = origargv[0];
1062 s += strlen(s);
1063 /* See if all the arguments are contiguous in memory */
1064 for (i = 1; i < origargc; i++) {
1065 if (origargv[i] == s + 1)
1066 s += strlen(++s); /* this one is ok too */
1067 }
1068 if (origenviron[0] == s + 1) { /* can grab env area too? */
1069 my_setenv("NoNeSuCh", Nullch);
1070 /* force copy of environment */
1071 for (i = 0; origenviron[i]; i++)
1072 if (origenviron[i] == s + 1)
1073 s += strlen(++s);
1074 }
1075 origalen = s - origargv[0];
1076 }
8990e307
LW
1077 s = SvPV(sv,len);
1078 i = len;
79072805
LW
1079 if (i >= origalen) {
1080 i = origalen;
1081 SvCUR_set(sv, i);
1082 *SvEND(sv) = '\0';
1083 Copy(s, origargv[0], i, char);
1084 }
1085 else {
1086 Copy(s, origargv[0], i, char);
1087 s = origargv[0]+i;
1088 *s++ = '\0';
1089 while (++i < origalen)
8990e307
LW
1090 *s++ = ' ';
1091 s = origargv[0]+i;
ed6116ce 1092 for (i = 1; i < origargc; i++)
8990e307 1093 origargv[i] = Nullch;
79072805
LW
1094 }
1095 break;
1096 }
1097 return 0;
1098}
1099
1100I32
1101whichsig(sig)
1102char *sig;
1103{
1104 register char **sigv;
1105
1106 for (sigv = sig_name+1; *sigv; sigv++)
1107 if (strEQ(sig,*sigv))
1108 return sigv - sig_name;
1109#ifdef SIGCLD
1110 if (strEQ(sig,"CHLD"))
1111 return SIGCLD;
1112#endif
1113#ifdef SIGCHLD
1114 if (strEQ(sig,"CLD"))
1115 return SIGCHLD;
1116#endif
1117 return 0;
1118}
1119
1120static handlertype
1121sighandler(sig)
1122I32 sig;
1123{
1124 dSP;
1125 GV *gv;
1126 SV *sv;
1127 CV *cv;
1128 CONTEXT *cx;
1129 AV *oldstack;
1130 I32 hasargs = 1;
1131 I32 items = 1;
1132 I32 gimme = G_SCALAR;
1133
1134#ifdef OS2 /* or anybody else who requires SIG_ACK */
1135 signal(sig, SIG_ACK);
1136#endif
1137
1138 gv = gv_fetchpv(
463ee0b2
LW
1139 SvPVx(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
1140 TRUE), na), TRUE);
79072805
LW
1141 cv = GvCV(gv);
1142 if (!cv && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
1143 if (sig_name[sig][1] == 'H')
463ee0b2 1144 gv = gv_fetchpv(SvPVx(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE), na),
79072805
LW
1145 TRUE);
1146 else
463ee0b2 1147 gv = gv_fetchpv(SvPVx(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE), na),
79072805
LW
1148 TRUE);
1149 cv = GvCV(gv); /* gag */
1150 }
1151 if (!cv) {
1152 if (dowarn)
1153 warn("SIG%s handler \"%s\" not defined.\n",
1154 sig_name[sig], GvENAME(gv) );
1155 return;
1156 }
1157
1158 oldstack = stack;
1159 SWITCHSTACK(stack, signalstack);
1160
8990e307 1161 sv = sv_newmortal();
79072805
LW
1162 sv_setpv(sv,sig_name[sig]);
1163 PUSHs(sv);
1164
1165 ENTER;
1166 SAVETMPS;
1167
1168 push_return(op);
1169 push_return(0);
1170 PUSHBLOCK(cx, CXt_SUB, sp);
1171 PUSHSUB(cx);
1172 cx->blk_sub.savearray = GvAV(defgv);
1173 cx->blk_sub.argarray = av_fake(items, sp);
8990e307 1174 SAVEFREESV(cx->blk_sub.argarray);
79072805
LW
1175 GvAV(defgv) = cx->blk_sub.argarray;
1176 CvDEPTH(cv)++;
1177 if (CvDEPTH(cv) >= 2) {
1178 if (CvDEPTH(cv) == 100 && dowarn)
1179 warn("Deep recursion on subroutine \"%s\"",GvENAME(gv));
1180 }
1181 op = CvSTART(cv);
1182 PUTBACK;
1183 run(); /* Does the LEAVE for us. */
1184
1185 SWITCHSTACK(signalstack, oldstack);
1186 op = pop_return();
1187
1188 return;
1189}