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