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