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