All args in embed.fnc should be named
[p5sagit/p5-mst-13.2.git] / mg.c
CommitLineData
a0d0e21e 1/* mg.c
79072805 2 *
4bb101f2 3 * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
cbdf9ef8 4 * 2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and others
79072805 5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
a0d0e21e 9 */
10
11/*
12 * "Sam sat on the ground and put his head in his hands. 'I wish I had never
13 * come here, and I don't want to see no more magic,' he said, and fell silent."
79072805 14 */
15
ccfc67b7 16/*
17=head1 Magical Functions
166f8a29 18
19"Magic" is special data attached to SV structures in order to give them
20"magical" properties. When any Perl code tries to read from, or assign to,
21an SV marked as magical, it calls the 'get' or 'set' function associated
22with that SV's magic. A get is called prior to reading an SV, in order to
ddfa107c 23give it a chance to update its internal value (get on $. writes the line
166f8a29 24number of the last read filehandle into to the SV's IV slot), while
25set is called after an SV has been written to, in order to allow it to make
ddfa107c 26use of its changed value (set on $/ copies the SV's new value to the
166f8a29 27PL_rs global variable).
28
29Magic is implemented as a linked list of MAGIC structures attached to the
30SV. Each MAGIC struct holds the type of the magic, a pointer to an array
31of functions that implement the get(), set(), length() etc functions,
32plus space for some flags and pointers. For example, a tied variable has
33a MAGIC structure that contains a pointer to the object associated with the
34tie.
35
ccfc67b7 36*/
37
79072805 38#include "EXTERN.h"
864dbfa3 39#define PERL_IN_MG_C
79072805 40#include "perl.h"
41
5cd24f17 42#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
188ea221 43# ifndef NGROUPS
44# define NGROUPS 32
45# endif
b7953727 46# ifdef I_GRP
47# include <grp.h>
48# endif
188ea221 49#endif
50
17aa7f3d 51#ifdef __hpux
52# include <sys/pstat.h>
53#endif
54
8aad04aa 55#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
56Signal_t Perl_csighandler(int sig, ...);
57#else
e69880a5 58Signal_t Perl_csighandler(int sig);
8aad04aa 59#endif
e69880a5 60
9cffb111 61#ifdef __Lynx__
62/* Missing protos on LynxOS */
63void setruid(uid_t id);
64void seteuid(uid_t id);
65void setrgid(uid_t id);
66void setegid(uid_t id);
67#endif
68
c07a80fd 69/*
70 * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
71 */
72
73struct magic_state {
74 SV* mgs_sv;
75 U32 mgs_flags;
455ece5e 76 I32 mgs_ss_ix;
c07a80fd 77};
455ece5e 78/* MGS is typedef'ed to struct magic_state in perl.h */
76e3520e 79
80STATIC void
8fb26106 81S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
c07a80fd 82{
455ece5e 83 MGS* mgs;
c07a80fd 84 assert(SvMAGICAL(sv));
f8c7b90f 85#ifdef PERL_OLD_COPY_ON_WRITE
765f542d 86 /* Turning READONLY off for a copy-on-write scalar is a bad idea. */
87 if (SvIsCOW(sv))
9a265e59 88 sv_force_normal_flags(sv, 0);
765f542d 89#endif
c07a80fd 90
8772537c 91 SAVEDESTRUCTOR_X(S_restore_magic, INT2PTR(void*, (IV)mgs_ix));
455ece5e 92
93 mgs = SSPTR(mgs_ix, MGS*);
c07a80fd 94 mgs->mgs_sv = sv;
95 mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
455ece5e 96 mgs->mgs_ss_ix = PL_savestack_ix; /* points after the saved destructor */
c07a80fd 97
98 SvMAGICAL_off(sv);
99 SvREADONLY_off(sv);
06759ea0 100 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_NOK|SVp_POK)) >> PRIVSHIFT;
c07a80fd 101}
102
954c1994 103/*
104=for apidoc mg_magical
105
106Turns on the magical status of an SV. See C<sv_magic>.
107
108=cut
109*/
110
8990e307 111void
864dbfa3 112Perl_mg_magical(pTHX_ SV *sv)
8990e307 113{
e1ec3a88 114 const MAGIC* mg;
8990e307 115 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
35a4481c 116 const MGVTBL* const vtbl = mg->mg_virtual;
8990e307 117 if (vtbl) {
2b260de0 118 if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
8990e307 119 SvGMAGICAL_on(sv);
120 if (vtbl->svt_set)
121 SvSMAGICAL_on(sv);
2b260de0 122 if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
8990e307 123 SvRMAGICAL_on(sv);
124 }
125 }
126}
127
954c1994 128/*
129=for apidoc mg_get
130
131Do magic after a value is retrieved from the SV. See C<sv_magic>.
132
133=cut
134*/
135
79072805 136int
864dbfa3 137Perl_mg_get(pTHX_ SV *sv)
79072805 138{
35a4481c 139 const I32 mgs_ix = SSNEW(sizeof(MGS));
fe2774ed 140 const bool was_temp = (bool)SvTEMP(sv);
0723351e 141 int have_new = 0;
ff76feab 142 MAGIC *newmg, *head, *cur, *mg;
20135930 143 /* guard against sv having being freed midway by holding a private
6683b158 144 reference. */
145
146 /* sv_2mortal has this side effect of turning on the TEMP flag, which can
147 cause the SV's buffer to get stolen (and maybe other stuff).
148 So restore it.
149 */
150 sv_2mortal(SvREFCNT_inc(sv));
151 if (!was_temp) {
152 SvTEMP_off(sv);
153 }
154
455ece5e 155 save_magic(mgs_ix, sv);
463ee0b2 156
ff76feab 157 /* We must call svt_get(sv, mg) for each valid entry in the linked
158 list of magic. svt_get() may delete the current entry, add new
159 magic to the head of the list, or upgrade the SV. AMS 20010810 */
160
161 newmg = cur = head = mg = SvMAGIC(sv);
162 while (mg) {
35a4481c 163 const MGVTBL * const vtbl = mg->mg_virtual;
ff76feab 164
2b260de0 165 if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
316ad4fe 166 CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
b77f7d40 167
58f82c5c 168 /* guard against magic having been deleted - eg FETCH calling
169 * untie */
170 if (!SvMAGIC(sv))
171 break;
b77f7d40 172
ff76feab 173 /* Don't restore the flags for this entry if it was deleted. */
174 if (mg->mg_flags & MGf_GSKIP)
175 (SSPTR(mgs_ix, MGS *))->mgs_flags = 0;
a0d0e21e 176 }
ff76feab 177
178 mg = mg->mg_moremagic;
179
0723351e 180 if (have_new) {
ff76feab 181 /* Have we finished with the new entries we saw? Start again
182 where we left off (unless there are more new entries). */
183 if (mg == head) {
0723351e 184 have_new = 0;
ff76feab 185 mg = cur;
186 head = newmg;
187 }
188 }
189
190 /* Were any new entries added? */
0723351e 191 if (!have_new && (newmg = SvMAGIC(sv)) != head) {
192 have_new = 1;
ff76feab 193 cur = mg;
194 mg = newmg;
760ac839 195 }
79072805 196 }
463ee0b2 197
8772537c 198 restore_magic(INT2PTR(void *, (IV)mgs_ix));
6683b158 199
200 if (SvREFCNT(sv) == 1) {
201 /* We hold the last reference to this SV, which implies that the
202 SV was deleted as a side effect of the routines we called. */
0c34ef67 203 SvOK_off(sv);
6683b158 204 }
79072805 205 return 0;
206}
207
954c1994 208/*
209=for apidoc mg_set
210
211Do magic after a value is assigned to the SV. See C<sv_magic>.
212
213=cut
214*/
215
79072805 216int
864dbfa3 217Perl_mg_set(pTHX_ SV *sv)
79072805 218{
35a4481c 219 const I32 mgs_ix = SSNEW(sizeof(MGS));
79072805 220 MAGIC* mg;
463ee0b2 221 MAGIC* nextmg;
222
455ece5e 223 save_magic(mgs_ix, sv);
463ee0b2 224
225 for (mg = SvMAGIC(sv); mg; mg = nextmg) {
e1ec3a88 226 const MGVTBL* vtbl = mg->mg_virtual;
463ee0b2 227 nextmg = mg->mg_moremagic; /* it may delete itself */
a0d0e21e 228 if (mg->mg_flags & MGf_GSKIP) {
229 mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
455ece5e 230 (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
a0d0e21e 231 }
2b260de0 232 if (vtbl && vtbl->svt_set)
fc0dc3b3 233 CALL_FPTR(vtbl->svt_set)(aTHX_ sv, mg);
79072805 234 }
463ee0b2 235
8772537c 236 restore_magic(INT2PTR(void*, (IV)mgs_ix));
79072805 237 return 0;
238}
239
954c1994 240/*
241=for apidoc mg_length
242
243Report on the SV's length. See C<sv_magic>.
244
245=cut
246*/
247
79072805 248U32
864dbfa3 249Perl_mg_length(pTHX_ SV *sv)
79072805 250{
251 MAGIC* mg;
463ee0b2 252 STRLEN len;
463ee0b2 253
79072805 254 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
35a4481c 255 const MGVTBL * const vtbl = mg->mg_virtual;
2b260de0 256 if (vtbl && vtbl->svt_len) {
35a4481c 257 const I32 mgs_ix = SSNEW(sizeof(MGS));
455ece5e 258 save_magic(mgs_ix, sv);
a0d0e21e 259 /* omit MGf_GSKIP -- not changed here */
fc0dc3b3 260 len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
8772537c 261 restore_magic(INT2PTR(void*, (IV)mgs_ix));
85e6fe83 262 return len;
263 }
264 }
265
35a4481c 266 if (DO_UTF8(sv)) {
10516c54 267 const U8 *s = (U8*)SvPV_const(sv, len);
5636d518 268 len = Perl_utf8_length(aTHX_ s, s + len);
269 }
270 else
10516c54 271 (void)SvPV_const(sv, len);
463ee0b2 272 return len;
79072805 273}
274
8fb26106 275I32
864dbfa3 276Perl_mg_size(pTHX_ SV *sv)
93965878 277{
278 MAGIC* mg;
ac27b0f5 279
93965878 280 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
35a4481c 281 const MGVTBL* const vtbl = mg->mg_virtual;
2b260de0 282 if (vtbl && vtbl->svt_len) {
35a4481c 283 const I32 mgs_ix = SSNEW(sizeof(MGS));
284 I32 len;
455ece5e 285 save_magic(mgs_ix, sv);
93965878 286 /* omit MGf_GSKIP -- not changed here */
fc0dc3b3 287 len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
8772537c 288 restore_magic(INT2PTR(void*, (IV)mgs_ix));
93965878 289 return len;
290 }
291 }
292
293 switch(SvTYPE(sv)) {
294 case SVt_PVAV:
35a4481c 295 return AvFILLp((AV *) sv); /* Fallback to non-tied array */
93965878 296 case SVt_PVHV:
297 /* FIXME */
298 default:
cea2e8a9 299 Perl_croak(aTHX_ "Size magic not implemented");
93965878 300 break;
301 }
302 return 0;
303}
304
954c1994 305/*
306=for apidoc mg_clear
307
308Clear something magical that the SV represents. See C<sv_magic>.
309
310=cut
311*/
312
79072805 313int
864dbfa3 314Perl_mg_clear(pTHX_ SV *sv)
79072805 315{
35a4481c 316 const I32 mgs_ix = SSNEW(sizeof(MGS));
79072805 317 MAGIC* mg;
463ee0b2 318
455ece5e 319 save_magic(mgs_ix, sv);
463ee0b2 320
79072805 321 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
35a4481c 322 const MGVTBL* const vtbl = mg->mg_virtual;
a0d0e21e 323 /* omit GSKIP -- never set here */
727405f8 324
2b260de0 325 if (vtbl && vtbl->svt_clear)
fc0dc3b3 326 CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
79072805 327 }
463ee0b2 328
8772537c 329 restore_magic(INT2PTR(void*, (IV)mgs_ix));
79072805 330 return 0;
331}
332
954c1994 333/*
334=for apidoc mg_find
335
336Finds the magic pointer for type matching the SV. See C<sv_magic>.
337
338=cut
339*/
340
93a17b20 341MAGIC*
35a4481c 342Perl_mg_find(pTHX_ const SV *sv, int type)
93a17b20 343{
35a4481c 344 if (sv) {
345 MAGIC *mg;
346 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
347 if (mg->mg_type == type)
348 return mg;
349 }
93a17b20 350 }
351 return 0;
352}
353
954c1994 354/*
355=for apidoc mg_copy
356
357Copies the magic from one SV to another. See C<sv_magic>.
358
359=cut
360*/
361
79072805 362int
864dbfa3 363Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
79072805 364{
463ee0b2 365 int count = 0;
79072805 366 MAGIC* mg;
463ee0b2 367 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
35a4481c 368 const MGVTBL* const vtbl = mg->mg_virtual;
68795e93 369 if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy){
370 count += CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv, key, klen);
371 }
823a54a3 372 else {
373 const char type = mg->mg_type;
374 if (isUPPER(type)) {
375 sv_magic(nsv,
376 (type == PERL_MAGIC_tied)
377 ? SvTIED_obj(sv, mg)
378 : (type == PERL_MAGIC_regdata && mg->mg_obj)
379 ? sv
380 : mg->mg_obj,
381 toLOWER(type), key, klen);
382 count++;
383 }
79072805 384 }
79072805 385 }
463ee0b2 386 return count;
79072805 387}
388
954c1994 389/*
0cbee0a4 390=for apidoc mg_localize
391
392Copy some of the magic from an existing SV to new localized version of
393that SV. Container magic (eg %ENV, $1, tie) gets copied, value magic
394doesn't (eg taint, pos).
395
396=cut
397*/
398
399void
400Perl_mg_localize(pTHX_ SV *sv, SV *nsv)
401{
402 MAGIC *mg;
403 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
404 const MGVTBL* const vtbl = mg->mg_virtual;
405 switch (mg->mg_type) {
406 /* value magic types: don't copy */
407 case PERL_MAGIC_bm:
408 case PERL_MAGIC_fm:
409 case PERL_MAGIC_regex_global:
410 case PERL_MAGIC_nkeys:
411#ifdef USE_LOCALE_COLLATE
412 case PERL_MAGIC_collxfrm:
413#endif
414 case PERL_MAGIC_qr:
415 case PERL_MAGIC_taint:
416 case PERL_MAGIC_vec:
417 case PERL_MAGIC_vstring:
418 case PERL_MAGIC_utf8:
419 case PERL_MAGIC_substr:
420 case PERL_MAGIC_defelem:
421 case PERL_MAGIC_arylen:
422 case PERL_MAGIC_pos:
423 case PERL_MAGIC_backref:
424 case PERL_MAGIC_arylen_p:
425 case PERL_MAGIC_rhash:
426 case PERL_MAGIC_symtab:
427 continue;
428 }
429
430 if ((mg->mg_flags & MGf_COPY) && vtbl->svt_copy) {
431 /* XXX calling the copy method is probably not correct. DAPM */
432 (void)CALL_FPTR(vtbl->svt_copy)(aTHX_ sv, mg, nsv,
433 mg->mg_ptr, mg->mg_len);
434 }
435 else {
436 sv_magicext(nsv, mg->mg_obj, mg->mg_type, vtbl,
437 mg->mg_ptr, mg->mg_len);
438 }
439 /* container types should remain read-only across localization */
440 SvFLAGS(nsv) |= SvREADONLY(sv);
441 }
442
443 if (SvTYPE(nsv) >= SVt_PVMG && SvMAGIC(nsv)) {
444 SvFLAGS(nsv) |= SvMAGICAL(sv);
445 PL_localizing = 1;
446 SvSETMAGIC(nsv);
447 PL_localizing = 0;
448 }
449}
450
451/*
954c1994 452=for apidoc mg_free
453
454Free any magic storage used by the SV. See C<sv_magic>.
455
456=cut
457*/
458
79072805 459int
864dbfa3 460Perl_mg_free(pTHX_ SV *sv)
79072805 461{
462 MAGIC* mg;
463 MAGIC* moremagic;
464 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
35a4481c 465 const MGVTBL* const vtbl = mg->mg_virtual;
79072805 466 moremagic = mg->mg_moremagic;
2b260de0 467 if (vtbl && vtbl->svt_free)
fc0dc3b3 468 CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
14befaf4 469 if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
979acdb5 470 if (mg->mg_len > 0 || mg->mg_type == PERL_MAGIC_utf8)
88e89b8a 471 Safefree(mg->mg_ptr);
565764a8 472 else if (mg->mg_len == HEf_SVKEY)
88e89b8a 473 SvREFCNT_dec((SV*)mg->mg_ptr);
d460ef45 474 }
b881518d 475 if (mg->mg_flags & MGf_REFCOUNTED)
476 SvREFCNT_dec(mg->mg_obj);
79072805 477 Safefree(mg);
478 }
b162af07 479 SvMAGIC_set(sv, NULL);
79072805 480 return 0;
481}
482
79072805 483#include <signal.h>
79072805 484
942e002e 485U32
864dbfa3 486Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
6cef1e77 487{
8772537c 488 PERL_UNUSED_ARG(sv);
6cef1e77 489
0bd48802 490 if (PL_curpm) {
491 register const REGEXP * const rx = PM_GETRE(PL_curpm);
492 if (rx) {
493 return mg->mg_obj
494 ? rx->nparens /* @+ */
495 : rx->lastparen; /* @- */
496 }
8f580fb8 497 }
ac27b0f5 498
942e002e 499 return (U32)-1;
6cef1e77 500}
501
502int
864dbfa3 503Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
6cef1e77 504{
0bd48802 505 if (PL_curpm) {
506 register const REGEXP * const rx = PM_GETRE(PL_curpm);
507 if (rx) {
508 register const I32 paren = mg->mg_len;
509 register I32 s;
510 register I32 t;
511 if (paren < 0)
512 return 0;
513 if (paren <= (I32)rx->nparens &&
514 (s = rx->startp[paren]) != -1 &&
515 (t = rx->endp[paren]) != -1)
516 {
517 register I32 i;
518 if (mg->mg_obj) /* @+ */
519 i = t;
520 else /* @- */
521 i = s;
522
523 if (i > 0 && RX_MATCH_UTF8(rx)) {
524 const char * const b = rx->subbeg;
525 if (b)
526 i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i));
527 }
727405f8 528
0bd48802 529 sv_setiv(sv, i);
1aa99e6b 530 }
0bd48802 531 }
6cef1e77 532 }
533 return 0;
534}
535
e4b89193 536int
a29d06ed 537Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
538{
8772537c 539 PERL_UNUSED_ARG(sv); PERL_UNUSED_ARG(mg);
a29d06ed 540 Perl_croak(aTHX_ PL_no_modify);
0dbb1585 541 NORETURN_FUNCTION_END;
a29d06ed 542}
543
93a17b20 544U32
864dbfa3 545Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
93a17b20 546{
547 register I32 paren;
93a17b20 548 register I32 i;
dd374669 549 register const REGEXP *rx;
a197cbdd 550 I32 s1, t1;
93a17b20 551
552 switch (*mg->mg_ptr) {
553 case '1': case '2': case '3': case '4':
554 case '5': case '6': case '7': case '8': case '9': case '&':
aaa362c4 555 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 556
ffc61ed2 557 paren = atoi(mg->mg_ptr); /* $& is in [0] */
93a17b20 558 getparen:
eb160463 559 if (paren <= (I32)rx->nparens &&
cf93c79d 560 (s1 = rx->startp[paren]) != -1 &&
561 (t1 = rx->endp[paren]) != -1)
bbce6d69 562 {
cf93c79d 563 i = t1 - s1;
a197cbdd 564 getlen:
a30b2f1f 565 if (i > 0 && RX_MATCH_UTF8(rx)) {
a28509cc 566 const char * const s = rx->subbeg + s1;
768c67ee 567 const U8 *ep;
568 STRLEN el;
ffc61ed2 569
6d5fa195 570 i = t1 - s1;
768c67ee 571 if (is_utf8_string_loclen((U8*)s, i, &ep, &el))
572 i = el;
a197cbdd 573 }
ffc61ed2 574 if (i < 0)
0844c848 575 Perl_croak(aTHX_ "panic: magic_len: %"IVdf, (IV)i);
ffc61ed2 576 return i;
93a17b20 577 }
235bddc8 578 else {
579 if (ckWARN(WARN_UNINITIALIZED))
29489e7c 580 report_uninit(sv);
235bddc8 581 }
582 }
583 else {
584 if (ckWARN(WARN_UNINITIALIZED))
29489e7c 585 report_uninit(sv);
93a17b20 586 }
748a9306 587 return 0;
93a17b20 588 case '+':
aaa362c4 589 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
d9f97599 590 paren = rx->lastparen;
13f57bf8 591 if (paren)
592 goto getparen;
93a17b20 593 }
748a9306 594 return 0;
a01268b5 595 case '\016': /* ^N */
596 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
597 paren = rx->lastcloseparen;
598 if (paren)
599 goto getparen;
600 }
601 return 0;
93a17b20 602 case '`':
aaa362c4 603 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 604 if (rx->startp[0] != -1) {
605 i = rx->startp[0];
a197cbdd 606 if (i > 0) {
607 s1 = 0;
608 t1 = i;
609 goto getlen;
610 }
93a17b20 611 }
93a17b20 612 }
748a9306 613 return 0;
93a17b20 614 case '\'':
aaa362c4 615 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 616 if (rx->endp[0] != -1) {
617 i = rx->sublen - rx->endp[0];
a197cbdd 618 if (i > 0) {
619 s1 = rx->endp[0];
620 t1 = rx->sublen;
621 goto getlen;
622 }
93a17b20 623 }
93a17b20 624 }
748a9306 625 return 0;
93a17b20 626 }
627 magic_get(sv,mg);
2d8e6c8d 628 if (!SvPOK(sv) && SvNIOK(sv)) {
8b6b16e7 629 sv_2pv(sv, 0);
2d8e6c8d 630 }
93a17b20 631 if (SvPOK(sv))
632 return SvCUR(sv);
633 return 0;
634}
635
ad3296c6 636#define SvRTRIM(sv) STMT_START { \
637 STRLEN len = SvCUR(sv); \
638 while (len > 0 && isSPACE(SvPVX(sv)[len-1])) \
639 --len; \
640 SvCUR_set(sv, len); \
641} STMT_END
642
79072805 643int
864dbfa3 644Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
79072805 645{
27da23d5 646 dVAR;
79072805 647 register I32 paren;
35272f84 648 register char *s = NULL;
79072805 649 register I32 i;
d9f97599 650 register REGEXP *rx;
823a54a3 651 const char * const remaining = mg->mg_ptr + 1;
652 const char nextchar = *remaining;
79072805 653
654 switch (*mg->mg_ptr) {
748a9306 655 case '\001': /* ^A */
3280af22 656 sv_setsv(sv, PL_bodytarget);
748a9306 657 break;
e5218da5 658 case '\003': /* ^C, ^CHILD_ERROR_NATIVE */
823a54a3 659 if (nextchar == '\0') {
e5218da5 660 sv_setiv(sv, (IV)PL_minus_c);
661 }
823a54a3 662 else if (strEQ(remaining, "HILD_ERROR_NATIVE")) {
e5218da5 663 sv_setiv(sv, (IV)STATUS_NATIVE);
664 }
49460fe6 665 break;
666
79072805 667 case '\004': /* ^D */
aea4f609 668 sv_setiv(sv, (IV)(PL_debug & DEBUG_MASK));
79072805 669 break;
28f23441 670 case '\005': /* ^E */
823a54a3 671 if (nextchar == '\0') {
cd39f2b6 672#ifdef MACOS_TRADITIONAL
0a378802 673 {
674 char msg[256];
727405f8 675
0a378802 676 sv_setnv(sv,(double)gMacPerl_OSErr);
727405f8 677 sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : "");
0a378802 678 }
727405f8 679#else
28f23441 680#ifdef VMS
0a378802 681 {
682# include <descrip.h>
683# include <starlet.h>
684 char msg[255];
685 $DESCRIPTOR(msgdsc,msg);
686 sv_setnv(sv,(NV) vaxc$errno);
687 if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
688 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
689 else
c69006e4 690 sv_setpvn(sv,"",0);
0a378802 691 }
28f23441 692#else
88e89b8a 693#ifdef OS2
0a378802 694 if (!(_emx_env & 0x200)) { /* Under DOS */
695 sv_setnv(sv, (NV)errno);
696 sv_setpv(sv, errno ? Strerror(errno) : "");
697 } else {
698 if (errno != errno_isOS2) {
823a54a3 699 const int tmp = _syserrno();
0a378802 700 if (tmp) /* 2nd call to _syserrno() makes it 0 */
701 Perl_rc = tmp;
702 }
703 sv_setnv(sv, (NV)Perl_rc);
704 sv_setpv(sv, os2error(Perl_rc));
705 }
88e89b8a 706#else
22fae026 707#ifdef WIN32
0a378802 708 {
709 DWORD dwErr = GetLastError();
710 sv_setnv(sv, (NV)dwErr);
823a54a3 711 if (dwErr) {
0a378802 712 PerlProc_GetOSError(sv, dwErr);
713 }
714 else
c69006e4 715 sv_setpvn(sv, "", 0);
0a378802 716 SetLastError(dwErr);
717 }
22fae026 718#else
f6c8f21d 719 {
8772537c 720 const int saveerrno = errno;
f6c8f21d 721 sv_setnv(sv, (NV)errno);
722 sv_setpv(sv, errno ? Strerror(errno) : "");
723 errno = saveerrno;
724 }
28f23441 725#endif
88e89b8a 726#endif
22fae026 727#endif
cd39f2b6 728#endif
ad3296c6 729 SvRTRIM(sv);
0a378802 730 SvNOK_on(sv); /* what a wonderful hack! */
731 }
823a54a3 732 else if (strEQ(remaining, "NCODING"))
0a378802 733 sv_setsv(sv, PL_encoding);
734 break;
79072805 735 case '\006': /* ^F */
3280af22 736 sv_setiv(sv, (IV)PL_maxsysfd);
79072805 737 break;
a0d0e21e 738 case '\010': /* ^H */
3280af22 739 sv_setiv(sv, (IV)PL_hints);
a0d0e21e 740 break;
9d116dd7 741 case '\011': /* ^I */ /* NOT \t in EBCDIC */
3280af22 742 if (PL_inplace)
743 sv_setpv(sv, PL_inplace);
79072805 744 else
3280af22 745 sv_setsv(sv, &PL_sv_undef);
79072805 746 break;
ac27b0f5 747 case '\017': /* ^O & ^OPEN */
823a54a3 748 if (nextchar == '\0') {
ac27b0f5 749 sv_setpv(sv, PL_osname);
3511154c 750 SvTAINTED_off(sv);
751 }
823a54a3 752 else if (strEQ(remaining, "PEN")) {
ac27b0f5 753 if (!PL_compiling.cop_io)
754 sv_setsv(sv, &PL_sv_undef);
755 else {
756 sv_setsv(sv, PL_compiling.cop_io);
757 }
758 }
28f23441 759 break;
79072805 760 case '\020': /* ^P */
3280af22 761 sv_setiv(sv, (IV)PL_perldb);
79072805 762 break;
fb73857a 763 case '\023': /* ^S */
823a54a3 764 if (nextchar == '\0') {
3280af22 765 if (PL_lex_state != LEX_NOTPARSING)
0c34ef67 766 SvOK_off(sv);
3280af22 767 else if (PL_in_eval)
6dc8a9e4 768 sv_setiv(sv, PL_in_eval & ~(EVAL_INREQUIRE));
a4268c0a 769 else
770 sv_setiv(sv, 0);
d58bf5aa 771 }
fb73857a 772 break;
79072805 773 case '\024': /* ^T */
823a54a3 774 if (nextchar == '\0') {
88e89b8a 775#ifdef BIG_TIME
7c36658b 776 sv_setnv(sv, PL_basetime);
88e89b8a 777#else
7c36658b 778 sv_setiv(sv, (IV)PL_basetime);
88e89b8a 779#endif
7c36658b 780 }
823a54a3 781 else if (strEQ(remaining, "AINT"))
9aa05f58 782 sv_setiv(sv, PL_tainting
783 ? (PL_taint_warn || PL_unsafe ? -1 : 1)
784 : 0);
7c36658b 785 break;
7cebcbc0 786 case '\025': /* $^UNICODE, $^UTF8LOCALE */
823a54a3 787 if (strEQ(remaining, "NICODE"))
a05d7ebb 788 sv_setuv(sv, (UV) PL_unicode);
823a54a3 789 else if (strEQ(remaining, "TF8LOCALE"))
7cebcbc0 790 sv_setuv(sv, (UV) PL_utf8locale);
fde18df1 791 break;
792 case '\027': /* ^W & $^WARNING_BITS */
823a54a3 793 if (nextchar == '\0')
4438c4b7 794 sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE));
823a54a3 795 else if (strEQ(remaining, "ARNING_BITS")) {
013b78e8 796 if (PL_compiling.cop_warnings == pWARN_NONE) {
4438c4b7 797 sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
013b78e8 798 }
799 else if (PL_compiling.cop_warnings == pWARN_STD) {
800 sv_setpvn(
801 sv,
802 (PL_dowarn & G_WARN_ON) ? WARN_ALLstring : WARN_NONEstring,
803 WARNsize
804 );
805 }
d3a7d8c7 806 else if (PL_compiling.cop_warnings == pWARN_ALL) {
75b6c4ca 807 /* Get the bit mask for $warnings::Bits{all}, because
808 * it could have been extended by warnings::register */
809 SV **bits_all;
823a54a3 810 HV * const bits=get_hv("warnings::Bits", FALSE);
75b6c4ca 811 if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) {
812 sv_setsv(sv, *bits_all);
813 }
814 else {
815 sv_setpvn(sv, WARN_ALLstring, WARNsize) ;
816 }
ac27b0f5 817 }
4438c4b7 818 else {
819 sv_setsv(sv, PL_compiling.cop_warnings);
ac27b0f5 820 }
d3a7d8c7 821 SvPOK_only(sv);
4438c4b7 822 }
79072805 823 break;
824 case '1': case '2': case '3': case '4':
825 case '5': case '6': case '7': case '8': case '9': case '&':
aaa362c4 826 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 827 I32 s1, t1;
828
a863c7d1 829 /*
830 * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
831 * XXX Does the new way break anything?
832 */
ffc61ed2 833 paren = atoi(mg->mg_ptr); /* $& is in [0] */
79072805 834 getparen:
eb160463 835 if (paren <= (I32)rx->nparens &&
cf93c79d 836 (s1 = rx->startp[paren]) != -1 &&
837 (t1 = rx->endp[paren]) != -1)
bbce6d69 838 {
cf93c79d 839 i = t1 - s1;
840 s = rx->subbeg + s1;
01ec43d0 841 if (!rx->subbeg)
c2e66d9e 842 break;
843
13f57bf8 844 getrx:
748a9306 845 if (i >= 0) {
f6ba9920 846 int oldtainted = PL_tainted;
847 TAINT_NOT;
cf93c79d 848 sv_setpvn(sv, s, i);
f6ba9920 849 PL_tainted = oldtainted;
a30b2f1f 850 if (RX_MATCH_UTF8(rx) && is_utf8_string((U8*)s, i))
7e2040f0 851 SvUTF8_on(sv);
852 else
853 SvUTF8_off(sv);
e9814ee1 854 if (PL_tainting) {
855 if (RX_MATCH_TAINTED(rx)) {
823a54a3 856 MAGIC* const mg = SvMAGIC(sv);
e9814ee1 857 MAGIC* mgt;
858 PL_tainted = 1;
b162af07 859 SvMAGIC_set(sv, mg->mg_moremagic);
e9814ee1 860 SvTAINT(sv);
861 if ((mgt = SvMAGIC(sv))) {
862 mg->mg_moremagic = mgt;
b162af07 863 SvMAGIC_set(sv, mg);
e9814ee1 864 }
865 } else
866 SvTAINTED_off(sv);
867 }
748a9306 868 break;
869 }
79072805 870 }
79072805 871 }
3280af22 872 sv_setsv(sv,&PL_sv_undef);
79072805 873 break;
874 case '+':
aaa362c4 875 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
d9f97599 876 paren = rx->lastparen;
a0d0e21e 877 if (paren)
878 goto getparen;
79072805 879 }
3280af22 880 sv_setsv(sv,&PL_sv_undef);
79072805 881 break;
a01268b5 882 case '\016': /* ^N */
883 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
884 paren = rx->lastcloseparen;
885 if (paren)
886 goto getparen;
887 }
888 sv_setsv(sv,&PL_sv_undef);
889 break;
79072805 890 case '`':
aaa362c4 891 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 892 if ((s = rx->subbeg) && rx->startp[0] != -1) {
893 i = rx->startp[0];
13f57bf8 894 goto getrx;
79072805 895 }
79072805 896 }
3280af22 897 sv_setsv(sv,&PL_sv_undef);
79072805 898 break;
899 case '\'':
aaa362c4 900 if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
cf93c79d 901 if (rx->subbeg && rx->endp[0] != -1) {
902 s = rx->subbeg + rx->endp[0];
903 i = rx->sublen - rx->endp[0];
13f57bf8 904 goto getrx;
79072805 905 }
79072805 906 }
3280af22 907 sv_setsv(sv,&PL_sv_undef);
79072805 908 break;
909 case '.':
3280af22 910 if (GvIO(PL_last_in_gv)) {
357c8808 911 sv_setiv(sv, (IV)IoLINES(GvIOp(PL_last_in_gv)));
79072805 912 }
79072805 913 break;
914 case '?':
809a5acc 915 {
809a5acc 916 sv_setiv(sv, (IV)STATUS_CURRENT);
ff0cee69 917#ifdef COMPLEX_STATUS
6b88bc9c 918 LvTARGOFF(sv) = PL_statusvalue;
919 LvTARGLEN(sv) = PL_statusvalue_vms;
ff0cee69 920#endif
809a5acc 921 }
79072805 922 break;
923 case '^':
0daa599b 924 if (GvIOp(PL_defoutgv))
925 s = IoTOP_NAME(GvIOp(PL_defoutgv));
79072805 926 if (s)
927 sv_setpv(sv,s);
928 else {
3280af22 929 sv_setpv(sv,GvENAME(PL_defoutgv));
79072805 930 sv_catpv(sv,"_TOP");
931 }
932 break;
933 case '~':
0daa599b 934 if (GvIOp(PL_defoutgv))
935 s = IoFMT_NAME(GvIOp(PL_defoutgv));
79072805 936 if (!s)
3280af22 937 s = GvENAME(PL_defoutgv);
79072805 938 sv_setpv(sv,s);
939 break;
79072805 940 case '=':
0daa599b 941 if (GvIOp(PL_defoutgv))
942 sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
79072805 943 break;
944 case '-':
0daa599b 945 if (GvIOp(PL_defoutgv))
946 sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
79072805 947 break;
948 case '%':
0daa599b 949 if (GvIOp(PL_defoutgv))
950 sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
79072805 951 break;
79072805 952 case ':':
953 break;
954 case '/':
955 break;
956 case '[':
3280af22 957 WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
79072805 958 break;
959 case '|':
0daa599b 960 if (GvIOp(PL_defoutgv))
961 sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
79072805 962 break;
963 case ',':
79072805 964 break;
965 case '\\':
b2ce0fda 966 if (PL_ors_sv)
f28098ff 967 sv_copypv(sv, PL_ors_sv);
79072805 968 break;
79072805 969 case '!':
a5f75d66 970#ifdef VMS
65202027 971 sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
88e89b8a 972 sv_setpv(sv, errno ? Strerror(errno) : "");
a5f75d66 973#else
88e89b8a 974 {
8772537c 975 const int saveerrno = errno;
65202027 976 sv_setnv(sv, (NV)errno);
88e89b8a 977#ifdef OS2
ed344e4f 978 if (errno == errno_isOS2 || errno == errno_isOS2_set)
979 sv_setpv(sv, os2error(Perl_rc));
88e89b8a 980 else
a5f75d66 981#endif
2304df62 982 sv_setpv(sv, errno ? Strerror(errno) : "");
88e89b8a 983 errno = saveerrno;
984 }
985#endif
ad3296c6 986 SvRTRIM(sv);
946ec16e 987 SvNOK_on(sv); /* what a wonderful hack! */
79072805 988 break;
989 case '<':
3280af22 990 sv_setiv(sv, (IV)PL_uid);
79072805 991 break;
992 case '>':
3280af22 993 sv_setiv(sv, (IV)PL_euid);
79072805 994 break;
995 case '(':
3280af22 996 sv_setiv(sv, (IV)PL_gid);
a52cb5f7 997#ifdef HAS_GETGROUPS
a3b680e6 998 Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_gid);
a52cb5f7 999#endif
79072805 1000 goto add_groups;
1001 case ')':
3280af22 1002 sv_setiv(sv, (IV)PL_egid);
a52cb5f7 1003#ifdef HAS_GETGROUPS
a3b680e6 1004 Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, (long unsigned int)PL_egid);
a52cb5f7 1005#endif
79072805 1006 add_groups:
79072805 1007#ifdef HAS_GETGROUPS
79072805 1008 {
a0d0e21e 1009 Groups_t gary[NGROUPS];
a3b680e6 1010 I32 j = getgroups(NGROUPS,gary);
1011 while (--j >= 0)
1012 Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, (long unsigned int)gary[j]);
79072805 1013 }
1014#endif
155aba94 1015 (void)SvIOK_on(sv); /* what a wonderful hack! */
79072805 1016 break;
cd39f2b6 1017#ifndef MACOS_TRADITIONAL
79072805 1018 case '0':
1019 break;
cd39f2b6 1020#endif
79072805 1021 }
a0d0e21e 1022 return 0;
79072805 1023}
1024
1025int
864dbfa3 1026Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
79072805 1027{
8772537c 1028 struct ufuncs * const uf = (struct ufuncs *)mg->mg_ptr;
79072805 1029
1030 if (uf && uf->uf_val)
24f81a43 1031 (*uf->uf_val)(aTHX_ uf->uf_index, sv);
79072805 1032 return 0;
1033}
1034
1035int
864dbfa3 1036Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
79072805 1037{
27da23d5 1038 dVAR;
b83604b4 1039 const char *s;
e62f0680 1040 const char *ptr;
5aabfad6 1041 STRLEN len, klen;
1e422769 1042
b83604b4 1043 s = SvPV_const(sv,len);
e62f0680 1044 ptr = MgPV_const(mg,klen);
88e89b8a 1045 my_setenv(ptr, s);
1e422769 1046
a0d0e21e 1047#ifdef DYNAMIC_ENV_FETCH
1048 /* We just undefd an environment var. Is a replacement */
1049 /* waiting in the wings? */
1050 if (!len) {
5aabfad6 1051 SV **valp;
6b88bc9c 1052 if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
b83604b4 1053 s = SvPV_const(*valp, len);
a0d0e21e 1054 }
1055#endif
1e422769 1056
39e571d4 1057#if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
79072805 1058 /* And you'll never guess what the dog had */
1059 /* in its mouth... */
3280af22 1060 if (PL_tainting) {
1e422769 1061 MgTAINTEDDIR_off(mg);
1062#ifdef VMS
5aabfad6 1063 if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
b8ffc8df 1064 char pathbuf[256], eltbuf[256], *cp, *elt;
c623ac67 1065 Stat_t sbuf;
1e422769 1066 int i = 0, j = 0;
1067
b8ffc8df 1068 strncpy(eltbuf, s, 255);
1069 eltbuf[255] = 0;
1070 elt = eltbuf;
1e422769 1071 do { /* DCL$PATH may be a search list */
1072 while (1) { /* as may dev portion of any element */
1073 if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
1074 if ( *(cp+1) == '.' || *(cp+1) == '-' ||
1075 cando_by_name(S_IWUSR,0,elt) ) {
1076 MgTAINTEDDIR_on(mg);
1077 return 0;
1078 }
1079 }
1080 if ((cp = strchr(elt, ':')) != Nullch)
1081 *cp = '\0';
1082 if (my_trnlnm(elt, eltbuf, j++))
1083 elt = eltbuf;
1084 else
1085 break;
1086 }
1087 j = 0;
1088 } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
1089 }
1090#endif /* VMS */
5aabfad6 1091 if (s && klen == 4 && strEQ(ptr,"PATH")) {
8772537c 1092 const char * const strend = s + len;
463ee0b2 1093
1094 while (s < strend) {
96827780 1095 char tmpbuf[256];
c623ac67 1096 Stat_t st;
5f74f29c 1097 I32 i;
96827780 1098 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
fc36a67e 1099 s, strend, ':', &i);
463ee0b2 1100 s++;
96827780 1101 if (i >= sizeof tmpbuf /* too long -- assume the worst */
1102 || *tmpbuf != '/'
c6ed36e1 1103 || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
8990e307 1104 MgTAINTEDDIR_on(mg);
1e422769 1105 return 0;
1106 }
463ee0b2 1107 }
79072805 1108 }
1109 }
39e571d4 1110#endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
1e422769 1111
79072805 1112 return 0;
1113}
1114
1115int
864dbfa3 1116Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
85e6fe83 1117{
8772537c 1118 PERL_UNUSED_ARG(sv);
01b8bcb7 1119 my_setenv(MgPV_nolen_const(mg),Nullch);
85e6fe83 1120 return 0;
1121}
1122
88e89b8a 1123int
864dbfa3 1124Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
fb73857a 1125{
65e66c80 1126 PERL_UNUSED_ARG(mg);
b0269e46 1127#if defined(VMS)
cea2e8a9 1128 Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
fb73857a 1129#else
3280af22 1130 if (PL_localizing) {
fb73857a 1131 HE* entry;
b0269e46 1132 my_clearenv();
fb73857a 1133 hv_iterinit((HV*)sv);
155aba94 1134 while ((entry = hv_iternext((HV*)sv))) {
fb73857a 1135 I32 keylen;
1136 my_setenv(hv_iterkey(entry, &keylen),
b83604b4 1137 SvPV_nolen_const(hv_iterval((HV*)sv, entry)));
fb73857a 1138 }
1139 }
1140#endif
1141 return 0;
1142}
1143
1144int
864dbfa3 1145Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
66b1d557 1146{
27da23d5 1147 dVAR;
8772537c 1148 PERL_UNUSED_ARG(sv);
1149 PERL_UNUSED_ARG(mg);
b0269e46 1150#if defined(VMS)
1151 Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
1152#else
1153 my_clearenv();
1154#endif
3e3baf6d 1155 return 0;
66b1d557 1156}
1157
64ca3a65 1158#ifndef PERL_MICRO
2d4fcd5e 1159#ifdef HAS_SIGPROCMASK
1160static void
1161restore_sigmask(pTHX_ SV *save_sv)
1162{
0bd48802 1163 const sigset_t * const ossetp = (const sigset_t *) SvPV_nolen_const( save_sv );
2d4fcd5e 1164 (void)sigprocmask(SIG_SETMASK, ossetp, (sigset_t *)0);
1165}
1166#endif
66b1d557 1167int
864dbfa3 1168Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
88e89b8a 1169{
88e89b8a 1170 /* Are we fetching a signal entry? */
8772537c 1171 const I32 i = whichsig(MgPV_nolen_const(mg));
e02bfb16 1172 if (i > 0) {
22c35a8c 1173 if(PL_psig_ptr[i])
1174 sv_setsv(sv,PL_psig_ptr[i]);
88e89b8a 1175 else {
85b332e2 1176 Sighandler_t sigstate;
2e34cc90 1177 sigstate = rsignal_state(i);
23ada85b 1178#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
27da23d5 1179 if (PL_sig_handlers_initted && PL_sig_ignoring[i]) sigstate = SIG_IGN;
2e34cc90 1180#endif
1181#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
27da23d5 1182 if (PL_sig_handlers_initted && PL_sig_defaulting[i]) sigstate = SIG_DFL;
85b332e2 1183#endif
88e89b8a 1184 /* cache state so we don't fetch it again */
8aad04aa 1185 if(sigstate == (Sighandler_t) SIG_IGN)
88e89b8a 1186 sv_setpv(sv,"IGNORE");
1187 else
3280af22 1188 sv_setsv(sv,&PL_sv_undef);
22c35a8c 1189 PL_psig_ptr[i] = SvREFCNT_inc(sv);
88e89b8a 1190 SvTEMP_off(sv);
1191 }
1192 }
1193 return 0;
1194}
1195int
864dbfa3 1196Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
88e89b8a 1197{
2d4fcd5e 1198 /* XXX Some of this code was copied from Perl_magic_setsig. A little
1199 * refactoring might be in order.
1200 */
27da23d5 1201 dVAR;
8772537c 1202 register const char * const s = MgPV_nolen_const(mg);
1203 PERL_UNUSED_ARG(sv);
2d4fcd5e 1204 if (*s == '_') {
27da23d5 1205 SV** svp = 0;
2d4fcd5e 1206 if (strEQ(s,"__DIE__"))
1207 svp = &PL_diehook;
1208 else if (strEQ(s,"__WARN__"))
1209 svp = &PL_warnhook;
1210 else
1211 Perl_croak(aTHX_ "No such hook: %s", s);
27da23d5 1212 if (svp && *svp) {
8772537c 1213 SV * const to_dec = *svp;
2d4fcd5e 1214 *svp = 0;
1215 SvREFCNT_dec(to_dec);
1216 }
1217 }
1218 else {
2d4fcd5e 1219 /* Are we clearing a signal entry? */
8772537c 1220 const I32 i = whichsig(s);
e02bfb16 1221 if (i > 0) {
2d4fcd5e 1222#ifdef HAS_SIGPROCMASK
1223 sigset_t set, save;
1224 SV* save_sv;
1225 /* Avoid having the signal arrive at a bad time, if possible. */
1226 sigemptyset(&set);
1227 sigaddset(&set,i);
1228 sigprocmask(SIG_BLOCK, &set, &save);
1229 ENTER;
1230 save_sv = newSVpv((char *)(&save), sizeof(sigset_t));
1231 SAVEFREESV(save_sv);
1232 SAVEDESTRUCTOR_X(restore_sigmask, save_sv);
1233#endif
1234 PERL_ASYNC_CHECK();
1235#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
27da23d5 1236 if (!PL_sig_handlers_initted) Perl_csighandler_init();
2d4fcd5e 1237#endif
1238#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
27da23d5 1239 PL_sig_defaulting[i] = 1;
5c1546dc 1240 (void)rsignal(i, PL_csighandlerp);
2d4fcd5e 1241#else
8aad04aa 1242 (void)rsignal(i, (Sighandler_t) SIG_DFL);
2d4fcd5e 1243#endif
1244 if(PL_psig_name[i]) {
1245 SvREFCNT_dec(PL_psig_name[i]);
1246 PL_psig_name[i]=0;
1247 }
1248 if(PL_psig_ptr[i]) {
dd374669 1249 SV *to_dec=PL_psig_ptr[i];
2d4fcd5e 1250 PL_psig_ptr[i]=0;
1251 LEAVE;
1252 SvREFCNT_dec(to_dec);
1253 }
1254 else
1255 LEAVE;
1256 }
88e89b8a 1257 }
1258 return 0;
1259}
3d37d572 1260
dd374669 1261static void
1262S_raise_signal(pTHX_ int sig)
0a8e0eff 1263{
1264 /* Set a flag to say this signal is pending */
1265 PL_psig_pend[sig]++;
1266 /* And one to say _a_ signal is pending */
1267 PL_sig_pending = 1;
1268}
1269
1270Signal_t
8aad04aa 1271#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
1272Perl_csighandler(int sig, ...)
1273#else
0a8e0eff 1274Perl_csighandler(int sig)
8aad04aa 1275#endif
0a8e0eff 1276{
1018e26f 1277#ifdef PERL_GET_SIG_CONTEXT
1278 dTHXa(PERL_GET_SIG_CONTEXT);
1279#else
85b332e2 1280 dTHX;
1281#endif
23ada85b 1282#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
5c1546dc 1283 (void) rsignal(sig, PL_csighandlerp);
27da23d5 1284 if (PL_sig_ignoring[sig]) return;
85b332e2 1285#endif
2e34cc90 1286#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
27da23d5 1287 if (PL_sig_defaulting[sig])
2e34cc90 1288#ifdef KILL_BY_SIGPRC
1289 exit((Perl_sig_to_vmscondition(sig)&STS$M_COND_ID)|STS$K_SEVERE|STS$M_INHIB_MSG);
1290#else
1291 exit(1);
1292#endif
1293#endif
4ffa73a3 1294 if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
1295 /* Call the perl level handler now--
1296 * with risk we may be in malloc() etc. */
1297 (*PL_sighandlerp)(sig);
1298 else
dd374669 1299 S_raise_signal(aTHX_ sig);
0a8e0eff 1300}
1301
2e34cc90 1302#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
1303void
1304Perl_csighandler_init(void)
1305{
1306 int sig;
27da23d5 1307 if (PL_sig_handlers_initted) return;
2e34cc90 1308
1309 for (sig = 1; sig < SIG_SIZE; sig++) {
1310#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
218fdd94 1311 dTHX;
27da23d5 1312 PL_sig_defaulting[sig] = 1;
5c1546dc 1313 (void) rsignal(sig, PL_csighandlerp);
2e34cc90 1314#endif
1315#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
27da23d5 1316 PL_sig_ignoring[sig] = 0;
2e34cc90 1317#endif
1318 }
27da23d5 1319 PL_sig_handlers_initted = 1;
2e34cc90 1320}
1321#endif
1322
0a8e0eff 1323void
1324Perl_despatch_signals(pTHX)
1325{
1326 int sig;
1327 PL_sig_pending = 0;
1328 for (sig = 1; sig < SIG_SIZE; sig++) {
1329 if (PL_psig_pend[sig]) {
25da4428 1330 PERL_BLOCKSIG_ADD(set, sig);
1331 PL_psig_pend[sig] = 0;
1332 PERL_BLOCKSIG_BLOCK(set);
f5203343 1333 (*PL_sighandlerp)(sig);
25da4428 1334 PERL_BLOCKSIG_UNBLOCK(set);
0a8e0eff 1335 }
1336 }
1337}
1338
85e6fe83 1339int
864dbfa3 1340Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
79072805 1341{
27da23d5 1342 dVAR;
79072805 1343 I32 i;
b7953727 1344 SV** svp = 0;
2d4fcd5e 1345 /* Need to be careful with SvREFCNT_dec(), because that can have side
1346 * effects (due to closures). We must make sure that the new disposition
1347 * is in place before it is called.
1348 */
1349 SV* to_dec = 0;
e72dc28c 1350 STRLEN len;
2d4fcd5e 1351#ifdef HAS_SIGPROCMASK
1352 sigset_t set, save;
1353 SV* save_sv;
1354#endif
a0d0e21e 1355
d5263905 1356 register const char *s = MgPV_const(mg,len);
748a9306 1357 if (*s == '_') {
1358 if (strEQ(s,"__DIE__"))
3280af22 1359 svp = &PL_diehook;
748a9306 1360 else if (strEQ(s,"__WARN__"))
3280af22 1361 svp = &PL_warnhook;
748a9306 1362 else
cea2e8a9 1363 Perl_croak(aTHX_ "No such hook: %s", s);
748a9306 1364 i = 0;
4633a7c4 1365 if (*svp) {
2d4fcd5e 1366 to_dec = *svp;
4633a7c4 1367 *svp = 0;
1368 }
748a9306 1369 }
1370 else {
1371 i = whichsig(s); /* ...no, a brick */
86d86cad 1372 if (i <= 0) {
e476b1b5 1373 if (ckWARN(WARN_SIGNAL))
9014280d 1374 Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "No such signal: SIG%s", s);
748a9306 1375 return 0;
1376 }
2d4fcd5e 1377#ifdef HAS_SIGPROCMASK
1378 /* Avoid having the signal arrive at a bad time, if possible. */
1379 sigemptyset(&set);
1380 sigaddset(&set,i);
1381 sigprocmask(SIG_BLOCK, &set, &save);
1382 ENTER;
1383 save_sv = newSVpv((char *)(&save), sizeof(sigset_t));
1384 SAVEFREESV(save_sv);
1385 SAVEDESTRUCTOR_X(restore_sigmask, save_sv);
1386#endif
1387 PERL_ASYNC_CHECK();
2e34cc90 1388#if defined(FAKE_PERSISTENT_SIGNAL_HANDLERS) || defined(FAKE_DEFAULT_SIGNAL_HANDLERS)
27da23d5 1389 if (!PL_sig_handlers_initted) Perl_csighandler_init();
2e34cc90 1390#endif
23ada85b 1391#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
27da23d5 1392 PL_sig_ignoring[i] = 0;
85b332e2 1393#endif
2e34cc90 1394#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
27da23d5 1395 PL_sig_defaulting[i] = 0;
2e34cc90 1396#endif
22c35a8c 1397 SvREFCNT_dec(PL_psig_name[i]);
2d4fcd5e 1398 to_dec = PL_psig_ptr[i];
22c35a8c 1399 PL_psig_ptr[i] = SvREFCNT_inc(sv);
88e89b8a 1400 SvTEMP_off(sv); /* Make sure it doesn't go away on us */
e72dc28c 1401 PL_psig_name[i] = newSVpvn(s, len);
22c35a8c 1402 SvREADONLY_on(PL_psig_name[i]);
748a9306 1403 }
a0d0e21e 1404 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
2d4fcd5e 1405 if (i) {
5c1546dc 1406 (void)rsignal(i, PL_csighandlerp);
2d4fcd5e 1407#ifdef HAS_SIGPROCMASK
1408 LEAVE;
1409#endif
1410 }
748a9306 1411 else
1412 *svp = SvREFCNT_inc(sv);
2d4fcd5e 1413 if(to_dec)
1414 SvREFCNT_dec(to_dec);
a0d0e21e 1415 return 0;
1416 }
e72dc28c 1417 s = SvPV_force(sv,len);
748a9306 1418 if (strEQ(s,"IGNORE")) {
85b332e2 1419 if (i) {
23ada85b 1420#ifdef FAKE_PERSISTENT_SIGNAL_HANDLERS
27da23d5 1421 PL_sig_ignoring[i] = 1;
5c1546dc 1422 (void)rsignal(i, PL_csighandlerp);
85b332e2 1423#else
8aad04aa 1424 (void)rsignal(i, (Sighandler_t) SIG_IGN);
85b332e2 1425#endif
2d4fcd5e 1426 }
748a9306 1427 }
1428 else if (strEQ(s,"DEFAULT") || !*s) {
1429 if (i)
2e34cc90 1430#ifdef FAKE_DEFAULT_SIGNAL_HANDLERS
1431 {
27da23d5 1432 PL_sig_defaulting[i] = 1;
5c1546dc 1433 (void)rsignal(i, PL_csighandlerp);
2e34cc90 1434 }
1435#else
8aad04aa 1436 (void)rsignal(i, (Sighandler_t) SIG_DFL);
2e34cc90 1437#endif
748a9306 1438 }
79072805 1439 else {
5aabfad6 1440 /*
1441 * We should warn if HINT_STRICT_REFS, but without
1442 * access to a known hint bit in a known OP, we can't
1443 * tell whether HINT_STRICT_REFS is in force or not.
1444 */
46fc3d4c 1445 if (!strchr(s,':') && !strchr(s,'\''))
e72dc28c 1446 sv_insert(sv, 0, 0, "main::", 6);
748a9306 1447 if (i)
5c1546dc 1448 (void)rsignal(i, PL_csighandlerp);
748a9306 1449 else
1450 *svp = SvREFCNT_inc(sv);
79072805 1451 }
2d4fcd5e 1452#ifdef HAS_SIGPROCMASK
1453 if(i)
1454 LEAVE;
1455#endif
1456 if(to_dec)
1457 SvREFCNT_dec(to_dec);
79072805 1458 return 0;
1459}
64ca3a65 1460#endif /* !PERL_MICRO */
79072805 1461
1462int
864dbfa3 1463Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
79072805 1464{
8772537c 1465 PERL_UNUSED_ARG(sv);
1466 PERL_UNUSED_ARG(mg);
3280af22 1467 PL_sub_generation++;
463ee0b2 1468 return 0;
1469}
1470
1471int
864dbfa3 1472Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1473{
8772537c 1474 PERL_UNUSED_ARG(sv);
1475 PERL_UNUSED_ARG(mg);
a0d0e21e 1476 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
3280af22 1477 PL_amagic_generation++;
463ee0b2 1478
a0d0e21e 1479 return 0;
1480}
463ee0b2 1481
946ec16e 1482int
864dbfa3 1483Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
6ff81951 1484{
dd374669 1485 HV * const hv = (HV*)LvTARG(sv);
6ff81951 1486 I32 i = 0;
8772537c 1487 PERL_UNUSED_ARG(mg);
7719e241 1488
6ff81951 1489 if (hv) {
497b47a8 1490 (void) hv_iterinit(hv);
1491 if (! SvTIED_mg((SV*)hv, PERL_MAGIC_tied))
1492 i = HvKEYS(hv);
1493 else {
1494 while (hv_iternext(hv))
1495 i++;
1496 }
6ff81951 1497 }
1498
1499 sv_setiv(sv, (IV)i);
1500 return 0;
1501}
1502
1503int
864dbfa3 1504Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
946ec16e 1505{
8772537c 1506 PERL_UNUSED_ARG(mg);
946ec16e 1507 if (LvTARG(sv)) {
1508 hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
946ec16e 1509 }
1510 return 0;
ac27b0f5 1511}
946ec16e 1512
e336de0d 1513/* caller is responsible for stack switching/cleanup */
565764a8 1514STATIC int
e1ec3a88 1515S_magic_methcall(pTHX_ SV *sv, const MAGIC *mg, const char *meth, I32 flags, int n, SV *val)
a0d0e21e 1516{
1517 dSP;
463ee0b2 1518
924508f0 1519 PUSHMARK(SP);
1520 EXTEND(SP, n);
33c27489 1521 PUSHs(SvTIED_obj(sv, mg));
ac27b0f5 1522 if (n > 1) {
93965878 1523 if (mg->mg_ptr) {
565764a8 1524 if (mg->mg_len >= 0)
79cb57f6 1525 PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
565764a8 1526 else if (mg->mg_len == HEf_SVKEY)
93965878 1527 PUSHs((SV*)mg->mg_ptr);
1528 }
14befaf4 1529 else if (mg->mg_type == PERL_MAGIC_tiedelem) {
565764a8 1530 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
93965878 1531 }
1532 }
1533 if (n > 2) {
1534 PUSHs(val);
88e89b8a 1535 }
463ee0b2 1536 PUTBACK;
1537
864dbfa3 1538 return call_method(meth, flags);
946ec16e 1539}
1540
76e3520e 1541STATIC int
e1ec3a88 1542S_magic_methpack(pTHX_ SV *sv, const MAGIC *mg, const char *meth)
a0d0e21e 1543{
27da23d5 1544 dVAR; dSP;
463ee0b2 1545
a0d0e21e 1546 ENTER;
1547 SAVETMPS;
e788e7d3 1548 PUSHSTACKi(PERLSI_MAGIC);
463ee0b2 1549
33c27489 1550 if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
3280af22 1551 sv_setsv(sv, *PL_stack_sp--);
93965878 1552 }
463ee0b2 1553
d3acc0f7 1554 POPSTACK;
a0d0e21e 1555 FREETMPS;
1556 LEAVE;
1557 return 0;
1558}
463ee0b2 1559
a0d0e21e 1560int
864dbfa3 1561Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e 1562{
a0d0e21e 1563 if (mg->mg_ptr)
1564 mg->mg_flags |= MGf_GSKIP;
58f82c5c 1565 magic_methpack(sv,mg,"FETCH");
463ee0b2 1566 return 0;
1567}
1568
1569int
864dbfa3 1570Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
e336de0d 1571{
27da23d5 1572 dVAR; dSP;
a60c0954 1573 ENTER;
e788e7d3 1574 PUSHSTACKi(PERLSI_MAGIC);
33c27489 1575 magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
d3acc0f7 1576 POPSTACK;
a60c0954 1577 LEAVE;
463ee0b2 1578 return 0;
1579}
1580
1581int
864dbfa3 1582Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1583{
a0d0e21e 1584 return magic_methpack(sv,mg,"DELETE");
1585}
463ee0b2 1586
93965878 1587
1588U32
864dbfa3 1589Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
ac27b0f5 1590{
27da23d5 1591 dVAR; dSP;
93965878 1592 U32 retval = 0;
1593
1594 ENTER;
1595 SAVETMPS;
e788e7d3 1596 PUSHSTACKi(PERLSI_MAGIC);
33c27489 1597 if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
3280af22 1598 sv = *PL_stack_sp--;
a60c0954 1599 retval = (U32) SvIV(sv)-1;
93965878 1600 }
d3acc0f7 1601 POPSTACK;
93965878 1602 FREETMPS;
1603 LEAVE;
1604 return retval;
1605}
1606
cea2e8a9 1607int
1608Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e 1609{
27da23d5 1610 dVAR; dSP;
463ee0b2 1611
e336de0d 1612 ENTER;
e788e7d3 1613 PUSHSTACKi(PERLSI_MAGIC);
924508f0 1614 PUSHMARK(SP);
33c27489 1615 XPUSHs(SvTIED_obj(sv, mg));
463ee0b2 1616 PUTBACK;
864dbfa3 1617 call_method("CLEAR", G_SCALAR|G_DISCARD);
d3acc0f7 1618 POPSTACK;
a60c0954 1619 LEAVE;
a3bcc51e 1620
463ee0b2 1621 return 0;
1622}
1623
1624int
864dbfa3 1625Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
463ee0b2 1626{
27da23d5 1627 dVAR; dSP;
35a4481c 1628 const char * const meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2 1629
1630 ENTER;
a0d0e21e 1631 SAVETMPS;
e788e7d3 1632 PUSHSTACKi(PERLSI_MAGIC);
924508f0 1633 PUSHMARK(SP);
1634 EXTEND(SP, 2);
33c27489 1635 PUSHs(SvTIED_obj(sv, mg));
463ee0b2 1636 if (SvOK(key))
1637 PUSHs(key);
1638 PUTBACK;
1639
864dbfa3 1640 if (call_method(meth, G_SCALAR))
3280af22 1641 sv_setsv(key, *PL_stack_sp--);
463ee0b2 1642
d3acc0f7 1643 POPSTACK;
a0d0e21e 1644 FREETMPS;
1645 LEAVE;
79072805 1646 return 0;
1647}
1648
1649int
864dbfa3 1650Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e 1651{
1652 return magic_methpack(sv,mg,"EXISTS");
ac27b0f5 1653}
a0d0e21e 1654
a3bcc51e 1655SV *
1656Perl_magic_scalarpack(pTHX_ HV *hv, MAGIC *mg)
1657{
27da23d5 1658 dVAR; dSP;
a3bcc51e 1659 SV *retval = &PL_sv_undef;
8772537c 1660 SV * const tied = SvTIED_obj((SV*)hv, mg);
1661 HV * const pkg = SvSTASH((SV*)SvRV(tied));
a3bcc51e 1662
1663 if (!gv_fetchmethod_autoload(pkg, "SCALAR", FALSE)) {
1664 SV *key;
bfcb3514 1665 if (HvEITER_get(hv))
a3bcc51e 1666 /* we are in an iteration so the hash cannot be empty */
1667 return &PL_sv_yes;
1668 /* no xhv_eiter so now use FIRSTKEY */
1669 key = sv_newmortal();
1670 magic_nextpack((SV*)hv, mg, key);
bfcb3514 1671 HvEITER_set(hv, NULL); /* need to reset iterator */
a3bcc51e 1672 return SvOK(key) ? &PL_sv_yes : &PL_sv_no;
1673 }
1674
1675 /* there is a SCALAR method that we can call */
1676 ENTER;
1677 PUSHSTACKi(PERLSI_MAGIC);
1678 PUSHMARK(SP);
1679 EXTEND(SP, 1);
1680 PUSHs(tied);
1681 PUTBACK;
1682
1683 if (call_method("SCALAR", G_SCALAR))
1684 retval = *PL_stack_sp--;
1685 POPSTACK;
1686 LEAVE;
1687 return retval;
1688}
1689
a0d0e21e 1690int
864dbfa3 1691Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
79072805 1692{
8772537c 1693 GV * const gv = PL_DBline;
1694 const I32 i = SvTRUE(sv);
1695 SV ** const svp = av_fetch(GvAV(gv),
01b8bcb7 1696 atoi(MgPV_nolen_const(mg)), FALSE);
8772537c 1697 if (svp && SvIOKp(*svp)) {
1698 OP * const o = INT2PTR(OP*,SvIVX(*svp));
1699 if (o) {
1700 /* set or clear breakpoint in the relevant control op */
1701 if (i)
1702 o->op_flags |= OPf_SPECIAL;
1703 else
1704 o->op_flags &= ~OPf_SPECIAL;
1705 }
5df8de69 1706 }
79072805 1707 return 0;
1708}
1709
1710int
8772537c 1711Perl_magic_getarylen(pTHX_ SV *sv, const MAGIC *mg)
79072805 1712{
8772537c 1713 const AV * const obj = (AV*)mg->mg_obj;
83bf042f 1714 if (obj) {
1715 sv_setiv(sv, AvFILL(obj) + PL_curcop->cop_arybase);
1716 } else {
1717 SvOK_off(sv);
1718 }
79072805 1719 return 0;
1720}
1721
1722int
864dbfa3 1723Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
79072805 1724{
8772537c 1725 AV * const obj = (AV*)mg->mg_obj;
83bf042f 1726 if (obj) {
1727 av_fill(obj, SvIV(sv) - PL_curcop->cop_arybase);
1728 } else {
1729 if (ckWARN(WARN_MISC))
1730 Perl_warner(aTHX_ packWARN(WARN_MISC),
1731 "Attempt to set length of freed array");
1732 }
1733 return 0;
1734}
1735
1736int
1737Perl_magic_freearylen_p(pTHX_ SV *sv, MAGIC *mg)
1738{
53c1dcc0 1739 PERL_UNUSED_ARG(sv);
94f3782b 1740 /* during global destruction, mg_obj may already have been freed */
1741 if (PL_in_clean_all)
1ea47f64 1742 return 0;
94f3782b 1743
83bf042f 1744 mg = mg_find (mg->mg_obj, PERL_MAGIC_arylen);
1745
1746 if (mg) {
1747 /* arylen scalar holds a pointer back to the array, but doesn't own a
1748 reference. Hence the we (the array) are about to go away with it
1749 still pointing at us. Clear its pointer, else it would be pointing
1750 at free memory. See the comment in sv_magic about reference loops,
1751 and why it can't own a reference to us. */
1752 mg->mg_obj = 0;
1753 }
a0d0e21e 1754 return 0;
1755}
1756
1757int
864dbfa3 1758Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e 1759{
8772537c 1760 SV* const lsv = LvTARG(sv);
ac27b0f5 1761
a0d0e21e 1762 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
14befaf4 1763 mg = mg_find(lsv, PERL_MAGIC_regex_global);
565764a8 1764 if (mg && mg->mg_len >= 0) {
a0ed51b3 1765 I32 i = mg->mg_len;
7e2040f0 1766 if (DO_UTF8(lsv))
a0ed51b3 1767 sv_pos_b2u(lsv, &i);
1768 sv_setiv(sv, i + PL_curcop->cop_arybase);
a0d0e21e 1769 return 0;
1770 }
1771 }
0c34ef67 1772 SvOK_off(sv);
a0d0e21e 1773 return 0;
1774}
1775
1776int
864dbfa3 1777Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e 1778{
8772537c 1779 SV* const lsv = LvTARG(sv);
a0d0e21e 1780 SSize_t pos;
1781 STRLEN len;
c00206c8 1782 STRLEN ulen = 0;
a0d0e21e 1783
1784 mg = 0;
ac27b0f5 1785
a0d0e21e 1786 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
14befaf4 1787 mg = mg_find(lsv, PERL_MAGIC_regex_global);
a0d0e21e 1788 if (!mg) {
1789 if (!SvOK(sv))
1790 return 0;
14befaf4 1791 sv_magic(lsv, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
1792 mg = mg_find(lsv, PERL_MAGIC_regex_global);
a0d0e21e 1793 }
1794 else if (!SvOK(sv)) {
565764a8 1795 mg->mg_len = -1;
a0d0e21e 1796 return 0;
1797 }
1798 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1799
c485e607 1800 pos = SvIV(sv) - PL_curcop->cop_arybase;
a0ed51b3 1801
7e2040f0 1802 if (DO_UTF8(lsv)) {
a0ed51b3 1803 ulen = sv_len_utf8(lsv);
1804 if (ulen)
1805 len = ulen;
a0ed51b3 1806 }
1807
a0d0e21e 1808 if (pos < 0) {
1809 pos += len;
1810 if (pos < 0)
1811 pos = 0;
1812 }
eb160463 1813 else if (pos > (SSize_t)len)
a0d0e21e 1814 pos = len;
a0ed51b3 1815
1816 if (ulen) {
1817 I32 p = pos;
1818 sv_pos_u2b(lsv, &p, 0);
1819 pos = p;
1820 }
727405f8 1821
565764a8 1822 mg->mg_len = pos;
71be2cbc 1823 mg->mg_flags &= ~MGf_MINMATCH;
a0d0e21e 1824
79072805 1825 return 0;
1826}
1827
1828int
864dbfa3 1829Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
79072805 1830{
8772537c 1831 PERL_UNUSED_ARG(mg);
8646b087 1832 if (SvFAKE(sv)) { /* FAKE globs can get coerced */
1833 SvFAKE_off(sv);
946ec16e 1834 gv_efullname3(sv,((GV*)sv), "*");
8646b087 1835 SvFAKE_on(sv);
1836 }
1837 else
946ec16e 1838 gv_efullname3(sv,((GV*)sv), "*"); /* a gv value, be nice */
79072805 1839 return 0;
1840}
1841
1842int
864dbfa3 1843Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
79072805 1844{
79072805 1845 GV* gv;
8772537c 1846 PERL_UNUSED_ARG(mg);
1847
79072805 1848 if (!SvOK(sv))
1849 return 0;
7a5fd60d 1850 gv = gv_fetchsv(sv,TRUE, SVt_PVGV);
79072805 1851 if (sv == (SV*)gv)
1852 return 0;
1853 if (GvGP(sv))
88e89b8a 1854 gp_free((GV*)sv);
79072805 1855 GvGP(sv) = gp_ref(GvGP(gv));
79072805 1856 return 0;
1857}
1858
1859int
864dbfa3 1860Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
6ff81951 1861{
1862 STRLEN len;
35a4481c 1863 SV * const lsv = LvTARG(sv);
b83604b4 1864 const char * const tmps = SvPV_const(lsv,len);
6ff81951 1865 I32 offs = LvTARGOFF(sv);
1866 I32 rem = LvTARGLEN(sv);
8772537c 1867 PERL_UNUSED_ARG(mg);
6ff81951 1868
9aa983d2 1869 if (SvUTF8(lsv))
1870 sv_pos_u2b(lsv, &offs, &rem);
eb160463 1871 if (offs > (I32)len)
6ff81951 1872 offs = len;
eb160463 1873 if (rem + offs > (I32)len)
6ff81951 1874 rem = len - offs;
1875 sv_setpvn(sv, tmps + offs, (STRLEN)rem);
9aa983d2 1876 if (SvUTF8(lsv))
2ef4b674 1877 SvUTF8_on(sv);
6ff81951 1878 return 0;
1879}
1880
1881int
864dbfa3 1882Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
79072805 1883{
9aa983d2 1884 STRLEN len;
b83604b4 1885 const char *tmps = SvPV_const(sv, len);
dd374669 1886 SV * const lsv = LvTARG(sv);
9aa983d2 1887 I32 lvoff = LvTARGOFF(sv);
1888 I32 lvlen = LvTARGLEN(sv);
8772537c 1889 PERL_UNUSED_ARG(mg);
075a4a2b 1890
1aa99e6b 1891 if (DO_UTF8(sv)) {
9aa983d2 1892 sv_utf8_upgrade(lsv);
1893 sv_pos_u2b(lsv, &lvoff, &lvlen);
1894 sv_insert(lsv, lvoff, lvlen, tmps, len);
b76f3ce2 1895 LvTARGLEN(sv) = sv_len_utf8(sv);
9aa983d2 1896 SvUTF8_on(lsv);
1897 }
9bf12eaf 1898 else if (lsv && SvUTF8(lsv)) {
9aa983d2 1899 sv_pos_u2b(lsv, &lvoff, &lvlen);
b76f3ce2 1900 LvTARGLEN(sv) = len;
e95af362 1901 tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
9aa983d2 1902 sv_insert(lsv, lvoff, lvlen, tmps, len);
1903 Safefree(tmps);
1aa99e6b 1904 }
b76f3ce2 1905 else {
1906 sv_insert(lsv, lvoff, lvlen, tmps, len);
1907 LvTARGLEN(sv) = len;
1908 }
1909
1aa99e6b 1910
79072805 1911 return 0;
1912}
1913
1914int
864dbfa3 1915Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1916{
8772537c 1917 PERL_UNUSED_ARG(sv);
27cc343c 1918 TAINT_IF((PL_localizing != 1) && (mg->mg_len & 1));
463ee0b2 1919 return 0;
1920}
1921
1922int
864dbfa3 1923Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1924{
8772537c 1925 PERL_UNUSED_ARG(sv);
0a9c116b 1926 /* update taint status unless we're restoring at scope exit */
1927 if (PL_localizing != 2) {
1928 if (PL_tainted)
1929 mg->mg_len |= 1;
1930 else
1931 mg->mg_len &= ~1;
1932 }
463ee0b2 1933 return 0;
1934}
1935
1936int
864dbfa3 1937Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
6ff81951 1938{
35a4481c 1939 SV * const lsv = LvTARG(sv);
8772537c 1940 PERL_UNUSED_ARG(mg);
6ff81951 1941
1942 if (!lsv) {
0c34ef67 1943 SvOK_off(sv);
6ff81951 1944 return 0;
1945 }
6ff81951 1946
81e118e0 1947 sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
6ff81951 1948 return 0;
1949}
1950
1951int
864dbfa3 1952Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
79072805 1953{
8772537c 1954 PERL_UNUSED_ARG(mg);
79072805 1955 do_vecset(sv); /* XXX slurp this routine */
1956 return 0;
1957}
1958
1959int
864dbfa3 1960Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
5f05dabc 1961{
71be2cbc 1962 SV *targ = Nullsv;
5f05dabc 1963 if (LvTARGLEN(sv)) {
68dc0745 1964 if (mg->mg_obj) {
8772537c 1965 SV * const ahv = LvTARG(sv);
1966 HE * const he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
6d822dc4 1967 if (he)
1968 targ = HeVAL(he);
68dc0745 1969 }
1970 else {
8772537c 1971 AV* const av = (AV*)LvTARG(sv);
68dc0745 1972 if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1973 targ = AvARRAY(av)[LvTARGOFF(sv)];
1974 }
3280af22 1975 if (targ && targ != &PL_sv_undef) {
68dc0745 1976 /* somebody else defined it for us */
1977 SvREFCNT_dec(LvTARG(sv));
1978 LvTARG(sv) = SvREFCNT_inc(targ);
1979 LvTARGLEN(sv) = 0;
1980 SvREFCNT_dec(mg->mg_obj);
1981 mg->mg_obj = Nullsv;
1982 mg->mg_flags &= ~MGf_REFCOUNTED;
1983 }
5f05dabc 1984 }
71be2cbc 1985 else
1986 targ = LvTARG(sv);
3280af22 1987 sv_setsv(sv, targ ? targ : &PL_sv_undef);
71be2cbc 1988 return 0;
1989}
1990
1991int
864dbfa3 1992Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
71be2cbc 1993{
8772537c 1994 PERL_UNUSED_ARG(mg);
71be2cbc 1995 if (LvTARGLEN(sv))
68dc0745 1996 vivify_defelem(sv);
1997 if (LvTARG(sv)) {
5f05dabc 1998 sv_setsv(LvTARG(sv), sv);
68dc0745 1999 SvSETMAGIC(LvTARG(sv));
2000 }
5f05dabc 2001 return 0;
2002}
2003
71be2cbc 2004void
864dbfa3 2005Perl_vivify_defelem(pTHX_ SV *sv)
71be2cbc 2006{
74e13ce4 2007 MAGIC *mg;
2008 SV *value = Nullsv;
71be2cbc 2009
14befaf4 2010 if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem)))
71be2cbc 2011 return;
68dc0745 2012 if (mg->mg_obj) {
8772537c 2013 SV * const ahv = LvTARG(sv);
2014 HE * const he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
6d822dc4 2015 if (he)
2016 value = HeVAL(he);
3280af22 2017 if (!value || value == &PL_sv_undef)
ce5030a2 2018 Perl_croak(aTHX_ PL_no_helem_sv, mg->mg_obj);
71be2cbc 2019 }
68dc0745 2020 else {
8772537c 2021 AV* const av = (AV*)LvTARG(sv);
5aabfad6 2022 if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
68dc0745 2023 LvTARG(sv) = Nullsv; /* array can't be extended */
2024 else {
aec46f14 2025 SV** const svp = av_fetch(av, LvTARGOFF(sv), TRUE);
3280af22 2026 if (!svp || (value = *svp) == &PL_sv_undef)
cea2e8a9 2027 Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
68dc0745 2028 }
2029 }
3e3baf6d 2030 (void)SvREFCNT_inc(value);
68dc0745 2031 SvREFCNT_dec(LvTARG(sv));
2032 LvTARG(sv) = value;
71be2cbc 2033 LvTARGLEN(sv) = 0;
68dc0745 2034 SvREFCNT_dec(mg->mg_obj);
2035 mg->mg_obj = Nullsv;
2036 mg->mg_flags &= ~MGf_REFCOUNTED;
5f05dabc 2037}
2038
2039int
864dbfa3 2040Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
810b8aa5 2041{
e15faf7d 2042 AV *const av = (AV*)mg->mg_obj;
2043 SV **svp = AvARRAY(av);
8772537c 2044 PERL_UNUSED_ARG(sv);
dd374669 2045
0565a181 2046 /* Not sure why the av can get freed ahead of its sv, but somehow it does
2047 in ext/B/t/bytecode.t test 15 (involving print <DATA>) */
2048 if (svp && !SvIS_FREED(av)) {
e15faf7d 2049 SV *const *const last = svp + AvFILLp(av);
2050
2051 while (svp <= last) {
2052 if (*svp) {
2053 SV *const referrer = *svp;
2054 if (SvWEAKREF(referrer)) {
2055 /* XXX Should we check that it hasn't changed? */
2056 SvRV_set(referrer, 0);
2057 SvOK_off(referrer);
2058 SvWEAKREF_off(referrer);
2059 } else if (SvTYPE(referrer) == SVt_PVGV ||
2060 SvTYPE(referrer) == SVt_PVLV) {
2061 /* You lookin' at me? */
2062 assert(GvSTASH(referrer));
2063 assert(GvSTASH(referrer) == (HV*)sv);
2064 GvSTASH(referrer) = 0;
2065 } else {
2066 Perl_croak(aTHX_
2067 "panic: magic_killbackrefs (flags=%"UVxf")",
e91e3b10 2068 (UV)SvFLAGS(referrer));
e15faf7d 2069 }
2070
2071 *svp = Nullsv;
2072 }
2073 svp++;
810b8aa5 2074 }
810b8aa5 2075 }
d99b02a1 2076 SvREFCNT_dec(av); /* remove extra count added by sv_add_backref() */
810b8aa5 2077 return 0;
2078}
2079
2080int
864dbfa3 2081Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
93a17b20 2082{
565764a8 2083 mg->mg_len = -1;
c6496cc7 2084 SvSCREAM_off(sv);
93a17b20 2085 return 0;
2086}
2087
2088int
864dbfa3 2089Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
79072805 2090{
8772537c 2091 PERL_UNUSED_ARG(mg);
14befaf4 2092 sv_unmagic(sv, PERL_MAGIC_bm);
79072805 2093 SvVALID_off(sv);
2094 return 0;
2095}
2096
2097int
864dbfa3 2098Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
55497cff 2099{
8772537c 2100 PERL_UNUSED_ARG(mg);
14befaf4 2101 sv_unmagic(sv, PERL_MAGIC_fm);
55497cff 2102 SvCOMPILED_off(sv);
2103 return 0;
2104}
2105
2106int
864dbfa3 2107Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
79072805 2108{
35a4481c 2109 const struct ufuncs * const uf = (struct ufuncs *)mg->mg_ptr;
79072805 2110
2111 if (uf && uf->uf_set)
24f81a43 2112 (*uf->uf_set)(aTHX_ uf->uf_index, sv);
79072805 2113 return 0;
2114}
2115
c277df42 2116int
faf82a0b 2117Perl_magic_setregexp(pTHX_ SV *sv, MAGIC *mg)
2118{
8772537c 2119 PERL_UNUSED_ARG(mg);
faf82a0b 2120 sv_unmagic(sv, PERL_MAGIC_qr);
2121 return 0;
2122}
2123
2124int
864dbfa3 2125Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
c277df42 2126{
8772537c 2127 regexp * const re = (regexp *)mg->mg_obj;
2128 PERL_UNUSED_ARG(sv);
2129
c277df42 2130 ReREFCNT_dec(re);
2131 return 0;
2132}
2133
7a4c00b4 2134#ifdef USE_LOCALE_COLLATE
79072805 2135int
864dbfa3 2136Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
bbce6d69 2137{
2138 /*
838b5b74 2139 * RenE<eacute> Descartes said "I think not."
bbce6d69 2140 * and vanished with a faint plop.
2141 */
8772537c 2142 PERL_UNUSED_ARG(sv);
7a4c00b4 2143 if (mg->mg_ptr) {
2144 Safefree(mg->mg_ptr);
2145 mg->mg_ptr = NULL;
565764a8 2146 mg->mg_len = -1;
7a4c00b4 2147 }
bbce6d69 2148 return 0;
2149}
7a4c00b4 2150#endif /* USE_LOCALE_COLLATE */
bbce6d69 2151
7e8c5dac 2152/* Just clear the UTF-8 cache data. */
2153int
2154Perl_magic_setutf8(pTHX_ SV *sv, MAGIC *mg)
2155{
8772537c 2156 PERL_UNUSED_ARG(sv);
7e8c5dac 2157 Safefree(mg->mg_ptr); /* The mg_ptr holds the pos cache. */
2158 mg->mg_ptr = 0;
2159 mg->mg_len = -1; /* The mg_len holds the len cache. */
2160 return 0;
2161}
2162
bbce6d69 2163int
864dbfa3 2164Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
79072805 2165{
e1ec3a88 2166 register const char *s;
79072805 2167 I32 i;
8990e307 2168 STRLEN len;
79072805 2169 switch (*mg->mg_ptr) {
748a9306 2170 case '\001': /* ^A */
3280af22 2171 sv_setsv(PL_bodytarget, sv);
748a9306 2172 break;
49460fe6 2173 case '\003': /* ^C */
eb160463 2174 PL_minus_c = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
49460fe6 2175 break;
2176
79072805 2177 case '\004': /* ^D */
b4ab917c 2178#ifdef DEBUGGING
b83604b4 2179 s = SvPV_nolen_const(sv);
ddcf8bc1 2180 PL_debug = get_debug_opts(&s, 0) | DEBUG_TOP_FLAG;
79072805 2181 DEBUG_x(dump_all());
b4ab917c 2182#else
2183 PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | DEBUG_TOP_FLAG;
2184#endif
79072805 2185 break;
28f23441 2186 case '\005': /* ^E */
d0063567 2187 if (*(mg->mg_ptr+1) == '\0') {
cd39f2b6 2188#ifdef MACOS_TRADITIONAL
d0063567 2189 gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
28f23441 2190#else
cd39f2b6 2191# ifdef VMS
d0063567 2192 set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
048c1ddf 2193# else
cd39f2b6 2194# ifdef WIN32
d0063567 2195 SetLastError( SvIV(sv) );
cd39f2b6 2196# else
9fed8b87 2197# ifdef OS2
d0063567 2198 os2_setsyserrno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
9fed8b87 2199# else
d0063567 2200 /* will anyone ever use this? */
2201 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
cd39f2b6 2202# endif
048c1ddf 2203# endif
2204# endif
22fae026 2205#endif
d0063567 2206 }
2207 else if (strEQ(mg->mg_ptr+1, "NCODING")) {
2208 if (PL_encoding)
2209 SvREFCNT_dec(PL_encoding);
2210 if (SvOK(sv) || SvGMAGICAL(sv)) {
2211 PL_encoding = newSVsv(sv);
2212 }
2213 else {
2214 PL_encoding = Nullsv;
2215 }
2216 }
2217 break;
79072805 2218 case '\006': /* ^F */
3280af22 2219 PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 2220 break;
a0d0e21e 2221 case '\010': /* ^H */
3280af22 2222 PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
a0d0e21e 2223 break;
9d116dd7 2224 case '\011': /* ^I */ /* NOT \t in EBCDIC */
43c5f42d 2225 Safefree(PL_inplace);
2226 PL_inplace = SvOK(sv) ? savesvpv(sv) : Nullch;
da78da6e 2227 break;
28f23441 2228 case '\017': /* ^O */
ac27b0f5 2229 if (*(mg->mg_ptr+1) == '\0') {
43c5f42d 2230 Safefree(PL_osname);
2231 PL_osname = Nullch;
3511154c 2232 if (SvOK(sv)) {
2233 TAINT_PROPER("assigning to $^O");
2e0de35c 2234 PL_osname = savesvpv(sv);
3511154c 2235 }
ac27b0f5 2236 }
2237 else if (strEQ(mg->mg_ptr, "\017PEN")) {
2238 if (!PL_compiling.cop_io)
2239 PL_compiling.cop_io = newSVsv(sv);
2240 else
2241 sv_setsv(PL_compiling.cop_io,sv);
2242 }
28f23441 2243 break;
79072805 2244 case '\020': /* ^P */
3280af22 2245 PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
f2a7f298 2246 if (PL_perldb && !PL_DBsingle)
1ee4443e 2247 init_debugger();
79072805 2248 break;
2249 case '\024': /* ^T */
88e89b8a 2250#ifdef BIG_TIME
6b88bc9c 2251 PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
88e89b8a 2252#else
3280af22 2253 PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
88e89b8a 2254#endif
79072805 2255 break;
fde18df1 2256 case '\027': /* ^W & $^WARNING_BITS */
4438c4b7 2257 if (*(mg->mg_ptr+1) == '\0') {
2258 if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
2259 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
ac27b0f5 2260 PL_dowarn = (PL_dowarn & ~G_WARN_ON)
0453d815 2261 | (i ? G_WARN_ON : G_WARN_OFF) ;
4438c4b7 2262 }
599cee73 2263 }
0a378802 2264 else if (strEQ(mg->mg_ptr+1, "ARNING_BITS")) {
4438c4b7 2265 if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
d775746e 2266 if (!SvPOK(sv) && PL_localizing) {
2267 sv_setpvn(sv, WARN_NONEstring, WARNsize);
d3a7d8c7 2268 PL_compiling.cop_warnings = pWARN_NONE;
d775746e 2269 break;
2270 }
f4fc7782 2271 {
b5477537 2272 STRLEN len, i;
d3a7d8c7 2273 int accumulate = 0 ;
f4fc7782 2274 int any_fatals = 0 ;
b83604b4 2275 const char * const ptr = SvPV_const(sv, len) ;
f4fc7782 2276 for (i = 0 ; i < len ; ++i) {
2277 accumulate |= ptr[i] ;
2278 any_fatals |= (ptr[i] & 0xAA) ;
2279 }
d3a7d8c7 2280 if (!accumulate)
2281 PL_compiling.cop_warnings = pWARN_NONE;
f4fc7782 2282 else if (isWARN_on(sv, WARN_ALL) && !any_fatals) {
2283 PL_compiling.cop_warnings = pWARN_ALL;
2284 PL_dowarn |= G_WARN_ONCE ;
727405f8 2285 }
d3a7d8c7 2286 else {
2287 if (specialWARN(PL_compiling.cop_warnings))
2288 PL_compiling.cop_warnings = newSVsv(sv) ;
2289 else
2290 sv_setsv(PL_compiling.cop_warnings, sv);
2291 if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
2292 PL_dowarn |= G_WARN_ONCE ;
2293 }
f4fc7782 2294
d3a7d8c7 2295 }
4438c4b7 2296 }
971a9dd3 2297 }
79072805 2298 break;
2299 case '.':
3280af22 2300 if (PL_localizing) {
2301 if (PL_localizing == 1)
7766f137 2302 SAVESPTR(PL_last_in_gv);
748a9306 2303 }
3280af22 2304 else if (SvOK(sv) && GvIO(PL_last_in_gv))
632db599 2305 IoLINES(GvIOp(PL_last_in_gv)) = SvIV(sv);
79072805 2306 break;
2307 case '^':
3280af22 2308 Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
e1ec3a88 2309 s = IoTOP_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv);
7a5fd60d 2310 IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv,TRUE, SVt_PVIO);
79072805 2311 break;
2312 case '~':
3280af22 2313 Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
e1ec3a88 2314 s = IoFMT_NAME(GvIOp(PL_defoutgv)) = savesvpv(sv);
7a5fd60d 2315 IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchsv(sv,TRUE, SVt_PVIO);
79072805 2316 break;
2317 case '=':
632db599 2318 IoPAGE_LEN(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 2319 break;
2320 case '-':
632db599 2321 IoLINES_LEFT(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
3280af22 2322 if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
2323 IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
79072805 2324 break;
2325 case '%':
632db599 2326 IoPAGE(GvIOp(PL_defoutgv)) = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 2327 break;
2328 case '|':
4b65379b 2329 {
8772537c 2330 IO * const io = GvIOp(PL_defoutgv);
720f287d 2331 if(!io)
2332 break;
4b65379b 2333 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
2334 IoFLAGS(io) &= ~IOf_FLUSH;
2335 else {
2336 if (!(IoFLAGS(io) & IOf_FLUSH)) {
2337 PerlIO *ofp = IoOFP(io);
2338 if (ofp)
2339 (void)PerlIO_flush(ofp);
2340 IoFLAGS(io) |= IOf_FLUSH;
2341 }
2342 }
79072805 2343 }
2344 break;
79072805 2345 case '/':
3280af22 2346 SvREFCNT_dec(PL_rs);
8bfdd7d9 2347 PL_rs = newSVsv(sv);
79072805 2348 break;
2349 case '\\':
7889fe52 2350 if (PL_ors_sv)
2351 SvREFCNT_dec(PL_ors_sv);
009c130f 2352 if (SvOK(sv) || SvGMAGICAL(sv)) {
7889fe52 2353 PL_ors_sv = newSVsv(sv);
009c130f 2354 }
e3c19b7b 2355 else {
7889fe52 2356 PL_ors_sv = Nullsv;
e3c19b7b 2357 }
79072805 2358 break;
2359 case ',':
7889fe52 2360 if (PL_ofs_sv)
2361 SvREFCNT_dec(PL_ofs_sv);
2362 if (SvOK(sv) || SvGMAGICAL(sv)) {
2363 PL_ofs_sv = newSVsv(sv);
2364 }
2365 else {
2366 PL_ofs_sv = Nullsv;
2367 }
79072805 2368 break;
79072805 2369 case '[':
3280af22 2370 PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 2371 break;
2372 case '?':
ff0cee69 2373#ifdef COMPLEX_STATUS
6b88bc9c 2374 if (PL_localizing == 2) {
2375 PL_statusvalue = LvTARGOFF(sv);
2376 PL_statusvalue_vms = LvTARGLEN(sv);
ff0cee69 2377 }
2378 else
2379#endif
2380#ifdef VMSISH_STATUS
2381 if (VMSISH_STATUS)
fb38d079 2382 STATUS_NATIVE_CHILD_SET((U32)SvIV(sv));
ff0cee69 2383 else
2384#endif
fb38d079 2385 STATUS_UNIX_EXIT_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 2386 break;
2387 case '!':
93189314 2388 {
2389#ifdef VMS
2390# define PERL_VMS_BANG vaxc$errno
2391#else
2392# define PERL_VMS_BANG 0
2393#endif
91487cfc 2394 SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
93189314 2395 (SvIV(sv) == EVMSERR) ? 4 : PERL_VMS_BANG);
2396 }
79072805 2397 break;
2398 case '<':
3280af22 2399 PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2400 if (PL_delaymagic) {
2401 PL_delaymagic |= DM_RUID;
79072805 2402 break; /* don't do magic till later */
2403 }
2404#ifdef HAS_SETRUID
b28d0864 2405 (void)setruid((Uid_t)PL_uid);
79072805 2406#else
2407#ifdef HAS_SETREUID
3280af22 2408 (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
748a9306 2409#else
85e6fe83 2410#ifdef HAS_SETRESUID
b28d0864 2411 (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
79072805 2412#else
75870ed3 2413 if (PL_uid == PL_euid) { /* special case $< = $> */
2414#ifdef PERL_DARWIN
2415 /* workaround for Darwin's setuid peculiarity, cf [perl #24122] */
2416 if (PL_uid != 0 && PerlProc_getuid() == 0)
2417 (void)PerlProc_setuid(0);
2418#endif
b28d0864 2419 (void)PerlProc_setuid(PL_uid);
75870ed3 2420 } else {
d8eceb89 2421 PL_uid = PerlProc_getuid();
cea2e8a9 2422 Perl_croak(aTHX_ "setruid() not implemented");
a0d0e21e 2423 }
79072805 2424#endif
2425#endif
85e6fe83 2426#endif
d8eceb89 2427 PL_uid = PerlProc_getuid();
3280af22 2428 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805 2429 break;
2430 case '>':
3280af22 2431 PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2432 if (PL_delaymagic) {
2433 PL_delaymagic |= DM_EUID;
79072805 2434 break; /* don't do magic till later */
2435 }
2436#ifdef HAS_SETEUID
3280af22 2437 (void)seteuid((Uid_t)PL_euid);
79072805 2438#else
2439#ifdef HAS_SETREUID
b28d0864 2440 (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
85e6fe83 2441#else
2442#ifdef HAS_SETRESUID
6b88bc9c 2443 (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
79072805 2444#else
b28d0864 2445 if (PL_euid == PL_uid) /* special case $> = $< */
2446 PerlProc_setuid(PL_euid);
a0d0e21e 2447 else {
e8ee3774 2448 PL_euid = PerlProc_geteuid();
cea2e8a9 2449 Perl_croak(aTHX_ "seteuid() not implemented");
a0d0e21e 2450 }
79072805 2451#endif
2452#endif
85e6fe83 2453#endif
d8eceb89 2454 PL_euid = PerlProc_geteuid();
3280af22 2455 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805 2456 break;
2457 case '(':
3280af22 2458 PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
2459 if (PL_delaymagic) {
2460 PL_delaymagic |= DM_RGID;
79072805 2461 break; /* don't do magic till later */
2462 }
2463#ifdef HAS_SETRGID
b28d0864 2464 (void)setrgid((Gid_t)PL_gid);
79072805 2465#else
2466#ifdef HAS_SETREGID
3280af22 2467 (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
85e6fe83 2468#else
2469#ifdef HAS_SETRESGID
b28d0864 2470 (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
79072805 2471#else
b28d0864 2472 if (PL_gid == PL_egid) /* special case $( = $) */
2473 (void)PerlProc_setgid(PL_gid);
748a9306 2474 else {
d8eceb89 2475 PL_gid = PerlProc_getgid();
cea2e8a9 2476 Perl_croak(aTHX_ "setrgid() not implemented");
748a9306 2477 }
79072805 2478#endif
2479#endif
85e6fe83 2480#endif
d8eceb89 2481 PL_gid = PerlProc_getgid();
3280af22 2482 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805 2483 break;
2484 case ')':
5cd24f17 2485#ifdef HAS_SETGROUPS
2486 {
b83604b4 2487 const char *p = SvPV_const(sv, len);
5cd24f17 2488 Groups_t gary[NGROUPS];
2489
5cd24f17 2490 while (isSPACE(*p))
2491 ++p;
2d4389e4 2492 PL_egid = Atol(p);
5cd24f17 2493 for (i = 0; i < NGROUPS; ++i) {
2494 while (*p && !isSPACE(*p))
2495 ++p;
2496 while (isSPACE(*p))
2497 ++p;
2498 if (!*p)
2499 break;
2d4389e4 2500 gary[i] = Atol(p);
5cd24f17 2501 }
8cc95fdb 2502 if (i)
2503 (void)setgroups(i, gary);
5cd24f17 2504 }
2505#else /* HAS_SETGROUPS */
b28d0864 2506 PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
5cd24f17 2507#endif /* HAS_SETGROUPS */
3280af22 2508 if (PL_delaymagic) {
2509 PL_delaymagic |= DM_EGID;
79072805 2510 break; /* don't do magic till later */
2511 }
2512#ifdef HAS_SETEGID
3280af22 2513 (void)setegid((Gid_t)PL_egid);
79072805 2514#else
2515#ifdef HAS_SETREGID
b28d0864 2516 (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
85e6fe83 2517#else
2518#ifdef HAS_SETRESGID
b28d0864 2519 (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
79072805 2520#else
b28d0864 2521 if (PL_egid == PL_gid) /* special case $) = $( */
2522 (void)PerlProc_setgid(PL_egid);
748a9306 2523 else {
d8eceb89 2524 PL_egid = PerlProc_getegid();
cea2e8a9 2525 Perl_croak(aTHX_ "setegid() not implemented");
748a9306 2526 }
79072805 2527#endif
2528#endif
85e6fe83 2529#endif
d8eceb89 2530 PL_egid = PerlProc_getegid();
3280af22 2531 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805 2532 break;
2533 case ':':
2d8e6c8d 2534 PL_chopset = SvPV_force(sv,len);
79072805 2535 break;
cd39f2b6 2536#ifndef MACOS_TRADITIONAL
79072805 2537 case '0':
e2975953 2538 LOCK_DOLLARZERO_MUTEX;
4bc88a62 2539#ifdef HAS_SETPROCTITLE
2540 /* The BSDs don't show the argv[] in ps(1) output, they
2541 * show a string from the process struct and provide
2542 * the setproctitle() routine to manipulate that. */
2543 {
b83604b4 2544 s = SvPV_const(sv, len);
98b76f99 2545# if __FreeBSD_version > 410001
9aad2c0e 2546 /* The leading "-" removes the "perl: " prefix,
4bc88a62 2547 * but not the "(perl) suffix from the ps(1)
2548 * output, because that's what ps(1) shows if the
2549 * argv[] is modified. */
6f2ad931 2550 setproctitle("-%s", s);
9aad2c0e 2551# else /* old FreeBSDs, NetBSD, OpenBSD, anyBSD */
4bc88a62 2552 /* This doesn't really work if you assume that
2553 * $0 = 'foobar'; will wipe out 'perl' from the $0
2554 * because in ps(1) output the result will be like
2555 * sprintf("perl: %s (perl)", s)
2556 * I guess this is a security feature:
2557 * one (a user process) cannot get rid of the original name.
2558 * --jhi */
2559 setproctitle("%s", s);
2560# endif
2561 }
2562#endif
17aa7f3d 2563#if defined(__hpux) && defined(PSTAT_SETCMD)
2564 {
2565 union pstun un;
b83604b4 2566 s = SvPV_const(sv, len);
6867be6d 2567 un.pst_command = (char *)s;
17aa7f3d 2568 pstat(PSTAT_SETCMD, un, len, 0, 0);
2569 }
2570#endif
3cb9023d 2571 /* PL_origalen is set in perl_parse(). */
a0d0e21e 2572 s = SvPV_force(sv,len);
6f698202 2573 if (len >= (STRLEN)PL_origalen-1) {
2574 /* Longer than original, will be truncated. We assume that
2575 * PL_origalen bytes are available. */
2576 Copy(s, PL_origargv[0], PL_origalen-1, char);
79072805 2577 }
2578 else {
54bfe034 2579 /* Shorter than original, will be padded. */
2580 Copy(s, PL_origargv[0], len, char);
2581 PL_origargv[0][len] = 0;
2582 memset(PL_origargv[0] + len + 1,
2583 /* Is the space counterintuitive? Yes.
2584 * (You were expecting \0?)
3cb9023d 2585 * Does it work? Seems to. (In Linux 2.4.20 at least.)
54bfe034 2586 * --jhi */
2587 (int)' ',
2588 PL_origalen - len - 1);
79072805 2589 }
ad7eccf4 2590 PL_origargv[0][PL_origalen-1] = 0;
2591 for (i = 1; i < PL_origargc; i++)
2592 PL_origargv[i] = 0;
e2975953 2593 UNLOCK_DOLLARZERO_MUTEX;
79072805 2594 break;
cd39f2b6 2595#endif
79072805 2596 }
2597 return 0;
2598}
2599
2600I32
35a4481c 2601Perl_whichsig(pTHX_ const char *sig)
79072805 2602{
aadb217d 2603 register char* const* sigv;
79072805 2604
aadb217d 2605 for (sigv = (char* const*)PL_sig_name; *sigv; sigv++)
79072805 2606 if (strEQ(sig,*sigv))
aadb217d 2607 return PL_sig_num[sigv - (char* const*)PL_sig_name];
79072805 2608#ifdef SIGCLD
2609 if (strEQ(sig,"CHLD"))
2610 return SIGCLD;
2611#endif
2612#ifdef SIGCHLD
2613 if (strEQ(sig,"CLD"))
2614 return SIGCHLD;
2615#endif
7f1236c0 2616 return -1;
79072805 2617}
2618
ecfc5424 2619Signal_t
1e82f5a6 2620#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
8aad04aa 2621Perl_sighandler(int sig, ...)
1e82f5a6 2622#else
2623Perl_sighandler(int sig)
2624#endif
79072805 2625{
1018e26f 2626#ifdef PERL_GET_SIG_CONTEXT
2627 dTHXa(PERL_GET_SIG_CONTEXT);
71d280e3 2628#else
cea2e8a9 2629 dTHX;
71d280e3 2630#endif
79072805 2631 dSP;
00d579c5 2632 GV *gv = Nullgv;
8772537c 2633 SV *sv = Nullsv;
2634 SV * const tSv = PL_Sv;
00d579c5 2635 CV *cv = Nullcv;
533c011a 2636 OP *myop = PL_op;
84902520 2637 U32 flags = 0;
8772537c 2638 XPV * const tXpv = PL_Xpv;
71d280e3 2639
3280af22 2640 if (PL_savestack_ix + 15 <= PL_savestack_max)
84902520 2641 flags |= 1;
3280af22 2642 if (PL_markstack_ptr < PL_markstack_max - 2)
84902520 2643 flags |= 4;
3280af22 2644 if (PL_scopestack_ix < PL_scopestack_max - 3)
84902520 2645 flags |= 16;
2646
727405f8 2647 if (!PL_psig_ptr[sig]) {
99ef548b 2648 PerlIO_printf(Perl_error_log, "Signal SIG%s received, but no signal handler set.\n",
727405f8 2649 PL_sig_name[sig]);
2650 exit(sig);
2651 }
ff0cee69 2652
84902520 2653 /* Max number of items pushed there is 3*n or 4. We cannot fix
2654 infinity, so we fix 4 (in fact 5): */
2655 if (flags & 1) {
3280af22 2656 PL_savestack_ix += 5; /* Protect save in progress. */
8772537c 2657 SAVEDESTRUCTOR_X(S_unwind_handler_stack, (void*)&flags);
84902520 2658 }
ac27b0f5 2659 if (flags & 4)
3280af22 2660 PL_markstack_ptr++; /* Protect mark. */
84902520 2661 if (flags & 16)
3280af22 2662 PL_scopestack_ix += 1;
84902520 2663 /* sv_2cv is too complicated, try a simpler variant first: */
ac27b0f5 2664 if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
8772537c 2665 || SvTYPE(cv) != SVt_PVCV) {
2666 HV *st;
22c35a8c 2667 cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
8772537c 2668 }
84902520 2669
a0d0e21e 2670 if (!cv || !CvROOT(cv)) {
599cee73 2671 if (ckWARN(WARN_SIGNAL))
9014280d 2672 Perl_warner(aTHX_ packWARN(WARN_SIGNAL), "SIG%s handler \"%s\" not defined.\n",
22c35a8c 2673 PL_sig_name[sig], (gv ? GvENAME(gv)
00d579c5 2674 : ((cv && CvGV(cv))
2675 ? GvENAME(CvGV(cv))
2676 : "__ANON__")));
2677 goto cleanup;
79072805 2678 }
2679
22c35a8c 2680 if(PL_psig_name[sig]) {
2681 sv = SvREFCNT_inc(PL_psig_name[sig]);
84902520 2682 flags |= 64;
df3728a2 2683#if !defined(PERL_IMPLICIT_CONTEXT)
27da23d5 2684 PL_sig_sv = sv;
df3728a2 2685#endif
84902520 2686 } else {
ff0cee69 2687 sv = sv_newmortal();
22c35a8c 2688 sv_setpv(sv,PL_sig_name[sig]);
88e89b8a 2689 }
e336de0d 2690
e788e7d3 2691 PUSHSTACKi(PERLSI_SIGNAL);
924508f0 2692 PUSHMARK(SP);
79072805 2693 PUSHs(sv);
8aad04aa 2694#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
2695 {
2696 struct sigaction oact;
2697
2698 if (sigaction(sig, 0, &oact) == 0 && oact.sa_flags & SA_SIGINFO) {
2699 siginfo_t *sip;
2700 va_list args;
2701
2702 va_start(args, sig);
2703 sip = (siginfo_t*)va_arg(args, siginfo_t*);
2704 if (sip) {
2705 HV *sih = newHV();
2706 SV *rv = newRV_noinc((SV*)sih);
2707 /* The siginfo fields signo, code, errno, pid, uid,
2708 * addr, status, and band are defined by POSIX/SUSv3. */
2709 hv_store(sih, "signo", 5, newSViv(sip->si_signo), 0);
2710 hv_store(sih, "code", 4, newSViv(sip->si_code), 0);
79dec0f4 2711#if 0 /* XXX TODO: Configure scan for the existence of these, but even that does not help if the SA_SIGINFO is not implemented according to the spec. */
ea1bde16 2712 hv_store(sih, "errno", 5, newSViv(sip->si_errno), 0);
79dec0f4 2713 hv_store(sih, "status", 6, newSViv(sip->si_status), 0);
8aad04aa 2714 hv_store(sih, "uid", 3, newSViv(sip->si_uid), 0);
2715 hv_store(sih, "pid", 3, newSViv(sip->si_pid), 0);
2716 hv_store(sih, "addr", 4, newSVuv(PTR2UV(sip->si_addr)), 0);
8aad04aa 2717 hv_store(sih, "band", 4, newSViv(sip->si_band), 0);
79dec0f4 2718#endif
8aad04aa 2719 EXTEND(SP, 2);
2720 PUSHs((SV*)rv);
2721 PUSHs(newSVpv((void*)sip, sizeof(*sip)));
2722 }
b4552a27 2723
31427afe 2724 va_end(args);
8aad04aa 2725 }
2726 }
2727#endif
79072805 2728 PUTBACK;
a0d0e21e 2729
1b266415 2730 call_sv((SV*)cv, G_DISCARD|G_EVAL);
79072805 2731
d3acc0f7 2732 POPSTACK;
1b266415 2733 if (SvTRUE(ERRSV)) {
1d615522 2734#ifndef PERL_MICRO
983dbef6 2735#ifdef HAS_SIGPROCMASK
1b266415 2736 /* Handler "died", for example to get out of a restart-able read().
2737 * Before we re-do that on its behalf re-enable the signal which was
2738 * blocked by the system when we entered.
2739 */
2740 sigset_t set;
2741 sigemptyset(&set);
2742 sigaddset(&set,sig);
2743 sigprocmask(SIG_UNBLOCK, &set, NULL);
2744#else
2745 /* Not clear if this will work */
2746 (void)rsignal(sig, SIG_IGN);
5c1546dc 2747 (void)rsignal(sig, PL_csighandlerp);
1b266415 2748#endif
1d615522 2749#endif /* !PERL_MICRO */
c3bdd826 2750 Perl_die(aTHX_ Nullch);
1b266415 2751 }
00d579c5 2752cleanup:
84902520 2753 if (flags & 1)
3280af22 2754 PL_savestack_ix -= 8; /* Unprotect save in progress. */
ac27b0f5 2755 if (flags & 4)
3280af22 2756 PL_markstack_ptr--;
84902520 2757 if (flags & 16)
3280af22 2758 PL_scopestack_ix -= 1;
84902520 2759 if (flags & 64)
2760 SvREFCNT_dec(sv);
533c011a 2761 PL_op = myop; /* Apparently not needed... */
ac27b0f5 2762
3280af22 2763 PL_Sv = tSv; /* Restore global temporaries. */
2764 PL_Xpv = tXpv;
53bb94e2 2765 return;
79072805 2766}
4e35701f 2767
2768
51371543 2769static void
8772537c 2770S_restore_magic(pTHX_ const void *p)
51371543 2771{
8772537c 2772 MGS* const mgs = SSPTR(PTR2IV(p), MGS*);
2773 SV* const sv = mgs->mgs_sv;
51371543 2774
2775 if (!sv)
2776 return;
2777
2778 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
2779 {
f8c7b90f 2780#ifdef PERL_OLD_COPY_ON_WRITE
f9701176 2781 /* While magic was saved (and off) sv_setsv may well have seen
2782 this SV as a prime candidate for COW. */
2783 if (SvIsCOW(sv))
e424a81e 2784 sv_force_normal_flags(sv, 0);
f9701176 2785#endif
2786
51371543 2787 if (mgs->mgs_flags)
2788 SvFLAGS(sv) |= mgs->mgs_flags;
2789 else
2790 mg_magical(sv);
2b77b520 2791 if (SvGMAGICAL(sv)) {
2792 /* downgrade public flags to private,
2793 and discard any other private flags */
2794
2795 U32 public = SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK);
2796 if (public) {
2797 SvFLAGS(sv) &= ~( public | SVp_IOK|SVp_NOK|SVp_POK );
2798 SvFLAGS(sv) |= ( public << PRIVSHIFT );
2799 }
2800 }
51371543 2801 }
2802
2803 mgs->mgs_sv = NULL; /* mark the MGS structure as restored */
2804
2805 /* If we're still on top of the stack, pop us off. (That condition
2806 * will be satisfied if restore_magic was called explicitly, but *not*
2807 * if it's being called via leave_scope.)
2808 * The reason for doing this is that otherwise, things like sv_2cv()
2809 * may leave alloc gunk on the savestack, and some code
2810 * (e.g. sighandler) doesn't expect that...
2811 */
2812 if (PL_savestack_ix == mgs->mgs_ss_ix)
2813 {
2814 I32 popval = SSPOPINT;
c76ac1ee 2815 assert(popval == SAVEt_DESTRUCTOR_X);
51371543 2816 PL_savestack_ix -= 2;
2817 popval = SSPOPINT;
2818 assert(popval == SAVEt_ALLOC);
2819 popval = SSPOPINT;
2820 PL_savestack_ix -= popval;
2821 }
2822
2823}
2824
2825static void
8772537c 2826S_unwind_handler_stack(pTHX_ const void *p)
51371543 2827{
27da23d5 2828 dVAR;
e1ec3a88 2829 const U32 flags = *(const U32*)p;
51371543 2830
2831 if (flags & 1)
2832 PL_savestack_ix -= 5; /* Unprotect save in progress. */
2833 /* cxstack_ix-- Not needed, die already unwound it. */
df3728a2 2834#if !defined(PERL_IMPLICIT_CONTEXT)
51371543 2835 if (flags & 64)
27da23d5 2836 SvREFCNT_dec(PL_sig_sv);
df3728a2 2837#endif
51371543 2838}
1018e26f 2839
66610fdd 2840/*
2841 * Local variables:
2842 * c-indentation-style: bsd
2843 * c-basic-offset: 4
2844 * indent-tabs-mode: t
2845 * End:
2846 *
37442d52 2847 * ex: set ts=8 sts=4 sw=4 noet:
2848 */