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