This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl5.000 patch.0o: [address] a few more Configure and build nits.
[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;
463ee0b2
LW
111 char *s;
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
133 s = 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;
226
227 switch (*mg->mg_ptr) {
228 case '1': case '2': case '3': case '4':
229 case '5': case '6': case '7': case '8': case '9': case '&':
230 if (curpm) {
231 paren = atoi(mg->mg_ptr);
232 getparen:
233 if (curpm->op_pmregexp &&
234 paren <= curpm->op_pmregexp->nparens &&
235 (s = curpm->op_pmregexp->startp[paren]) ) {
236 i = curpm->op_pmregexp->endp[paren] - s;
237 if (i >= 0)
238 return i;
239 else
240 return 0;
241 }
242 else
243 return 0;
244 }
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 }
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;
261 else
262 return 0;
263 }
264 else
265 return 0;
266 }
267 break;
268 case '\'':
269 if (curpm) {
270 if (curpm->op_pmregexp &&
271 (s = curpm->op_pmregexp->endp[0]) ) {
272 return (STRLEN) (curpm->op_pmregexp->subend - s);
273 }
274 else
275 return 0;
276 }
277 break;
278 case ',':
279 return (STRLEN)ofslen;
280 case '\\':
281 return (STRLEN)orslen;
282 }
283 magic_get(sv,mg);
284 if (!SvPOK(sv) && SvNIOK(sv))
463ee0b2 285 sv_2pv(sv, &na);
93a17b20
LW
286 if (SvPOK(sv))
287 return SvCUR(sv);
288 return 0;
289}
290
79072805
LW
291int
292magic_get(sv, mg)
293SV *sv;
294MAGIC *mg;
295{
296 register I32 paren;
297 register char *s;
298 register I32 i;
299
300 switch (*mg->mg_ptr) {
301 case '\004': /* ^D */
302 sv_setiv(sv,(I32)(debug & 32767));
303 break;
304 case '\006': /* ^F */
305 sv_setiv(sv,(I32)maxsysfd);
306 break;
a0d0e21e
LW
307 case '\010': /* ^H */
308 sv_setiv(sv,(I32)hints);
309 break;
79072805
LW
310 case '\t': /* ^I */
311 if (inplace)
312 sv_setpv(sv, inplace);
313 else
314 sv_setsv(sv,&sv_undef);
315 break;
316 case '\020': /* ^P */
317 sv_setiv(sv,(I32)perldb);
318 break;
319 case '\024': /* ^T */
320 sv_setiv(sv,(I32)basetime);
321 break;
322 case '\027': /* ^W */
323 sv_setiv(sv,(I32)dowarn);
324 break;
325 case '1': case '2': case '3': case '4':
326 case '5': case '6': case '7': case '8': case '9': case '&':
327 if (curpm) {
328 paren = atoi(GvENAME(mg->mg_obj));
329 getparen:
330 if (curpm->op_pmregexp &&
331 paren <= curpm->op_pmregexp->nparens &&
a0d0e21e
LW
332 (s = curpm->op_pmregexp->startp[paren]) &&
333 curpm->op_pmregexp->endp[paren] ) {
79072805
LW
334 i = curpm->op_pmregexp->endp[paren] - s;
335 if (i >= 0)
336 sv_setpvn(sv,s,i);
337 else
338 sv_setsv(sv,&sv_undef);
339 }
340 else
341 sv_setsv(sv,&sv_undef);
342 }
343 break;
344 case '+':
345 if (curpm) {
346 paren = curpm->op_pmregexp->lastparen;
a0d0e21e
LW
347 if (paren)
348 goto getparen;
349 else
350 sv_setsv(sv,&sv_undef);
79072805
LW
351 }
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;
358 if (i >= 0)
359 sv_setpvn(sv,s,i);
360 else
361 sv_setpvn(sv,"",0);
362 }
363 else
364 sv_setpvn(sv,"",0);
365 }
366 break;
367 case '\'':
368 if (curpm) {
369 if (curpm->op_pmregexp &&
370 (s = curpm->op_pmregexp->endp[0]) ) {
371 sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
372 }
373 else
374 sv_setpvn(sv,"",0);
375 }
376 break;
377 case '.':
378#ifndef lint
a0d0e21e 379 if (GvIO(last_in_gv)) {
8990e307 380 sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
79072805
LW
381 }
382#endif
383 break;
384 case '?':
385 sv_setiv(sv,(I32)statusvalue);
386 break;
387 case '^':
a0d0e21e 388 s = IoTOP_NAME(GvIOp(defoutgv));
79072805
LW
389 if (s)
390 sv_setpv(sv,s);
391 else {
392 sv_setpv(sv,GvENAME(defoutgv));
393 sv_catpv(sv,"_TOP");
394 }
395 break;
396 case '~':
a0d0e21e 397 s = IoFMT_NAME(GvIOp(defoutgv));
79072805
LW
398 if (!s)
399 s = GvENAME(defoutgv);
400 sv_setpv(sv,s);
401 break;
402#ifndef lint
403 case '=':
a0d0e21e 404 sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
79072805
LW
405 break;
406 case '-':
a0d0e21e 407 sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
79072805
LW
408 break;
409 case '%':
a0d0e21e 410 sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
79072805
LW
411 break;
412#endif
413 case ':':
414 break;
415 case '/':
416 break;
417 case '[':
a0d0e21e 418 sv_setiv(sv,(I32)curcop->cop_arybase);
79072805
LW
419 break;
420 case '|':
a0d0e21e 421 sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
79072805
LW
422 break;
423 case ',':
424 sv_setpvn(sv,ofs,ofslen);
425 break;
426 case '\\':
427 sv_setpvn(sv,ors,orslen);
428 break;
429 case '#':
430 sv_setpv(sv,ofmt);
431 break;
432 case '!':
433 sv_setnv(sv,(double)errno);
2304df62 434 sv_setpv(sv, errno ? Strerror(errno) : "");
79072805
LW
435 SvNOK_on(sv); /* what a wonderful hack! */
436 break;
437 case '<':
438 sv_setiv(sv,(I32)uid);
439 break;
440 case '>':
441 sv_setiv(sv,(I32)euid);
442 break;
443 case '(':
444 s = buf;
445 (void)sprintf(s,"%d",(int)gid);
446 goto add_groups;
447 case ')':
448 s = buf;
449 (void)sprintf(s,"%d",(int)egid);
450 add_groups:
451 while (*s) s++;
452#ifdef HAS_GETGROUPS
453#ifndef NGROUPS
454#define NGROUPS 32
455#endif
456 {
a0d0e21e 457 Groups_t gary[NGROUPS];
79072805
LW
458
459 i = getgroups(NGROUPS,gary);
460 while (--i >= 0) {
461 (void)sprintf(s," %ld", (long)gary[i]);
462 while (*s) s++;
463 }
464 }
465#endif
466 sv_setpv(sv,buf);
467 break;
468 case '*':
469 break;
470 case '0':
471 break;
472 }
a0d0e21e 473 return 0;
79072805
LW
474}
475
476int
477magic_getuvar(sv, mg)
478SV *sv;
479MAGIC *mg;
480{
481 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
482
483 if (uf && uf->uf_val)
484 (*uf->uf_val)(uf->uf_index, sv);
485 return 0;
486}
487
488int
489magic_setenv(sv,mg)
490SV* sv;
491MAGIC* mg;
492{
493 register char *s;
a0d0e21e
LW
494 STRLEN len;
495 I32 i;
496 s = SvPV(sv,len);
79072805 497 my_setenv(mg->mg_ptr,s);
a0d0e21e
LW
498#ifdef DYNAMIC_ENV_FETCH
499 /* We just undefd an environment var. Is a replacement */
500 /* waiting in the wings? */
501 if (!len) {
502 SV **envsvp;
503 if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE))
504 s = SvPV(*envsvp,len);
505 }
506#endif
79072805
LW
507 /* And you'll never guess what the dog had */
508 /* in its mouth... */
463ee0b2
LW
509 if (tainting) {
510 if (s && strEQ(mg->mg_ptr,"PATH")) {
a0d0e21e 511 char *strend = s + len;
463ee0b2
LW
512
513 while (s < strend) {
514 s = cpytill(tokenbuf,s,strend,':',&i);
515 s++;
516 if (*tokenbuf != '/'
a0d0e21e 517 || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
8990e307 518 MgTAINTEDDIR_on(mg);
463ee0b2 519 }
79072805
LW
520 }
521 }
79072805
LW
522 return 0;
523}
524
525int
85e6fe83
LW
526magic_clearenv(sv,mg)
527SV* sv;
528MAGIC* mg;
529{
530 my_setenv(mg->mg_ptr,Nullch);
531 return 0;
532}
533
534int
79072805
LW
535magic_setsig(sv,mg)
536SV* sv;
537MAGIC* mg;
538{
539 register char *s;
540 I32 i;
a0d0e21e 541
79072805
LW
542 i = whichsig(mg->mg_ptr); /* ...no, a brick */
543 if (!i && (dowarn || strEQ(mg->mg_ptr,"ALARM")))
544 warn("No such signal: SIG%s", mg->mg_ptr);
a0d0e21e
LW
545 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
546 (void)signal(i,sighandler);
547 return 0;
548 }
549 s = SvPV_force(sv,na);
79072805
LW
550 if (strEQ(s,"IGNORE"))
551#ifndef lint
552 (void)signal(i,SIG_IGN);
553#else
554 ;
555#endif
556 else if (strEQ(s,"DEFAULT") || !*s)
557 (void)signal(i,SIG_DFL);
558 else {
559 (void)signal(i,sighandler);
2304df62
AD
560 if (!strchr(s,':') && !strchr(s,'\'')) {
561 sprintf(tokenbuf, "main::%s",s);
79072805
LW
562 sv_setpv(sv,tokenbuf);
563 }
564 }
565 return 0;
566}
567
568int
463ee0b2 569magic_setisa(sv,mg)
79072805
LW
570SV* sv;
571MAGIC* mg;
572{
463ee0b2
LW
573 sub_generation++;
574 return 0;
575}
576
a0d0e21e
LW
577#ifdef OVERLOAD
578
463ee0b2 579int
a0d0e21e 580magic_setamagic(sv,mg)
463ee0b2
LW
581SV* sv;
582MAGIC* mg;
583{
a0d0e21e
LW
584 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
585 amagic_generation++;
463ee0b2 586
a0d0e21e
LW
587 return 0;
588}
589#endif /* OVERLOAD */
463ee0b2 590
a0d0e21e
LW
591static int
592magic_methpack(sv,mg,meth)
593SV* sv;
594MAGIC* mg;
595char *meth;
596{
597 dSP;
463ee0b2 598
a0d0e21e
LW
599 ENTER;
600 SAVETMPS;
601 PUSHMARK(sp);
602 EXTEND(sp, 2);
603 PUSHs(mg->mg_obj);
463ee0b2 604 if (mg->mg_ptr)
a0d0e21e
LW
605 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
606 else if (mg->mg_type == 'p')
607 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2
LW
608 PUTBACK;
609
a0d0e21e
LW
610 if (perl_call_method(meth, G_SCALAR))
611 sv_setsv(sv, *stack_sp--);
463ee0b2 612
a0d0e21e
LW
613 FREETMPS;
614 LEAVE;
615 return 0;
616}
463ee0b2 617
a0d0e21e
LW
618int
619magic_getpack(sv,mg)
620SV* sv;
621MAGIC* mg;
622{
623 magic_methpack(sv,mg,"FETCH");
624 if (mg->mg_ptr)
625 mg->mg_flags |= MGf_GSKIP;
463ee0b2
LW
626 return 0;
627}
628
629int
630magic_setpack(sv,mg)
631SV* sv;
632MAGIC* mg;
633{
463ee0b2 634 dSP;
463ee0b2 635
a0d0e21e
LW
636 PUSHMARK(sp);
637 EXTEND(sp, 3);
638 PUSHs(mg->mg_obj);
463ee0b2 639 if (mg->mg_ptr)
a0d0e21e
LW
640 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
641 else if (mg->mg_type == 'p')
642 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2
LW
643 PUSHs(sv);
644 PUTBACK;
645
a0d0e21e 646 perl_call_method("STORE", G_SCALAR|G_DISCARD);
463ee0b2
LW
647
648 return 0;
649}
650
651int
652magic_clearpack(sv,mg)
653SV* sv;
654MAGIC* mg;
655{
a0d0e21e
LW
656 return magic_methpack(sv,mg,"DELETE");
657}
463ee0b2 658
a0d0e21e
LW
659int magic_wipepack(sv,mg)
660SV* sv;
661MAGIC* mg;
662{
663 dSP;
463ee0b2 664
a0d0e21e
LW
665 PUSHMARK(sp);
666 XPUSHs(mg->mg_obj);
463ee0b2 667 PUTBACK;
463ee0b2 668
a0d0e21e 669 perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
463ee0b2
LW
670
671 return 0;
672}
673
674int
675magic_nextpack(sv,mg,key)
676SV* sv;
677MAGIC* mg;
678SV* key;
679{
463ee0b2 680 dSP;
a0d0e21e 681 char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2
LW
682
683 ENTER;
a0d0e21e
LW
684 SAVETMPS;
685 PUSHMARK(sp);
686 EXTEND(sp, 2);
687 PUSHs(mg->mg_obj);
463ee0b2
LW
688 if (SvOK(key))
689 PUSHs(key);
690 PUTBACK;
691
a0d0e21e
LW
692 if (perl_call_method(meth, G_SCALAR))
693 sv_setsv(key, *stack_sp--);
463ee0b2 694
a0d0e21e
LW
695 FREETMPS;
696 LEAVE;
79072805
LW
697 return 0;
698}
699
700int
a0d0e21e
LW
701magic_existspack(sv,mg)
702SV* sv;
703MAGIC* mg;
704{
705 return magic_methpack(sv,mg,"EXISTS");
706}
707
708int
79072805
LW
709magic_setdbline(sv,mg)
710SV* sv;
711MAGIC* mg;
712{
713 OP *o;
714 I32 i;
715 GV* gv;
716 SV** svp;
717
718 gv = DBline;
719 i = SvTRUE(sv);
720 svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
8990e307 721 if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
93a17b20 722 o->op_private = i;
79072805
LW
723 else
724 warn("Can't break at that line\n");
725 return 0;
726}
727
728int
729magic_getarylen(sv,mg)
730SV* sv;
731MAGIC* mg;
732{
a0d0e21e 733 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
79072805
LW
734 return 0;
735}
736
737int
738magic_setarylen(sv,mg)
739SV* sv;
740MAGIC* mg;
741{
a0d0e21e
LW
742 av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
743 return 0;
744}
745
746int
747magic_getpos(sv,mg)
748SV* sv;
749MAGIC* mg;
750{
751 SV* lsv = LvTARG(sv);
752
753 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
754 mg = mg_find(lsv, 'g');
755 if (mg && mg->mg_len >= 0) {
756 sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
757 return 0;
758 }
759 }
760 (void)SvOK_off(sv);
761 return 0;
762}
763
764int
765magic_setpos(sv,mg)
766SV* sv;
767MAGIC* mg;
768{
769 SV* lsv = LvTARG(sv);
770 SSize_t pos;
771 STRLEN len;
772
773 mg = 0;
774
775 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
776 mg = mg_find(lsv, 'g');
777 if (!mg) {
778 if (!SvOK(sv))
779 return 0;
780 sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
781 mg = mg_find(lsv, 'g');
782 }
783 else if (!SvOK(sv)) {
784 mg->mg_len = -1;
785 return 0;
786 }
787 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
788
789 pos = SvIV(sv) - curcop->cop_arybase;
790 if (pos < 0) {
791 pos += len;
792 if (pos < 0)
793 pos = 0;
794 }
795 else if (pos > len)
796 pos = len;
797 mg->mg_len = pos;
798
79072805
LW
799 return 0;
800}
801
802int
803magic_getglob(sv,mg)
804SV* sv;
805MAGIC* mg;
806{
807 gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
808 return 0;
809}
810
811int
812magic_setglob(sv,mg)
813SV* sv;
814MAGIC* mg;
815{
816 register char *s;
817 GV* gv;
818
819 if (!SvOK(sv))
820 return 0;
463ee0b2 821 s = SvPV(sv, na);
79072805
LW
822 if (*s == '*' && s[1])
823 s++;
85e6fe83 824 gv = gv_fetchpv(s,TRUE, SVt_PVGV);
79072805
LW
825 if (sv == (SV*)gv)
826 return 0;
827 if (GvGP(sv))
828 gp_free(sv);
829 GvGP(sv) = gp_ref(GvGP(gv));
830 if (!GvAV(gv))
831 gv_AVadd(gv);
832 if (!GvHV(gv))
833 gv_HVadd(gv);
a0d0e21e
LW
834 if (!GvIOp(gv))
835 GvIOp(gv) = newIO();
79072805
LW
836 return 0;
837}
838
839int
840magic_setsubstr(sv,mg)
841SV* sv;
842MAGIC* mg;
843{
8990e307
LW
844 STRLEN len;
845 char *tmps = SvPV(sv,len);
846 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
79072805
LW
847 return 0;
848}
849
850int
463ee0b2
LW
851magic_gettaint(sv,mg)
852SV* sv;
853MAGIC* mg;
854{
855 tainted = TRUE;
856 return 0;
857}
858
859int
860magic_settaint(sv,mg)
861SV* sv;
862MAGIC* mg;
863{
a0d0e21e
LW
864 if (!tainted) {
865 if (!SvMAGICAL(sv))
866 SvMAGICAL_on(sv);
463ee0b2 867 sv_unmagic(sv, 't');
a0d0e21e 868 }
463ee0b2
LW
869 return 0;
870}
871
872int
79072805
LW
873magic_setvec(sv,mg)
874SV* sv;
875MAGIC* mg;
876{
877 do_vecset(sv); /* XXX slurp this routine */
878 return 0;
879}
880
881int
93a17b20
LW
882magic_setmglob(sv,mg)
883SV* sv;
884MAGIC* mg;
885{
a0d0e21e 886 mg->mg_len = -1;
93a17b20
LW
887 return 0;
888}
889
890int
79072805
LW
891magic_setbm(sv,mg)
892SV* sv;
893MAGIC* mg;
894{
463ee0b2 895 sv_unmagic(sv, 'B');
79072805
LW
896 SvVALID_off(sv);
897 return 0;
898}
899
900int
901magic_setuvar(sv,mg)
902SV* sv;
903MAGIC* mg;
904{
905 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
906
907 if (uf && uf->uf_set)
908 (*uf->uf_set)(uf->uf_index, sv);
909 return 0;
910}
911
912int
913magic_set(sv,mg)
914SV* sv;
915MAGIC* mg;
916{
917 register char *s;
918 I32 i;
8990e307 919 STRLEN len;
79072805
LW
920 switch (*mg->mg_ptr) {
921 case '\004': /* ^D */
8990e307 922 debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
79072805
LW
923 DEBUG_x(dump_all());
924 break;
925 case '\006': /* ^F */
463ee0b2 926 maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 927 break;
a0d0e21e
LW
928 case '\010': /* ^H */
929 hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
930 break;
79072805
LW
931 case '\t': /* ^I */
932 if (inplace)
933 Safefree(inplace);
934 if (SvOK(sv))
a0d0e21e 935 inplace = savepv(SvPV(sv,na));
79072805
LW
936 else
937 inplace = Nullch;
938 break;
939 case '\020': /* ^P */
463ee0b2 940 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
941 if (i != perldb) {
942 if (perldb)
943 oldlastpm = curpm;
944 else
945 curpm = oldlastpm;
946 }
947 perldb = i;
948 break;
949 case '\024': /* ^T */
85e6fe83 950 basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
951 break;
952 case '\027': /* ^W */
463ee0b2 953 dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
954 break;
955 case '.':
956 if (localizing)
957 save_sptr((SV**)&last_in_gv);
2304df62 958 else if (SvOK(sv))
a0d0e21e 959 IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
79072805
LW
960 break;
961 case '^':
a0d0e21e
LW
962 Safefree(IoTOP_NAME(GvIOp(defoutgv)));
963 IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
964 IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
965 break;
966 case '~':
a0d0e21e
LW
967 Safefree(IoFMT_NAME(GvIOp(defoutgv)));
968 IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
969 IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
970 break;
971 case '=':
a0d0e21e 972 IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
973 break;
974 case '-':
a0d0e21e
LW
975 IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
976 if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
977 IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
79072805
LW
978 break;
979 case '%':
a0d0e21e 980 IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
981 break;
982 case '|':
a0d0e21e 983 IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
463ee0b2 984 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
a0d0e21e 985 IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
79072805
LW
986 }
987 break;
988 case '*':
463ee0b2 989 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
990 multiline = (i != 0);
991 break;
992 case '/':
a0d0e21e
LW
993 if (SvOK(sv)) {
994 nrs = rs = SvPV_force(sv,rslen);
8990e307 995 nrslen = rslen;
79072805 996 if (rspara = !rslen) {
93a17b20
LW
997 nrs = rs = "\n\n";
998 nrslen = rslen = 2;
79072805 999 }
93a17b20 1000 nrschar = rschar = rs[rslen - 1];
79072805
LW
1001 }
1002 else {
93a17b20
LW
1003 nrschar = rschar = 0777; /* fake a non-existent char */
1004 nrslen = rslen = 1;
79072805
LW
1005 }
1006 break;
1007 case '\\':
1008 if (ors)
1009 Safefree(ors);
a0d0e21e 1010 ors = savepv(SvPV(sv,orslen));
79072805
LW
1011 break;
1012 case ',':
1013 if (ofs)
1014 Safefree(ofs);
a0d0e21e 1015 ofs = savepv(SvPV(sv, ofslen));
79072805
LW
1016 break;
1017 case '#':
1018 if (ofmt)
1019 Safefree(ofmt);
a0d0e21e 1020 ofmt = savepv(SvPV(sv,na));
79072805
LW
1021 break;
1022 case '[':
a0d0e21e 1023 compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1024 break;
1025 case '?':
463ee0b2 1026 statusvalue = U_S(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1027 break;
1028 case '!':
463ee0b2 1029 errno = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); /* will anyone ever use this? */
79072805
LW
1030 break;
1031 case '<':
463ee0b2 1032 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1033 if (delaymagic) {
1034 delaymagic |= DM_RUID;
1035 break; /* don't do magic till later */
1036 }
1037#ifdef HAS_SETRUID
85e6fe83 1038 (void)setruid((Uid_t)uid);
79072805
LW
1039#else
1040#ifdef HAS_SETREUID
85e6fe83
LW
1041 (void)setreuid((Uid_t)uid, (Uid_t)-1);
1042#ifdef HAS_SETRESUID
1043 (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
79072805
LW
1044#else
1045 if (uid == euid) /* special case $< = $> */
1046 (void)setuid(uid);
a0d0e21e
LW
1047 else {
1048 uid = (I32)getuid();
463ee0b2 1049 croak("setruid() not implemented");
a0d0e21e 1050 }
79072805
LW
1051#endif
1052#endif
85e6fe83 1053#endif
463ee0b2
LW
1054 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1055 tainting |= (euid != uid || egid != gid);
79072805
LW
1056 break;
1057 case '>':
463ee0b2 1058 euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1059 if (delaymagic) {
1060 delaymagic |= DM_EUID;
1061 break; /* don't do magic till later */
1062 }
1063#ifdef HAS_SETEUID
85e6fe83 1064 (void)seteuid((Uid_t)euid);
79072805
LW
1065#else
1066#ifdef HAS_SETREUID
85e6fe83
LW
1067 (void)setreuid((Uid_t)-1, (Uid_t)euid);
1068#else
1069#ifdef HAS_SETRESUID
1070 (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
79072805
LW
1071#else
1072 if (euid == uid) /* special case $> = $< */
1073 setuid(euid);
a0d0e21e
LW
1074 else {
1075 euid = (I32)geteuid();
463ee0b2 1076 croak("seteuid() not implemented");
a0d0e21e 1077 }
79072805
LW
1078#endif
1079#endif
85e6fe83 1080#endif
79072805 1081 euid = (I32)geteuid();
463ee0b2 1082 tainting |= (euid != uid || egid != gid);
79072805
LW
1083 break;
1084 case '(':
463ee0b2 1085 gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1086 if (delaymagic) {
1087 delaymagic |= DM_RGID;
1088 break; /* don't do magic till later */
1089 }
1090#ifdef HAS_SETRGID
85e6fe83 1091 (void)setrgid((Gid_t)gid);
79072805
LW
1092#else
1093#ifdef HAS_SETREGID
85e6fe83
LW
1094 (void)setregid((Gid_t)gid, (Gid_t)-1);
1095#else
1096#ifdef HAS_SETRESGID
1097 (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
79072805
LW
1098#else
1099 if (gid == egid) /* special case $( = $) */
1100 (void)setgid(gid);
1101 else
463ee0b2 1102 croak("setrgid() not implemented");
79072805
LW
1103#endif
1104#endif
85e6fe83 1105#endif
79072805 1106 gid = (I32)getgid();
463ee0b2 1107 tainting |= (euid != uid || egid != gid);
79072805
LW
1108 break;
1109 case ')':
463ee0b2 1110 egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1111 if (delaymagic) {
1112 delaymagic |= DM_EGID;
1113 break; /* don't do magic till later */
1114 }
1115#ifdef HAS_SETEGID
85e6fe83 1116 (void)setegid((Gid_t)egid);
79072805
LW
1117#else
1118#ifdef HAS_SETREGID
85e6fe83
LW
1119 (void)setregid((Gid_t)-1, (Gid_t)egid);
1120#else
1121#ifdef HAS_SETRESGID
1122 (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
79072805
LW
1123#else
1124 if (egid == gid) /* special case $) = $( */
1125 (void)setgid(egid);
1126 else
463ee0b2 1127 croak("setegid() not implemented");
79072805
LW
1128#endif
1129#endif
85e6fe83 1130#endif
79072805 1131 egid = (I32)getegid();
463ee0b2 1132 tainting |= (euid != uid || egid != gid);
79072805
LW
1133 break;
1134 case ':':
a0d0e21e 1135 chopset = SvPV_force(sv,na);
79072805
LW
1136 break;
1137 case '0':
1138 if (!origalen) {
1139 s = origargv[0];
1140 s += strlen(s);
1141 /* See if all the arguments are contiguous in memory */
1142 for (i = 1; i < origargc; i++) {
1143 if (origargv[i] == s + 1)
1144 s += strlen(++s); /* this one is ok too */
1145 }
1146 if (origenviron[0] == s + 1) { /* can grab env area too? */
1147 my_setenv("NoNeSuCh", Nullch);
1148 /* force copy of environment */
1149 for (i = 0; origenviron[i]; i++)
1150 if (origenviron[i] == s + 1)
1151 s += strlen(++s);
1152 }
1153 origalen = s - origargv[0];
1154 }
a0d0e21e 1155 s = SvPV_force(sv,len);
8990e307 1156 i = len;
79072805
LW
1157 if (i >= origalen) {
1158 i = origalen;
1159 SvCUR_set(sv, i);
1160 *SvEND(sv) = '\0';
1161 Copy(s, origargv[0], i, char);
1162 }
1163 else {
1164 Copy(s, origargv[0], i, char);
1165 s = origargv[0]+i;
1166 *s++ = '\0';
1167 while (++i < origalen)
8990e307
LW
1168 *s++ = ' ';
1169 s = origargv[0]+i;
ed6116ce 1170 for (i = 1; i < origargc; i++)
8990e307 1171 origargv[i] = Nullch;
79072805
LW
1172 }
1173 break;
1174 }
1175 return 0;
1176}
1177
1178I32
1179whichsig(sig)
1180char *sig;
1181{
1182 register char **sigv;
1183
1184 for (sigv = sig_name+1; *sigv; sigv++)
1185 if (strEQ(sig,*sigv))
1186 return sigv - sig_name;
1187#ifdef SIGCLD
1188 if (strEQ(sig,"CHLD"))
1189 return SIGCLD;
1190#endif
1191#ifdef SIGCHLD
1192 if (strEQ(sig,"CLD"))
1193 return SIGCHLD;
1194#endif
1195 return 0;
1196}
1197
ecfc5424 1198Signal_t
79072805 1199sighandler(sig)
a0d0e21e 1200int sig;
79072805
LW
1201{
1202 dSP;
1203 GV *gv;
a0d0e21e 1204 HV *st;
79072805
LW
1205 SV *sv;
1206 CV *cv;
79072805 1207 AV *oldstack;
79072805
LW
1208
1209#ifdef OS2 /* or anybody else who requires SIG_ACK */
1210 signal(sig, SIG_ACK);
1211#endif
1212
a0d0e21e
LW
1213 cv = sv_2cv(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
1214 TRUE),
1215 &st, &gv, TRUE);
1216 if (!cv || !CvROOT(cv) &&
1217 *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
1218
79072805 1219 if (sig_name[sig][1] == 'H')
a0d0e21e
LW
1220 cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
1221 &st, &gv, TRUE);
79072805 1222 else
a0d0e21e
LW
1223 cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE),
1224 &st, &gv, TRUE);
1225 /* gag */
79072805 1226 }
a0d0e21e 1227 if (!cv || !CvROOT(cv)) {
79072805
LW
1228 if (dowarn)
1229 warn("SIG%s handler \"%s\" not defined.\n",
1230 sig_name[sig], GvENAME(gv) );
1231 return;
1232 }
1233
1234 oldstack = stack;
a0d0e21e
LW
1235 if (stack != signalstack)
1236 AvFILL(signalstack) = 0;
79072805
LW
1237 SWITCHSTACK(stack, signalstack);
1238
8990e307 1239 sv = sv_newmortal();
79072805 1240 sv_setpv(sv,sig_name[sig]);
a0d0e21e 1241 PUSHMARK(sp);
79072805 1242 PUSHs(sv);
79072805 1243 PUTBACK;
a0d0e21e
LW
1244
1245 perl_call_sv((SV*)cv, G_DISCARD);
79072805
LW
1246
1247 SWITCHSTACK(signalstack, oldstack);
79072805
LW
1248
1249 return;
1250}