This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
More -Wall sweeping.
[perl5.git] / mg.c
CommitLineData
a0d0e21e 1/* mg.c
79072805 2 *
bc89e66f 3 * Copyright (c) 1991-2001, Larry Wall
79072805
LW
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
a0d0e21e
LW
8 */
9
10/*
11 * "Sam sat on the ground and put his head in his hands. 'I wish I had never
12 * come here, and I don't want to see no more magic,' he said, and fell silent."
79072805
LW
13 */
14
15#include "EXTERN.h"
864dbfa3 16#define PERL_IN_MG_C
79072805
LW
17#include "perl.h"
18
5cd24f17 19#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
188ea221
CS
20# ifndef NGROUPS
21# define NGROUPS 32
22# endif
b7953727
JH
23# ifdef I_GRP
24# include <grp.h>
25# endif
188ea221
CS
26#endif
27
51371543
GS
28static void restore_magic(pTHXo_ void *p);
29static void unwind_handler_stack(pTHXo_ void *p);
30
c07a80fd 31/*
32 * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
33 */
34
35struct magic_state {
36 SV* mgs_sv;
37 U32 mgs_flags;
455ece5e 38 I32 mgs_ss_ix;
c07a80fd 39};
455ece5e 40/* MGS is typedef'ed to struct magic_state in perl.h */
76e3520e
GS
41
42STATIC void
cea2e8a9 43S_save_magic(pTHX_ I32 mgs_ix, SV *sv)
c07a80fd 44{
455ece5e 45 MGS* mgs;
c07a80fd 46 assert(SvMAGICAL(sv));
47
c76ac1ee 48 SAVEDESTRUCTOR_X(restore_magic, (void*)mgs_ix);
455ece5e
AD
49
50 mgs = SSPTR(mgs_ix, MGS*);
c07a80fd 51 mgs->mgs_sv = sv;
52 mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
455ece5e 53 mgs->mgs_ss_ix = PL_savestack_ix; /* points after the saved destructor */
c07a80fd 54
55 SvMAGICAL_off(sv);
56 SvREADONLY_off(sv);
06759ea0 57 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_NOK|SVp_POK)) >> PRIVSHIFT;
c07a80fd 58}
59
954c1994
GS
60/*
61=for apidoc mg_magical
62
63Turns on the magical status of an SV. See C<sv_magic>.
64
65=cut
66*/
67
8990e307 68void
864dbfa3 69Perl_mg_magical(pTHX_ SV *sv)
8990e307
LW
70{
71 MAGIC* mg;
72 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
73 MGVTBL* vtbl = mg->mg_virtual;
74 if (vtbl) {
2b260de0 75 if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
8990e307
LW
76 SvGMAGICAL_on(sv);
77 if (vtbl->svt_set)
78 SvSMAGICAL_on(sv);
2b260de0 79 if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
8990e307
LW
80 SvRMAGICAL_on(sv);
81 }
82 }
83}
84
954c1994
GS
85/*
86=for apidoc mg_get
87
88Do magic after a value is retrieved from the SV. See C<sv_magic>.
89
90=cut
91*/
92
79072805 93int
864dbfa3 94Perl_mg_get(pTHX_ SV *sv)
79072805 95{
455ece5e 96 I32 mgs_ix;
79072805 97 MAGIC* mg;
c6496cc7 98 MAGIC** mgp;
760ac839 99 int mgp_valid = 0;
463ee0b2 100
455ece5e
AD
101 mgs_ix = SSNEW(sizeof(MGS));
102 save_magic(mgs_ix, sv);
463ee0b2 103
c6496cc7 104 mgp = &SvMAGIC(sv);
105 while ((mg = *mgp) != 0) {
79072805 106 MGVTBL* vtbl = mg->mg_virtual;
2b260de0 107 if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
316ad4fe 108 CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
c6496cc7 109 /* Ignore this magic if it's been deleted */
48e43a1c
CS
110 if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
111 (mg->mg_flags & MGf_GSKIP))
455ece5e 112 (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
a0d0e21e 113 }
c6496cc7 114 /* Advance to next magic (complicated by possible deletion) */
760ac839 115 if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
c6496cc7 116 mgp = &mg->mg_moremagic;
760ac839
LW
117 mgp_valid = 1;
118 }
119 else
120 mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
79072805 121 }
463ee0b2 122
51371543 123 restore_magic(aTHXo_ (void*)mgs_ix);
79072805
LW
124 return 0;
125}
126
954c1994
GS
127/*
128=for apidoc mg_set
129
130Do magic after a value is assigned to the SV. See C<sv_magic>.
131
132=cut
133*/
134
79072805 135int
864dbfa3 136Perl_mg_set(pTHX_ SV *sv)
79072805 137{
455ece5e 138 I32 mgs_ix;
79072805 139 MAGIC* mg;
463ee0b2
LW
140 MAGIC* nextmg;
141
455ece5e
AD
142 mgs_ix = SSNEW(sizeof(MGS));
143 save_magic(mgs_ix, sv);
463ee0b2
LW
144
145 for (mg = SvMAGIC(sv); mg; mg = nextmg) {
79072805 146 MGVTBL* vtbl = mg->mg_virtual;
463ee0b2 147 nextmg = mg->mg_moremagic; /* it may delete itself */
a0d0e21e
LW
148 if (mg->mg_flags & MGf_GSKIP) {
149 mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
455ece5e 150 (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
a0d0e21e 151 }
2b260de0 152 if (vtbl && vtbl->svt_set)
fc0dc3b3 153 CALL_FPTR(vtbl->svt_set)(aTHX_ sv, mg);
79072805 154 }
463ee0b2 155
51371543 156 restore_magic(aTHXo_ (void*)mgs_ix);
79072805
LW
157 return 0;
158}
159
954c1994
GS
160/*
161=for apidoc mg_length
162
163Report on the SV's length. See C<sv_magic>.
164
165=cut
166*/
167
79072805 168U32
864dbfa3 169Perl_mg_length(pTHX_ SV *sv)
79072805
LW
170{
171 MAGIC* mg;
748a9306 172 char *junk;
463ee0b2 173 STRLEN len;
463ee0b2 174
79072805
LW
175 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
176 MGVTBL* vtbl = mg->mg_virtual;
2b260de0 177 if (vtbl && vtbl->svt_len) {
455ece5e 178 I32 mgs_ix;
48e43a1c 179
455ece5e
AD
180 mgs_ix = SSNEW(sizeof(MGS));
181 save_magic(mgs_ix, sv);
a0d0e21e 182 /* omit MGf_GSKIP -- not changed here */
fc0dc3b3 183 len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
51371543 184 restore_magic(aTHXo_ (void*)mgs_ix);
85e6fe83
LW
185 return len;
186 }
187 }
188
748a9306 189 junk = SvPV(sv, len);
463ee0b2 190 return len;
79072805
LW
191}
192
93965878 193I32
864dbfa3 194Perl_mg_size(pTHX_ SV *sv)
93965878
NIS
195{
196 MAGIC* mg;
197 I32 len;
ac27b0f5 198
93965878
NIS
199 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
200 MGVTBL* vtbl = mg->mg_virtual;
2b260de0 201 if (vtbl && vtbl->svt_len) {
455ece5e
AD
202 I32 mgs_ix;
203
204 mgs_ix = SSNEW(sizeof(MGS));
205 save_magic(mgs_ix, sv);
93965878 206 /* omit MGf_GSKIP -- not changed here */
fc0dc3b3 207 len = CALL_FPTR(vtbl->svt_len)(aTHX_ sv, mg);
51371543 208 restore_magic(aTHXo_ (void*)mgs_ix);
93965878
NIS
209 return len;
210 }
211 }
212
213 switch(SvTYPE(sv)) {
214 case SVt_PVAV:
215 len = AvFILLp((AV *) sv); /* Fallback to non-tied array */
216 return len;
217 case SVt_PVHV:
218 /* FIXME */
219 default:
cea2e8a9 220 Perl_croak(aTHX_ "Size magic not implemented");
93965878
NIS
221 break;
222 }
223 return 0;
224}
225
954c1994
GS
226/*
227=for apidoc mg_clear
228
229Clear something magical that the SV represents. See C<sv_magic>.
230
231=cut
232*/
233
79072805 234int
864dbfa3 235Perl_mg_clear(pTHX_ SV *sv)
79072805 236{
455ece5e 237 I32 mgs_ix;
79072805 238 MAGIC* mg;
463ee0b2 239
455ece5e
AD
240 mgs_ix = SSNEW(sizeof(MGS));
241 save_magic(mgs_ix, sv);
463ee0b2 242
79072805
LW
243 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
244 MGVTBL* vtbl = mg->mg_virtual;
a0d0e21e
LW
245 /* omit GSKIP -- never set here */
246
2b260de0 247 if (vtbl && vtbl->svt_clear)
fc0dc3b3 248 CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
79072805 249 }
463ee0b2 250
51371543 251 restore_magic(aTHXo_ (void*)mgs_ix);
79072805
LW
252 return 0;
253}
254
954c1994
GS
255/*
256=for apidoc mg_find
257
258Finds the magic pointer for type matching the SV. See C<sv_magic>.
259
260=cut
261*/
262
93a17b20 263MAGIC*
864dbfa3 264Perl_mg_find(pTHX_ SV *sv, int type)
93a17b20
LW
265{
266 MAGIC* mg;
3f8f4626
DC
267 if (!sv)
268 return 0;
93a17b20
LW
269 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
270 if (mg->mg_type == type)
271 return mg;
272 }
273 return 0;
274}
275
954c1994
GS
276/*
277=for apidoc mg_copy
278
279Copies the magic from one SV to another. See C<sv_magic>.
280
281=cut
282*/
283
79072805 284int
864dbfa3 285Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
79072805 286{
463ee0b2 287 int count = 0;
79072805 288 MAGIC* mg;
463ee0b2
LW
289 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
290 if (isUPPER(mg->mg_type)) {
33c27489 291 sv_magic(nsv,
14befaf4
DM
292 mg->mg_type == PERL_MAGIC_tied ? SvTIED_obj(sv, mg) :
293 (mg->mg_type == PERL_MAGIC_regdata && mg->mg_obj)
294 ? sv : mg->mg_obj,
33c27489 295 toLOWER(mg->mg_type), key, klen);
463ee0b2 296 count++;
79072805 297 }
79072805 298 }
463ee0b2 299 return count;
79072805
LW
300}
301
954c1994
GS
302/*
303=for apidoc mg_free
304
305Free any magic storage used by the SV. See C<sv_magic>.
306
307=cut
308*/
309
79072805 310int
864dbfa3 311Perl_mg_free(pTHX_ SV *sv)
79072805
LW
312{
313 MAGIC* mg;
314 MAGIC* moremagic;
315 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
316 MGVTBL* vtbl = mg->mg_virtual;
317 moremagic = mg->mg_moremagic;
2b260de0 318 if (vtbl && vtbl->svt_free)
fc0dc3b3 319 CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
14befaf4 320 if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
565764a8 321 if (mg->mg_len >= 0)
88e89b8a 322 Safefree(mg->mg_ptr);
565764a8 323 else if (mg->mg_len == HEf_SVKEY)
88e89b8a 324 SvREFCNT_dec((SV*)mg->mg_ptr);
d460ef45 325 }
85e6fe83 326 if (mg->mg_flags & MGf_REFCOUNTED)
8990e307 327 SvREFCNT_dec(mg->mg_obj);
79072805
LW
328 Safefree(mg);
329 }
330 SvMAGIC(sv) = 0;
331 return 0;
332}
333
d460ef45 334
79072805
LW
335#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
336#include <signal.h>
337#endif
338
942e002e 339U32
864dbfa3 340Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
6cef1e77 341{
6cef1e77 342 register REGEXP *rx;
6cef1e77 343
8f580fb8
IZ
344 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
345 if (mg->mg_obj) /* @+ */
346 return rx->nparens;
347 else /* @- */
348 return rx->lastparen;
349 }
ac27b0f5 350
942e002e 351 return (U32)-1;
6cef1e77
IZ
352}
353
354int
864dbfa3 355Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
6cef1e77 356{
6cef1e77 357 register I32 paren;
cf93c79d 358 register I32 s;
6cef1e77
IZ
359 register I32 i;
360 register REGEXP *rx;
cf93c79d 361 I32 t;
6cef1e77
IZ
362
363 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
364 paren = mg->mg_len;
365 if (paren < 0)
366 return 0;
367 if (paren <= rx->nparens &&
cf93c79d
IZ
368 (s = rx->startp[paren]) != -1 &&
369 (t = rx->endp[paren]) != -1)
6cef1e77
IZ
370 {
371 if (mg->mg_obj) /* @+ */
cf93c79d 372 i = t;
6cef1e77 373 else /* @- */
cf93c79d 374 i = s;
1aa99e6b
IH
375
376 if (i > 0 && DO_UTF8(PL_reg_sv)) {
377 char *b = rx->subbeg;
378 i = Perl_utf8_length(aTHX_ (U8*)b, (U8*)(b+i));
379 }
6cef1e77
IZ
380 sv_setiv(sv,i);
381 }
382 }
383 return 0;
384}
385
e4b89193 386int
a29d06ed
MG
387Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg)
388{
a29d06ed 389 Perl_croak(aTHX_ PL_no_modify);
e4b89193
GS
390 /* NOT REACHED */
391 return 0;
a29d06ed
MG
392}
393
93a17b20 394U32
864dbfa3 395Perl_magic_len(pTHX_ SV *sv, MAGIC *mg)
93a17b20
LW
396{
397 register I32 paren;
93a17b20 398 register I32 i;
d9f97599 399 register REGEXP *rx;
a197cbdd 400 I32 s1, t1;
93a17b20
LW
401
402 switch (*mg->mg_ptr) {
403 case '1': case '2': case '3': case '4':
404 case '5': case '6': case '7': case '8': case '9': case '&':
3280af22 405 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d 406
ffc61ed2 407 paren = atoi(mg->mg_ptr); /* $& is in [0] */
93a17b20 408 getparen:
d9f97599 409 if (paren <= rx->nparens &&
cf93c79d
IZ
410 (s1 = rx->startp[paren]) != -1 &&
411 (t1 = rx->endp[paren]) != -1)
bbce6d69 412 {
cf93c79d 413 i = t1 - s1;
a197cbdd 414 getlen:
ffc61ed2
JH
415 if (i > 0 && DO_UTF8(PL_reg_sv)) {
416 char *s = rx->subbeg + s1;
a197cbdd 417 char *send = rx->subbeg + t1;
ffc61ed2 418
60425c38
JH
419 i = t1 - s1;
420 if (is_utf8_string((U8*)s, i))
421 i = Perl_utf8_length(aTHX_ (U8*)s, (U8*)send);
a197cbdd 422 }
ffc61ed2 423 if (i < 0)
0844c848 424 Perl_croak(aTHX_ "panic: magic_len: %"IVdf, (IV)i);
ffc61ed2 425 return i;
93a17b20 426 }
93a17b20 427 }
748a9306 428 return 0;
93a17b20 429 case '+':
3280af22 430 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
d9f97599 431 paren = rx->lastparen;
13f57bf8
CS
432 if (paren)
433 goto getparen;
93a17b20 434 }
748a9306 435 return 0;
93a17b20 436 case '`':
3280af22 437 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d
IZ
438 if (rx->startp[0] != -1) {
439 i = rx->startp[0];
a197cbdd
GS
440 if (i > 0) {
441 s1 = 0;
442 t1 = i;
443 goto getlen;
444 }
93a17b20 445 }
93a17b20 446 }
748a9306 447 return 0;
93a17b20 448 case '\'':
3280af22 449 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d
IZ
450 if (rx->endp[0] != -1) {
451 i = rx->sublen - rx->endp[0];
a197cbdd
GS
452 if (i > 0) {
453 s1 = rx->endp[0];
454 t1 = rx->sublen;
455 goto getlen;
456 }
93a17b20 457 }
93a17b20 458 }
748a9306 459 return 0;
93a17b20
LW
460 }
461 magic_get(sv,mg);
2d8e6c8d
GS
462 if (!SvPOK(sv) && SvNIOK(sv)) {
463 STRLEN n_a;
464 sv_2pv(sv, &n_a);
465 }
93a17b20
LW
466 if (SvPOK(sv))
467 return SvCUR(sv);
468 return 0;
469}
470
79072805 471int
864dbfa3 472Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
473{
474 register I32 paren;
475 register char *s;
476 register I32 i;
d9f97599 477 register REGEXP *rx;
79072805
LW
478
479 switch (*mg->mg_ptr) {
748a9306 480 case '\001': /* ^A */
3280af22 481 sv_setsv(sv, PL_bodytarget);
748a9306 482 break;
49460fe6
NIS
483 case '\003': /* ^C */
484 sv_setiv(sv, (IV)PL_minus_c);
485 break;
486
79072805 487 case '\004': /* ^D */
aea4f609 488 sv_setiv(sv, (IV)(PL_debug & DEBUG_MASK));
d056ab3f 489#if defined(YYDEBUG) && defined(DEBUGGING)
aea4f609 490 PL_yydebug = DEBUG_p_TEST;
d056ab3f 491#endif
79072805 492 break;
28f23441 493 case '\005': /* ^E */
cd39f2b6
JH
494#ifdef MACOS_TRADITIONAL
495 {
496 char msg[256];
ac27b0f5 497
bf4acbe4
GS
498 sv_setnv(sv,(double)gMacPerl_OSErr);
499 sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : "");
cd39f2b6
JH
500 }
501#else
28f23441 502#ifdef VMS
503 {
504# include <descrip.h>
505# include <starlet.h>
506 char msg[255];
507 $DESCRIPTOR(msgdsc,msg);
65202027 508 sv_setnv(sv,(NV) vaxc$errno);
28f23441 509 if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
510 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
511 else
512 sv_setpv(sv,"");
513 }
514#else
88e89b8a 515#ifdef OS2
fb73857a 516 if (!(_emx_env & 0x200)) { /* Under DOS */
65202027 517 sv_setnv(sv, (NV)errno);
fb73857a 518 sv_setpv(sv, errno ? Strerror(errno) : "");
519 } else {
017f25f1
IZ
520 if (errno != errno_isOS2) {
521 int tmp = _syserrno();
522 if (tmp) /* 2nd call to _syserrno() makes it 0 */
523 Perl_rc = tmp;
524 }
65202027 525 sv_setnv(sv, (NV)Perl_rc);
fb73857a 526 sv_setpv(sv, os2error(Perl_rc));
527 }
88e89b8a 528#else
22fae026
TM
529#ifdef WIN32
530 {
531 DWORD dwErr = GetLastError();
65202027 532 sv_setnv(sv, (NV)dwErr);
22fae026 533 if (dwErr)
76e3520e 534 {
0cb96387 535 PerlProc_GetOSError(sv, dwErr);
76e3520e 536 }
22fae026
TM
537 else
538 sv_setpv(sv, "");
539 SetLastError(dwErr);
540 }
541#else
65202027 542 sv_setnv(sv, (NV)errno);
28f23441 543 sv_setpv(sv, errno ? Strerror(errno) : "");
544#endif
88e89b8a 545#endif
22fae026 546#endif
cd39f2b6 547#endif
946ec16e 548 SvNOK_on(sv); /* what a wonderful hack! */
28f23441 549 break;
79072805 550 case '\006': /* ^F */
3280af22 551 sv_setiv(sv, (IV)PL_maxsysfd);
79072805 552 break;
a0d0e21e 553 case '\010': /* ^H */
3280af22 554 sv_setiv(sv, (IV)PL_hints);
a0d0e21e 555 break;
9d116dd7 556 case '\011': /* ^I */ /* NOT \t in EBCDIC */
3280af22
NIS
557 if (PL_inplace)
558 sv_setpv(sv, PL_inplace);
79072805 559 else
3280af22 560 sv_setsv(sv, &PL_sv_undef);
79072805 561 break;
ac27b0f5
NIS
562 case '\017': /* ^O & ^OPEN */
563 if (*(mg->mg_ptr+1) == '\0')
564 sv_setpv(sv, PL_osname);
565 else if (strEQ(mg->mg_ptr, "\017PEN")) {
566 if (!PL_compiling.cop_io)
567 sv_setsv(sv, &PL_sv_undef);
568 else {
569 sv_setsv(sv, PL_compiling.cop_io);
570 }
571 }
28f23441 572 break;
79072805 573 case '\020': /* ^P */
3280af22 574 sv_setiv(sv, (IV)PL_perldb);
79072805 575 break;
fb73857a 576 case '\023': /* ^S */
d58bf5aa 577 {
3280af22 578 if (PL_lex_state != LEX_NOTPARSING)
155aba94 579 (void)SvOK_off(sv);
3280af22 580 else if (PL_in_eval)
6dc8a9e4 581 sv_setiv(sv, PL_in_eval & ~(EVAL_INREQUIRE));
d58bf5aa 582 }
fb73857a 583 break;
79072805 584 case '\024': /* ^T */
88e89b8a 585#ifdef BIG_TIME
6b88bc9c 586 sv_setnv(sv, PL_basetime);
88e89b8a 587#else
3280af22 588 sv_setiv(sv, (IV)PL_basetime);
88e89b8a 589#endif
79072805 590 break;
46487f74 591 case '\027': /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */
4438c4b7
JH
592 if (*(mg->mg_ptr+1) == '\0')
593 sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE));
6a818117 594 else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) {
d3a7d8c7
GS
595 if (PL_compiling.cop_warnings == pWARN_NONE ||
596 PL_compiling.cop_warnings == pWARN_STD)
4438c4b7
JH
597 {
598 sv_setpvn(sv, WARN_NONEstring, WARNsize) ;
599 }
d3a7d8c7 600 else if (PL_compiling.cop_warnings == pWARN_ALL) {
4438c4b7 601 sv_setpvn(sv, WARN_ALLstring, WARNsize) ;
ac27b0f5 602 }
4438c4b7
JH
603 else {
604 sv_setsv(sv, PL_compiling.cop_warnings);
ac27b0f5 605 }
d3a7d8c7 606 SvPOK_only(sv);
4438c4b7 607 }
46487f74
GS
608 else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS"))
609 sv_setiv(sv, (IV)PL_widesyscalls);
79072805
LW
610 break;
611 case '1': case '2': case '3': case '4':
612 case '5': case '6': case '7': case '8': case '9': case '&':
3280af22 613 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d
IZ
614 I32 s1, t1;
615
a863c7d1
MB
616 /*
617 * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
618 * XXX Does the new way break anything?
619 */
ffc61ed2 620 paren = atoi(mg->mg_ptr); /* $& is in [0] */
79072805 621 getparen:
d9f97599 622 if (paren <= rx->nparens &&
cf93c79d
IZ
623 (s1 = rx->startp[paren]) != -1 &&
624 (t1 = rx->endp[paren]) != -1)
bbce6d69 625 {
cf93c79d
IZ
626 i = t1 - s1;
627 s = rx->subbeg + s1;
01ec43d0 628 if (!rx->subbeg)
c2e66d9e
GS
629 break;
630
13f57bf8 631 getrx:
748a9306 632 if (i >= 0) {
b7953727 633 bool was_tainted = FALSE;
3280af22
NIS
634 if (PL_tainting) {
635 was_tainted = PL_tainted;
636 PL_tainted = FALSE;
13f57bf8 637 }
cf93c79d 638 sv_setpvn(sv, s, i);
bdc14a33 639 if (PL_reg_sv && DO_UTF8(PL_reg_sv) && is_utf8_string((U8*)s, i))
7e2040f0
GS
640 SvUTF8_on(sv);
641 else
642 SvUTF8_off(sv);
3280af22
NIS
643 if (PL_tainting)
644 PL_tainted = (was_tainted || RX_MATCH_TAINTED(rx));
748a9306
LW
645 break;
646 }
79072805 647 }
79072805 648 }
3280af22 649 sv_setsv(sv,&PL_sv_undef);
79072805
LW
650 break;
651 case '+':
3280af22 652 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
d9f97599 653 paren = rx->lastparen;
a0d0e21e
LW
654 if (paren)
655 goto getparen;
79072805 656 }
3280af22 657 sv_setsv(sv,&PL_sv_undef);
79072805
LW
658 break;
659 case '`':
3280af22 660 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d
IZ
661 if ((s = rx->subbeg) && rx->startp[0] != -1) {
662 i = rx->startp[0];
13f57bf8 663 goto getrx;
79072805 664 }
79072805 665 }
3280af22 666 sv_setsv(sv,&PL_sv_undef);
79072805
LW
667 break;
668 case '\'':
3280af22 669 if (PL_curpm && (rx = PL_curpm->op_pmregexp)) {
cf93c79d
IZ
670 if (rx->subbeg && rx->endp[0] != -1) {
671 s = rx->subbeg + rx->endp[0];
672 i = rx->sublen - rx->endp[0];
13f57bf8 673 goto getrx;
79072805 674 }
79072805 675 }
3280af22 676 sv_setsv(sv,&PL_sv_undef);
79072805
LW
677 break;
678 case '.':
679#ifndef lint
3280af22 680 if (GvIO(PL_last_in_gv)) {
357c8808 681 sv_setiv(sv, (IV)IoLINES(GvIOp(PL_last_in_gv)));
79072805
LW
682 }
683#endif
684 break;
685 case '?':
809a5acc 686 {
809a5acc 687 sv_setiv(sv, (IV)STATUS_CURRENT);
ff0cee69 688#ifdef COMPLEX_STATUS
6b88bc9c
GS
689 LvTARGOFF(sv) = PL_statusvalue;
690 LvTARGLEN(sv) = PL_statusvalue_vms;
ff0cee69 691#endif
809a5acc 692 }
79072805
LW
693 break;
694 case '^':
3280af22 695 s = IoTOP_NAME(GvIOp(PL_defoutgv));
79072805
LW
696 if (s)
697 sv_setpv(sv,s);
698 else {
3280af22 699 sv_setpv(sv,GvENAME(PL_defoutgv));
79072805
LW
700 sv_catpv(sv,"_TOP");
701 }
702 break;
703 case '~':
3280af22 704 s = IoFMT_NAME(GvIOp(PL_defoutgv));
79072805 705 if (!s)
3280af22 706 s = GvENAME(PL_defoutgv);
79072805
LW
707 sv_setpv(sv,s);
708 break;
709#ifndef lint
710 case '=':
3280af22 711 sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(PL_defoutgv)));
79072805
LW
712 break;
713 case '-':
3280af22 714 sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(PL_defoutgv)));
79072805
LW
715 break;
716 case '%':
3280af22 717 sv_setiv(sv, (IV)IoPAGE(GvIOp(PL_defoutgv)));
79072805
LW
718 break;
719#endif
720 case ':':
721 break;
722 case '/':
723 break;
724 case '[':
3280af22 725 WITH_THR(sv_setiv(sv, (IV)PL_curcop->cop_arybase));
79072805
LW
726 break;
727 case '|':
3280af22 728 sv_setiv(sv, (IV)(IoFLAGS(GvIOp(PL_defoutgv)) & IOf_FLUSH) != 0 );
79072805
LW
729 break;
730 case ',':
79072805
LW
731 break;
732 case '\\':
79072805
LW
733 break;
734 case '#':
3280af22 735 sv_setpv(sv,PL_ofmt);
79072805
LW
736 break;
737 case '!':
a5f75d66 738#ifdef VMS
65202027 739 sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
88e89b8a 740 sv_setpv(sv, errno ? Strerror(errno) : "");
a5f75d66 741#else
88e89b8a 742 {
743 int saveerrno = errno;
65202027 744 sv_setnv(sv, (NV)errno);
88e89b8a 745#ifdef OS2
ed344e4f
IZ
746 if (errno == errno_isOS2 || errno == errno_isOS2_set)
747 sv_setpv(sv, os2error(Perl_rc));
88e89b8a 748 else
a5f75d66 749#endif
2304df62 750 sv_setpv(sv, errno ? Strerror(errno) : "");
88e89b8a 751 errno = saveerrno;
752 }
753#endif
946ec16e 754 SvNOK_on(sv); /* what a wonderful hack! */
79072805
LW
755 break;
756 case '<':
3280af22 757 sv_setiv(sv, (IV)PL_uid);
79072805
LW
758 break;
759 case '>':
3280af22 760 sv_setiv(sv, (IV)PL_euid);
79072805
LW
761 break;
762 case '(':
3280af22 763 sv_setiv(sv, (IV)PL_gid);
a52cb5f7 764#ifdef HAS_GETGROUPS
785fb66b 765 Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_gid);
a52cb5f7 766#endif
79072805
LW
767 goto add_groups;
768 case ')':
3280af22 769 sv_setiv(sv, (IV)PL_egid);
a52cb5f7 770#ifdef HAS_GETGROUPS
785fb66b 771 Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_egid);
a52cb5f7 772#endif
79072805 773 add_groups:
79072805 774#ifdef HAS_GETGROUPS
79072805 775 {
a0d0e21e 776 Groups_t gary[NGROUPS];
79072805 777 i = getgroups(NGROUPS,gary);
46fc3d4c 778 while (--i >= 0)
785fb66b 779 Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]);
79072805
LW
780 }
781#endif
155aba94 782 (void)SvIOK_on(sv); /* what a wonderful hack! */
79072805
LW
783 break;
784 case '*':
785 break;
cd39f2b6 786#ifndef MACOS_TRADITIONAL
79072805
LW
787 case '0':
788 break;
cd39f2b6 789#endif
a863c7d1
MB
790#ifdef USE_THREADS
791 case '@':
38a03e6e 792 sv_setsv(sv, thr->errsv);
a863c7d1
MB
793 break;
794#endif /* USE_THREADS */
79072805 795 }
a0d0e21e 796 return 0;
79072805
LW
797}
798
799int
864dbfa3 800Perl_magic_getuvar(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
801{
802 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
803
804 if (uf && uf->uf_val)
24f81a43 805 (*uf->uf_val)(aTHX_ uf->uf_index, sv);
79072805
LW
806 return 0;
807}
808
809int
864dbfa3 810Perl_magic_setenv(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
811{
812 register char *s;
88e89b8a 813 char *ptr;
5aabfad6 814 STRLEN len, klen;
a0d0e21e 815 I32 i;
1e422769 816
a0d0e21e 817 s = SvPV(sv,len);
5aabfad6 818 ptr = MgPV(mg,klen);
88e89b8a 819 my_setenv(ptr, s);
1e422769 820
a0d0e21e
LW
821#ifdef DYNAMIC_ENV_FETCH
822 /* We just undefd an environment var. Is a replacement */
823 /* waiting in the wings? */
824 if (!len) {
5aabfad6 825 SV **valp;
6b88bc9c 826 if ((valp = hv_fetch(GvHVn(PL_envgv), ptr, klen, FALSE)))
5aabfad6 827 s = SvPV(*valp, len);
a0d0e21e
LW
828 }
829#endif
1e422769 830
39e571d4 831#if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) && !defined(MSDOS)
79072805
LW
832 /* And you'll never guess what the dog had */
833 /* in its mouth... */
3280af22 834 if (PL_tainting) {
1e422769 835 MgTAINTEDDIR_off(mg);
836#ifdef VMS
5aabfad6 837 if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
1e422769 838 char pathbuf[256], eltbuf[256], *cp, *elt = s;
839 struct stat sbuf;
840 int i = 0, j = 0;
841
842 do { /* DCL$PATH may be a search list */
843 while (1) { /* as may dev portion of any element */
844 if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
845 if ( *(cp+1) == '.' || *(cp+1) == '-' ||
846 cando_by_name(S_IWUSR,0,elt) ) {
847 MgTAINTEDDIR_on(mg);
848 return 0;
849 }
850 }
851 if ((cp = strchr(elt, ':')) != Nullch)
852 *cp = '\0';
853 if (my_trnlnm(elt, eltbuf, j++))
854 elt = eltbuf;
855 else
856 break;
857 }
858 j = 0;
859 } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
860 }
861#endif /* VMS */
5aabfad6 862 if (s && klen == 4 && strEQ(ptr,"PATH")) {
a0d0e21e 863 char *strend = s + len;
463ee0b2
LW
864
865 while (s < strend) {
96827780 866 char tmpbuf[256];
1e422769 867 struct stat st;
96827780 868 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
fc36a67e 869 s, strend, ':', &i);
463ee0b2 870 s++;
96827780
MB
871 if (i >= sizeof tmpbuf /* too long -- assume the worst */
872 || *tmpbuf != '/'
c6ed36e1 873 || (PerlLIO_stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
8990e307 874 MgTAINTEDDIR_on(mg);
1e422769 875 return 0;
876 }
463ee0b2 877 }
79072805
LW
878 }
879 }
39e571d4 880#endif /* neither OS2 nor AMIGAOS nor WIN32 nor MSDOS */
1e422769 881
79072805
LW
882 return 0;
883}
884
885int
864dbfa3 886Perl_magic_clearenv(pTHX_ SV *sv, MAGIC *mg)
85e6fe83 887{
2d8e6c8d
GS
888 STRLEN n_a;
889 my_setenv(MgPV(mg,n_a),Nullch);
85e6fe83
LW
890 return 0;
891}
892
88e89b8a 893int
864dbfa3 894Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg)
fb73857a 895{
896#if defined(VMS)
cea2e8a9 897 Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
fb73857a 898#else
3280af22 899 if (PL_localizing) {
fb73857a 900 HE* entry;
2d8e6c8d 901 STRLEN n_a;
fb73857a 902 magic_clear_all_env(sv,mg);
903 hv_iterinit((HV*)sv);
155aba94 904 while ((entry = hv_iternext((HV*)sv))) {
fb73857a 905 I32 keylen;
906 my_setenv(hv_iterkey(entry, &keylen),
2d8e6c8d 907 SvPV(hv_iterval((HV*)sv, entry), n_a));
fb73857a 908 }
909 }
910#endif
911 return 0;
912}
913
914int
864dbfa3 915Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg)
66b1d557 916{
ed79a026 917#if defined(VMS) || defined(EPOC)
cea2e8a9 918 Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system");
3e3baf6d 919#else
7766f137
GS
920# ifdef PERL_IMPLICIT_SYS
921 PerlEnv_clearenv();
922# else
923# ifdef WIN32
3e3baf6d
TB
924 char *envv = GetEnvironmentStrings();
925 char *cur = envv;
926 STRLEN len;
927 while (*cur) {
928 char *end = strchr(cur,'=');
929 if (end && end != cur) {
930 *end = '\0';
931 my_setenv(cur,Nullch);
932 *end = '=';
ac5c734f 933 cur = end + strlen(end+1)+2;
3e3baf6d
TB
934 }
935 else if ((len = strlen(cur)))
936 cur += len+1;
937 }
938 FreeEnvironmentStrings(envv);
7766f137 939# else
5acaa6ec 940#ifdef USE_ENVIRON_ARRAY
7766f137 941# ifndef PERL_USE_SAFE_PUTENV
66b1d557
HM
942 I32 i;
943
3280af22 944 if (environ == PL_origenviron)
f2517201 945 environ = (char**)safesysmalloc(sizeof(char*));
66b1d557
HM
946 else
947 for (i = 0; environ[i]; i++)
f2517201 948 safesysfree(environ[i]);
7766f137 949# endif /* PERL_USE_SAFE_PUTENV */
f2517201 950
66b1d557
HM
951 environ[0] = Nullch;
952
5acaa6ec 953#endif /* USE_ENVIRON_ARRAY */
7766f137
GS
954# endif /* WIN32 */
955# endif /* PERL_IMPLICIT_SYS */
f2517201 956#endif /* VMS */
3e3baf6d 957 return 0;
66b1d557
HM
958}
959
64ca3a65 960#ifndef PERL_MICRO
66b1d557 961int
864dbfa3 962Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg)
88e89b8a 963{
964 I32 i;
2d8e6c8d 965 STRLEN n_a;
88e89b8a 966 /* Are we fetching a signal entry? */
2d8e6c8d 967 i = whichsig(MgPV(mg,n_a));
88e89b8a 968 if (i) {
22c35a8c
GS
969 if(PL_psig_ptr[i])
970 sv_setsv(sv,PL_psig_ptr[i]);
88e89b8a 971 else {
ff68c719 972 Sighandler_t sigstate = rsignal_state(i);
973
88e89b8a 974 /* cache state so we don't fetch it again */
ff68c719 975 if(sigstate == SIG_IGN)
88e89b8a 976 sv_setpv(sv,"IGNORE");
977 else
3280af22 978 sv_setsv(sv,&PL_sv_undef);
22c35a8c 979 PL_psig_ptr[i] = SvREFCNT_inc(sv);
88e89b8a 980 SvTEMP_off(sv);
981 }
982 }
983 return 0;
984}
985int
864dbfa3 986Perl_magic_clearsig(pTHX_ SV *sv, MAGIC *mg)
88e89b8a 987{
988 I32 i;
2d8e6c8d 989 STRLEN n_a;
88e89b8a 990 /* Are we clearing a signal entry? */
2d8e6c8d 991 i = whichsig(MgPV(mg,n_a));
88e89b8a 992 if (i) {
22c35a8c
GS
993 if(PL_psig_ptr[i]) {
994 SvREFCNT_dec(PL_psig_ptr[i]);
995 PL_psig_ptr[i]=0;
88e89b8a 996 }
22c35a8c
GS
997 if(PL_psig_name[i]) {
998 SvREFCNT_dec(PL_psig_name[i]);
999 PL_psig_name[i]=0;
88e89b8a 1000 }
1001 }
1002 return 0;
1003}
3d37d572 1004
0a8e0eff
NIS
1005void
1006Perl_raise_signal(pTHX_ int sig)
1007{
1008 /* Set a flag to say this signal is pending */
1009 PL_psig_pend[sig]++;
1010 /* And one to say _a_ signal is pending */
1011 PL_sig_pending = 1;
1012}
1013
1014Signal_t
1015Perl_csighandler(int sig)
1016{
1017#ifdef PERL_OLD_SIGNALS
1018 /* Call the perl level handler now with risk we may be in malloc() etc. */
1019 (*PL_sighandlerp)(sig);
1020#else
1021 dTHX;
1022 Perl_raise_signal(aTHX_ sig);
1023#endif
1024}
1025
1026void
1027Perl_despatch_signals(pTHX)
1028{
1029 int sig;
1030 PL_sig_pending = 0;
1031 for (sig = 1; sig < SIG_SIZE; sig++) {
1032 if (PL_psig_pend[sig]) {
1033 PL_psig_pend[sig] = 0;
1034 (*PL_sighandlerp)(sig);
1035 }
1036 }
1037}
1038
85e6fe83 1039int
864dbfa3 1040Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1041{
1042 register char *s;
1043 I32 i;
b7953727 1044 SV** svp = 0;
e72dc28c 1045 STRLEN len;
a0d0e21e 1046
e72dc28c 1047 s = MgPV(mg,len);
748a9306
LW
1048 if (*s == '_') {
1049 if (strEQ(s,"__DIE__"))
3280af22 1050 svp = &PL_diehook;
748a9306 1051 else if (strEQ(s,"__WARN__"))
3280af22 1052 svp = &PL_warnhook;
748a9306 1053 else
cea2e8a9 1054 Perl_croak(aTHX_ "No such hook: %s", s);
748a9306 1055 i = 0;
4633a7c4
LW
1056 if (*svp) {
1057 SvREFCNT_dec(*svp);
1058 *svp = 0;
1059 }
748a9306
LW
1060 }
1061 else {
1062 i = whichsig(s); /* ...no, a brick */
1063 if (!i) {
e476b1b5 1064 if (ckWARN(WARN_SIGNAL))
cea2e8a9 1065 Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s);
748a9306
LW
1066 return 0;
1067 }
22c35a8c
GS
1068 SvREFCNT_dec(PL_psig_name[i]);
1069 SvREFCNT_dec(PL_psig_ptr[i]);
1070 PL_psig_ptr[i] = SvREFCNT_inc(sv);
88e89b8a 1071 SvTEMP_off(sv); /* Make sure it doesn't go away on us */
e72dc28c 1072 PL_psig_name[i] = newSVpvn(s, len);
22c35a8c 1073 SvREADONLY_on(PL_psig_name[i]);
748a9306 1074 }
a0d0e21e 1075 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
748a9306 1076 if (i)
0a8e0eff 1077 (void)rsignal(i, &Perl_csighandler);
748a9306
LW
1078 else
1079 *svp = SvREFCNT_inc(sv);
a0d0e21e
LW
1080 return 0;
1081 }
e72dc28c 1082 s = SvPV_force(sv,len);
748a9306
LW
1083 if (strEQ(s,"IGNORE")) {
1084 if (i)
ff68c719 1085 (void)rsignal(i, SIG_IGN);
748a9306
LW
1086 else
1087 *svp = 0;
1088 }
1089 else if (strEQ(s,"DEFAULT") || !*s) {
1090 if (i)
ff68c719 1091 (void)rsignal(i, SIG_DFL);
748a9306
LW
1092 else
1093 *svp = 0;
1094 }
79072805 1095 else {
5aabfad6 1096 /*
1097 * We should warn if HINT_STRICT_REFS, but without
1098 * access to a known hint bit in a known OP, we can't
1099 * tell whether HINT_STRICT_REFS is in force or not.
1100 */
46fc3d4c 1101 if (!strchr(s,':') && !strchr(s,'\''))
e72dc28c 1102 sv_insert(sv, 0, 0, "main::", 6);
748a9306 1103 if (i)
0a8e0eff 1104 (void)rsignal(i, &Perl_csighandler);
748a9306
LW
1105 else
1106 *svp = SvREFCNT_inc(sv);
79072805
LW
1107 }
1108 return 0;
1109}
64ca3a65 1110#endif /* !PERL_MICRO */
79072805
LW
1111
1112int
864dbfa3 1113Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg)
79072805 1114{
3280af22 1115 PL_sub_generation++;
463ee0b2
LW
1116 return 0;
1117}
1118
1119int
864dbfa3 1120Perl_magic_setamagic(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1121{
a0d0e21e 1122 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
3280af22 1123 PL_amagic_generation++;
463ee0b2 1124
a0d0e21e
LW
1125 return 0;
1126}
463ee0b2 1127
946ec16e 1128int
864dbfa3 1129Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg)
6ff81951
GS
1130{
1131 HV *hv = (HV*)LvTARG(sv);
1132 HE *entry;
1133 I32 i = 0;
1134
1135 if (hv) {
1136 (void) hv_iterinit(hv);
14befaf4 1137 if (! SvTIED_mg((SV*)hv, PERL_MAGIC_tied))
6ff81951
GS
1138 i = HvKEYS(hv);
1139 else {
1140 /*SUPPRESS 560*/
155aba94 1141 while ((entry = hv_iternext(hv))) {
6ff81951
GS
1142 i++;
1143 }
1144 }
1145 }
1146
1147 sv_setiv(sv, (IV)i);
1148 return 0;
1149}
1150
1151int
864dbfa3 1152Perl_magic_setnkeys(pTHX_ SV *sv, MAGIC *mg)
946ec16e 1153{
1154 if (LvTARG(sv)) {
1155 hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
946ec16e 1156 }
1157 return 0;
ac27b0f5 1158}
946ec16e 1159
e336de0d 1160/* caller is responsible for stack switching/cleanup */
565764a8 1161STATIC int
cea2e8a9 1162S_magic_methcall(pTHX_ SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
a0d0e21e
LW
1163{
1164 dSP;
463ee0b2 1165
924508f0
GS
1166 PUSHMARK(SP);
1167 EXTEND(SP, n);
33c27489 1168 PUSHs(SvTIED_obj(sv, mg));
ac27b0f5 1169 if (n > 1) {
93965878 1170 if (mg->mg_ptr) {
565764a8 1171 if (mg->mg_len >= 0)
79cb57f6 1172 PUSHs(sv_2mortal(newSVpvn(mg->mg_ptr, mg->mg_len)));
565764a8 1173 else if (mg->mg_len == HEf_SVKEY)
93965878
NIS
1174 PUSHs((SV*)mg->mg_ptr);
1175 }
14befaf4 1176 else if (mg->mg_type == PERL_MAGIC_tiedelem) {
565764a8 1177 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
93965878
NIS
1178 }
1179 }
1180 if (n > 2) {
1181 PUSHs(val);
88e89b8a 1182 }
463ee0b2
LW
1183 PUTBACK;
1184
864dbfa3 1185 return call_method(meth, flags);
946ec16e 1186}
1187
76e3520e 1188STATIC int
cea2e8a9 1189S_magic_methpack(pTHX_ SV *sv, MAGIC *mg, char *meth)
a0d0e21e
LW
1190{
1191 dSP;
463ee0b2 1192
a0d0e21e
LW
1193 ENTER;
1194 SAVETMPS;
e788e7d3 1195 PUSHSTACKi(PERLSI_MAGIC);
463ee0b2 1196
33c27489 1197 if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
3280af22 1198 sv_setsv(sv, *PL_stack_sp--);
93965878 1199 }
463ee0b2 1200
d3acc0f7 1201 POPSTACK;
a0d0e21e
LW
1202 FREETMPS;
1203 LEAVE;
1204 return 0;
1205}
463ee0b2 1206
a0d0e21e 1207int
864dbfa3 1208Perl_magic_getpack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e
LW
1209{
1210 magic_methpack(sv,mg,"FETCH");
1211 if (mg->mg_ptr)
1212 mg->mg_flags |= MGf_GSKIP;
463ee0b2
LW
1213 return 0;
1214}
1215
1216int
864dbfa3 1217Perl_magic_setpack(pTHX_ SV *sv, MAGIC *mg)
e336de0d
GS
1218{
1219 dSP;
a60c0954 1220 ENTER;
e788e7d3 1221 PUSHSTACKi(PERLSI_MAGIC);
33c27489 1222 magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
d3acc0f7 1223 POPSTACK;
a60c0954 1224 LEAVE;
463ee0b2
LW
1225 return 0;
1226}
1227
1228int
864dbfa3 1229Perl_magic_clearpack(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1230{
a0d0e21e
LW
1231 return magic_methpack(sv,mg,"DELETE");
1232}
463ee0b2 1233
93965878
NIS
1234
1235U32
864dbfa3 1236Perl_magic_sizepack(pTHX_ SV *sv, MAGIC *mg)
ac27b0f5 1237{
e336de0d 1238 dSP;
93965878
NIS
1239 U32 retval = 0;
1240
1241 ENTER;
1242 SAVETMPS;
e788e7d3 1243 PUSHSTACKi(PERLSI_MAGIC);
33c27489 1244 if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
3280af22 1245 sv = *PL_stack_sp--;
a60c0954 1246 retval = (U32) SvIV(sv)-1;
93965878 1247 }
d3acc0f7 1248 POPSTACK;
93965878
NIS
1249 FREETMPS;
1250 LEAVE;
1251 return retval;
1252}
1253
cea2e8a9
GS
1254int
1255Perl_magic_wipepack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e
LW
1256{
1257 dSP;
463ee0b2 1258
e336de0d 1259 ENTER;
e788e7d3 1260 PUSHSTACKi(PERLSI_MAGIC);
924508f0 1261 PUSHMARK(SP);
33c27489 1262 XPUSHs(SvTIED_obj(sv, mg));
463ee0b2 1263 PUTBACK;
864dbfa3 1264 call_method("CLEAR", G_SCALAR|G_DISCARD);
d3acc0f7 1265 POPSTACK;
a60c0954 1266 LEAVE;
463ee0b2
LW
1267 return 0;
1268}
1269
1270int
864dbfa3 1271Perl_magic_nextpack(pTHX_ SV *sv, MAGIC *mg, SV *key)
463ee0b2 1272{
463ee0b2 1273 dSP;
dff6d3cd 1274 const char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2
LW
1275
1276 ENTER;
a0d0e21e 1277 SAVETMPS;
e788e7d3 1278 PUSHSTACKi(PERLSI_MAGIC);
924508f0
GS
1279 PUSHMARK(SP);
1280 EXTEND(SP, 2);
33c27489 1281 PUSHs(SvTIED_obj(sv, mg));
463ee0b2
LW
1282 if (SvOK(key))
1283 PUSHs(key);
1284 PUTBACK;
1285
864dbfa3 1286 if (call_method(meth, G_SCALAR))
3280af22 1287 sv_setsv(key, *PL_stack_sp--);
463ee0b2 1288
d3acc0f7 1289 POPSTACK;
a0d0e21e
LW
1290 FREETMPS;
1291 LEAVE;
79072805
LW
1292 return 0;
1293}
1294
1295int
864dbfa3 1296Perl_magic_existspack(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e
LW
1297{
1298 return magic_methpack(sv,mg,"EXISTS");
ac27b0f5 1299}
a0d0e21e
LW
1300
1301int
864dbfa3 1302Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1303{
1304 OP *o;
1305 I32 i;
1306 GV* gv;
1307 SV** svp;
2d8e6c8d 1308 STRLEN n_a;
79072805 1309
3280af22 1310 gv = PL_DBline;
79072805 1311 i = SvTRUE(sv);
188ea221 1312 svp = av_fetch(GvAV(gv),
2d8e6c8d 1313 atoi(MgPV(mg,n_a)), FALSE);
57b2e452 1314 if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp))))
93a17b20 1315 o->op_private = i;
79072805
LW
1316 return 0;
1317}
1318
1319int
864dbfa3 1320Perl_magic_getarylen(pTHX_ SV *sv, MAGIC *mg)
79072805 1321{
3280af22 1322 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + PL_curcop->cop_arybase);
79072805
LW
1323 return 0;
1324}
1325
1326int
864dbfa3 1327Perl_magic_setarylen(pTHX_ SV *sv, MAGIC *mg)
79072805 1328{
3280af22 1329 av_fill((AV*)mg->mg_obj, SvIV(sv) - PL_curcop->cop_arybase);
a0d0e21e
LW
1330 return 0;
1331}
1332
1333int
864dbfa3 1334Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e
LW
1335{
1336 SV* lsv = LvTARG(sv);
ac27b0f5 1337
a0d0e21e 1338 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
14befaf4 1339 mg = mg_find(lsv, PERL_MAGIC_regex_global);
565764a8 1340 if (mg && mg->mg_len >= 0) {
a0ed51b3 1341 I32 i = mg->mg_len;
7e2040f0 1342 if (DO_UTF8(lsv))
a0ed51b3
LW
1343 sv_pos_b2u(lsv, &i);
1344 sv_setiv(sv, i + PL_curcop->cop_arybase);
a0d0e21e
LW
1345 return 0;
1346 }
1347 }
1348 (void)SvOK_off(sv);
1349 return 0;
1350}
1351
1352int
864dbfa3 1353Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg)
a0d0e21e
LW
1354{
1355 SV* lsv = LvTARG(sv);
1356 SSize_t pos;
1357 STRLEN len;
c00206c8 1358 STRLEN ulen = 0;
a0d0e21e
LW
1359
1360 mg = 0;
ac27b0f5 1361
a0d0e21e 1362 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
14befaf4 1363 mg = mg_find(lsv, PERL_MAGIC_regex_global);
a0d0e21e
LW
1364 if (!mg) {
1365 if (!SvOK(sv))
1366 return 0;
14befaf4
DM
1367 sv_magic(lsv, (SV*)0, PERL_MAGIC_regex_global, Nullch, 0);
1368 mg = mg_find(lsv, PERL_MAGIC_regex_global);
a0d0e21e
LW
1369 }
1370 else if (!SvOK(sv)) {
565764a8 1371 mg->mg_len = -1;
a0d0e21e
LW
1372 return 0;
1373 }
1374 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1375
c485e607 1376 pos = SvIV(sv) - PL_curcop->cop_arybase;
a0ed51b3 1377
7e2040f0 1378 if (DO_UTF8(lsv)) {
a0ed51b3
LW
1379 ulen = sv_len_utf8(lsv);
1380 if (ulen)
1381 len = ulen;
a0ed51b3
LW
1382 }
1383
a0d0e21e
LW
1384 if (pos < 0) {
1385 pos += len;
1386 if (pos < 0)
1387 pos = 0;
1388 }
1389 else if (pos > len)
1390 pos = len;
a0ed51b3
LW
1391
1392 if (ulen) {
1393 I32 p = pos;
1394 sv_pos_u2b(lsv, &p, 0);
1395 pos = p;
1396 }
1397
565764a8 1398 mg->mg_len = pos;
71be2cbc 1399 mg->mg_flags &= ~MGf_MINMATCH;
a0d0e21e 1400
79072805
LW
1401 return 0;
1402}
1403
1404int
864dbfa3 1405Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
79072805 1406{
8646b087 1407 if (SvFAKE(sv)) { /* FAKE globs can get coerced */
1408 SvFAKE_off(sv);
946ec16e 1409 gv_efullname3(sv,((GV*)sv), "*");
8646b087 1410 SvFAKE_on(sv);
1411 }
1412 else
946ec16e 1413 gv_efullname3(sv,((GV*)sv), "*"); /* a gv value, be nice */
79072805
LW
1414 return 0;
1415}
1416
1417int
864dbfa3 1418Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1419{
1420 register char *s;
1421 GV* gv;
2d8e6c8d 1422 STRLEN n_a;
79072805
LW
1423
1424 if (!SvOK(sv))
1425 return 0;
2d8e6c8d 1426 s = SvPV(sv, n_a);
79072805
LW
1427 if (*s == '*' && s[1])
1428 s++;
85e6fe83 1429 gv = gv_fetchpv(s,TRUE, SVt_PVGV);
79072805
LW
1430 if (sv == (SV*)gv)
1431 return 0;
1432 if (GvGP(sv))
88e89b8a 1433 gp_free((GV*)sv);
79072805 1434 GvGP(sv) = gp_ref(GvGP(gv));
79072805
LW
1435 return 0;
1436}
1437
1438int
864dbfa3 1439Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg)
6ff81951
GS
1440{
1441 STRLEN len;
1442 SV *lsv = LvTARG(sv);
1443 char *tmps = SvPV(lsv,len);
1444 I32 offs = LvTARGOFF(sv);
1445 I32 rem = LvTARGLEN(sv);
1446
9aa983d2
JH
1447 if (SvUTF8(lsv))
1448 sv_pos_u2b(lsv, &offs, &rem);
6ff81951
GS
1449 if (offs > len)
1450 offs = len;
1451 if (rem + offs > len)
1452 rem = len - offs;
1453 sv_setpvn(sv, tmps + offs, (STRLEN)rem);
9aa983d2 1454 if (SvUTF8(lsv))
2ef4b674 1455 SvUTF8_on(sv);
6ff81951
GS
1456 return 0;
1457}
1458
1459int
864dbfa3 1460Perl_magic_setsubstr(pTHX_ SV *sv, MAGIC *mg)
79072805 1461{
9aa983d2
JH
1462 STRLEN len;
1463 char *tmps = SvPV(sv, len);
1464 SV *lsv = LvTARG(sv);
1465 I32 lvoff = LvTARGOFF(sv);
1466 I32 lvlen = LvTARGLEN(sv);
075a4a2b 1467
1aa99e6b 1468 if (DO_UTF8(sv)) {
9aa983d2
JH
1469 sv_utf8_upgrade(lsv);
1470 sv_pos_u2b(lsv, &lvoff, &lvlen);
1471 sv_insert(lsv, lvoff, lvlen, tmps, len);
1472 SvUTF8_on(lsv);
1473 }
1474 else if (SvUTF8(lsv)) {
1475 sv_pos_u2b(lsv, &lvoff, &lvlen);
e95af362 1476 tmps = (char*)bytes_to_utf8((U8*)tmps, &len);
9aa983d2
JH
1477 sv_insert(lsv, lvoff, lvlen, tmps, len);
1478 Safefree(tmps);
1aa99e6b
IH
1479 }
1480 else
9aa983d2 1481 sv_insert(lsv, lvoff, lvlen, tmps, len);
1aa99e6b 1482
79072805
LW
1483 return 0;
1484}
1485
1486int
864dbfa3 1487Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1488{
565764a8 1489 TAINT_IF((mg->mg_len & 1) ||
155aba94 1490 ((mg->mg_len & 2) && mg->mg_obj == sv)); /* kludge */
463ee0b2
LW
1491 return 0;
1492}
1493
1494int
864dbfa3 1495Perl_magic_settaint(pTHX_ SV *sv, MAGIC *mg)
463ee0b2 1496{
3280af22
NIS
1497 if (PL_localizing) {
1498 if (PL_localizing == 1)
565764a8 1499 mg->mg_len <<= 1;
748a9306 1500 else
565764a8 1501 mg->mg_len >>= 1;
a0d0e21e 1502 }
3280af22 1503 else if (PL_tainted)
565764a8 1504 mg->mg_len |= 1;
748a9306 1505 else
565764a8 1506 mg->mg_len &= ~1;
463ee0b2
LW
1507 return 0;
1508}
1509
1510int
864dbfa3 1511Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg)
6ff81951
GS
1512{
1513 SV *lsv = LvTARG(sv);
6ff81951
GS
1514
1515 if (!lsv) {
155aba94 1516 (void)SvOK_off(sv);
6ff81951
GS
1517 return 0;
1518 }
6ff81951 1519
81e118e0 1520 sv_setuv(sv, do_vecget(lsv, LvTARGOFF(sv), LvTARGLEN(sv)));
6ff81951
GS
1521 return 0;
1522}
1523
1524int
864dbfa3 1525Perl_magic_setvec(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1526{
1527 do_vecset(sv); /* XXX slurp this routine */
1528 return 0;
1529}
1530
1531int
864dbfa3 1532Perl_magic_getdefelem(pTHX_ SV *sv, MAGIC *mg)
5f05dabc 1533{
71be2cbc 1534 SV *targ = Nullsv;
5f05dabc 1535 if (LvTARGLEN(sv)) {
68dc0745 1536 if (mg->mg_obj) {
74e13ce4
GS
1537 SV *ahv = LvTARG(sv);
1538 if (SvTYPE(ahv) == SVt_PVHV) {
1539 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, FALSE, 0);
1540 if (he)
1541 targ = HeVAL(he);
1542 }
1543 else {
1544 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, FALSE, 0);
1545 if (svp)
1546 targ = *svp;
1547 }
68dc0745 1548 }
1549 else {
3c78fafa 1550 AV* av = (AV*)LvTARG(sv);
68dc0745 1551 if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1552 targ = AvARRAY(av)[LvTARGOFF(sv)];
1553 }
3280af22 1554 if (targ && targ != &PL_sv_undef) {
68dc0745 1555 /* somebody else defined it for us */
1556 SvREFCNT_dec(LvTARG(sv));
1557 LvTARG(sv) = SvREFCNT_inc(targ);
1558 LvTARGLEN(sv) = 0;
1559 SvREFCNT_dec(mg->mg_obj);
1560 mg->mg_obj = Nullsv;
1561 mg->mg_flags &= ~MGf_REFCOUNTED;
1562 }
5f05dabc 1563 }
71be2cbc 1564 else
1565 targ = LvTARG(sv);
3280af22 1566 sv_setsv(sv, targ ? targ : &PL_sv_undef);
71be2cbc 1567 return 0;
1568}
1569
1570int
864dbfa3 1571Perl_magic_setdefelem(pTHX_ SV *sv, MAGIC *mg)
71be2cbc 1572{
1573 if (LvTARGLEN(sv))
68dc0745 1574 vivify_defelem(sv);
1575 if (LvTARG(sv)) {
5f05dabc 1576 sv_setsv(LvTARG(sv), sv);
68dc0745 1577 SvSETMAGIC(LvTARG(sv));
1578 }
5f05dabc 1579 return 0;
1580}
1581
71be2cbc 1582void
864dbfa3 1583Perl_vivify_defelem(pTHX_ SV *sv)
71be2cbc 1584{
74e13ce4
GS
1585 MAGIC *mg;
1586 SV *value = Nullsv;
71be2cbc 1587
14befaf4 1588 if (!LvTARGLEN(sv) || !(mg = mg_find(sv, PERL_MAGIC_defelem)))
71be2cbc 1589 return;
68dc0745 1590 if (mg->mg_obj) {
74e13ce4 1591 SV *ahv = LvTARG(sv);
2d8e6c8d 1592 STRLEN n_a;
74e13ce4 1593 if (SvTYPE(ahv) == SVt_PVHV) {
af7f9c15 1594 HE *he = hv_fetch_ent((HV*)ahv, mg->mg_obj, TRUE, 0);
74e13ce4
GS
1595 if (he)
1596 value = HeVAL(he);
1597 }
1598 else {
af7f9c15 1599 SV **svp = avhv_fetch_ent((AV*)ahv, mg->mg_obj, TRUE, 0);
74e13ce4
GS
1600 if (svp)
1601 value = *svp;
1602 }
3280af22 1603 if (!value || value == &PL_sv_undef)
cea2e8a9 1604 Perl_croak(aTHX_ PL_no_helem, SvPV(mg->mg_obj, n_a));
71be2cbc 1605 }
68dc0745 1606 else {
1607 AV* av = (AV*)LvTARG(sv);
5aabfad6 1608 if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
68dc0745 1609 LvTARG(sv) = Nullsv; /* array can't be extended */
1610 else {
1611 SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
3280af22 1612 if (!svp || (value = *svp) == &PL_sv_undef)
cea2e8a9 1613 Perl_croak(aTHX_ PL_no_aelem, (I32)LvTARGOFF(sv));
68dc0745 1614 }
1615 }
3e3baf6d 1616 (void)SvREFCNT_inc(value);
68dc0745 1617 SvREFCNT_dec(LvTARG(sv));
1618 LvTARG(sv) = value;
71be2cbc 1619 LvTARGLEN(sv) = 0;
68dc0745 1620 SvREFCNT_dec(mg->mg_obj);
1621 mg->mg_obj = Nullsv;
1622 mg->mg_flags &= ~MGf_REFCOUNTED;
5f05dabc 1623}
1624
1625int
864dbfa3 1626Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg)
810b8aa5
GS
1627{
1628 AV *av = (AV*)mg->mg_obj;
1629 SV **svp = AvARRAY(av);
1630 I32 i = AvFILLp(av);
1631 while (i >= 0) {
1632 if (svp[i] && svp[i] != &PL_sv_undef) {
1633 if (!SvWEAKREF(svp[i]))
cea2e8a9 1634 Perl_croak(aTHX_ "panic: magic_killbackrefs");
810b8aa5
GS
1635 /* XXX Should we check that it hasn't changed? */
1636 SvRV(svp[i]) = 0;
155aba94 1637 (void)SvOK_off(svp[i]);
810b8aa5
GS
1638 SvWEAKREF_off(svp[i]);
1639 svp[i] = &PL_sv_undef;
1640 }
1641 i--;
1642 }
1643 return 0;
1644}
1645
1646int
864dbfa3 1647Perl_magic_setmglob(pTHX_ SV *sv, MAGIC *mg)
93a17b20 1648{
565764a8 1649 mg->mg_len = -1;
c6496cc7 1650 SvSCREAM_off(sv);
93a17b20
LW
1651 return 0;
1652}
1653
1654int
864dbfa3 1655Perl_magic_setbm(pTHX_ SV *sv, MAGIC *mg)
79072805 1656{
14befaf4 1657 sv_unmagic(sv, PERL_MAGIC_bm);
79072805
LW
1658 SvVALID_off(sv);
1659 return 0;
1660}
1661
1662int
864dbfa3 1663Perl_magic_setfm(pTHX_ SV *sv, MAGIC *mg)
55497cff 1664{
14befaf4 1665 sv_unmagic(sv, PERL_MAGIC_fm);
55497cff 1666 SvCOMPILED_off(sv);
1667 return 0;
1668}
1669
1670int
864dbfa3 1671Perl_magic_setuvar(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1672{
1673 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1674
1675 if (uf && uf->uf_set)
24f81a43 1676 (*uf->uf_set)(aTHX_ uf->uf_index, sv);
79072805
LW
1677 return 0;
1678}
1679
c277df42 1680int
864dbfa3 1681Perl_magic_freeregexp(pTHX_ SV *sv, MAGIC *mg)
c277df42
IZ
1682{
1683 regexp *re = (regexp *)mg->mg_obj;
1684 ReREFCNT_dec(re);
1685 return 0;
1686}
1687
7a4c00b4 1688#ifdef USE_LOCALE_COLLATE
79072805 1689int
864dbfa3 1690Perl_magic_setcollxfrm(pTHX_ SV *sv, MAGIC *mg)
bbce6d69 1691{
1692 /*
838b5b74 1693 * RenE<eacute> Descartes said "I think not."
bbce6d69 1694 * and vanished with a faint plop.
1695 */
7a4c00b4 1696 if (mg->mg_ptr) {
1697 Safefree(mg->mg_ptr);
1698 mg->mg_ptr = NULL;
565764a8 1699 mg->mg_len = -1;
7a4c00b4 1700 }
bbce6d69 1701 return 0;
1702}
7a4c00b4 1703#endif /* USE_LOCALE_COLLATE */
bbce6d69 1704
1705int
864dbfa3 1706Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
79072805
LW
1707{
1708 register char *s;
1709 I32 i;
8990e307 1710 STRLEN len;
79072805 1711 switch (*mg->mg_ptr) {
748a9306 1712 case '\001': /* ^A */
3280af22 1713 sv_setsv(PL_bodytarget, sv);
748a9306 1714 break;
49460fe6
NIS
1715 case '\003': /* ^C */
1716 PL_minus_c = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1717 break;
1718
79072805 1719 case '\004': /* ^D */
aea4f609 1720 PL_debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | DEBUG_TOP_FLAG;
79072805
LW
1721 DEBUG_x(dump_all());
1722 break;
28f23441 1723 case '\005': /* ^E */
cd39f2b6 1724#ifdef MACOS_TRADITIONAL
bf4acbe4 1725 gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
28f23441 1726#else
cd39f2b6
JH
1727# ifdef VMS
1728 set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
048c1ddf 1729# else
cd39f2b6
JH
1730# ifdef WIN32
1731 SetLastError( SvIV(sv) );
1732# else
1733# ifndef OS2
f86702cc 1734 /* will anyone ever use this? */
1735 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
cd39f2b6 1736# endif
048c1ddf
IZ
1737# endif
1738# endif
22fae026 1739#endif
28f23441 1740 break;
79072805 1741 case '\006': /* ^F */
3280af22 1742 PL_maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1743 break;
a0d0e21e 1744 case '\010': /* ^H */
3280af22 1745 PL_hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
a0d0e21e 1746 break;
9d116dd7 1747 case '\011': /* ^I */ /* NOT \t in EBCDIC */
3280af22
NIS
1748 if (PL_inplace)
1749 Safefree(PL_inplace);
79072805 1750 if (SvOK(sv))
2d8e6c8d 1751 PL_inplace = savepv(SvPV(sv,len));
79072805 1752 else
3280af22 1753 PL_inplace = Nullch;
79072805 1754 break;
28f23441 1755 case '\017': /* ^O */
ac27b0f5
NIS
1756 if (*(mg->mg_ptr+1) == '\0') {
1757 if (PL_osname)
1758 Safefree(PL_osname);
1759 if (SvOK(sv))
1760 PL_osname = savepv(SvPV(sv,len));
1761 else
1762 PL_osname = Nullch;
1763 }
1764 else if (strEQ(mg->mg_ptr, "\017PEN")) {
1765 if (!PL_compiling.cop_io)
1766 PL_compiling.cop_io = newSVsv(sv);
1767 else
1768 sv_setsv(PL_compiling.cop_io,sv);
1769 }
28f23441 1770 break;
79072805 1771 case '\020': /* ^P */
3280af22 1772 PL_perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1ee4443e
IZ
1773 if (PL_perldb && !PL_DBsingle)
1774 init_debugger();
79072805
LW
1775 break;
1776 case '\024': /* ^T */
88e89b8a 1777#ifdef BIG_TIME
6b88bc9c 1778 PL_basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
88e89b8a 1779#else
3280af22 1780 PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
88e89b8a 1781#endif
79072805 1782 break;
46487f74 1783 case '\027': /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */
4438c4b7
JH
1784 if (*(mg->mg_ptr+1) == '\0') {
1785 if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
1786 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
ac27b0f5 1787 PL_dowarn = (PL_dowarn & ~G_WARN_ON)
0453d815 1788 | (i ? G_WARN_ON : G_WARN_OFF) ;
4438c4b7 1789 }
599cee73 1790 }
6a818117 1791 else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) {
4438c4b7 1792 if ( ! (PL_dowarn & G_WARN_ALL_MASK)) {
d775746e
GS
1793 if (!SvPOK(sv) && PL_localizing) {
1794 sv_setpvn(sv, WARN_NONEstring, WARNsize);
d3a7d8c7 1795 PL_compiling.cop_warnings = pWARN_NONE;
d775746e
GS
1796 break;
1797 }
f4fc7782 1798 {
b5477537 1799 STRLEN len, i;
d3a7d8c7 1800 int accumulate = 0 ;
f4fc7782 1801 int any_fatals = 0 ;
d3a7d8c7 1802 char * ptr = (char*)SvPV(sv, len) ;
f4fc7782
JH
1803 for (i = 0 ; i < len ; ++i) {
1804 accumulate |= ptr[i] ;
1805 any_fatals |= (ptr[i] & 0xAA) ;
1806 }
d3a7d8c7
GS
1807 if (!accumulate)
1808 PL_compiling.cop_warnings = pWARN_NONE;
f4fc7782
JH
1809 else if (isWARN_on(sv, WARN_ALL) && !any_fatals) {
1810 PL_compiling.cop_warnings = pWARN_ALL;
1811 PL_dowarn |= G_WARN_ONCE ;
1812 }
d3a7d8c7
GS
1813 else {
1814 if (specialWARN(PL_compiling.cop_warnings))
1815 PL_compiling.cop_warnings = newSVsv(sv) ;
1816 else
1817 sv_setsv(PL_compiling.cop_warnings, sv);
1818 if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE))
1819 PL_dowarn |= G_WARN_ONCE ;
1820 }
f4fc7782 1821
d3a7d8c7 1822 }
4438c4b7 1823 }
971a9dd3 1824 }
46487f74
GS
1825 else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS"))
1826 PL_widesyscalls = SvTRUE(sv);
79072805
LW
1827 break;
1828 case '.':
3280af22
NIS
1829 if (PL_localizing) {
1830 if (PL_localizing == 1)
7766f137 1831 SAVESPTR(PL_last_in_gv);
748a9306 1832 }
3280af22
NIS
1833 else if (SvOK(sv) && GvIO(PL_last_in_gv))
1834 IoLINES(GvIOp(PL_last_in_gv)) = (long)SvIV(sv);
79072805
LW
1835 break;
1836 case '^':
3280af22 1837 Safefree(IoTOP_NAME(GvIOp(PL_defoutgv)));
2d8e6c8d 1838 IoTOP_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
3280af22 1839 IoTOP_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
1840 break;
1841 case '~':
3280af22 1842 Safefree(IoFMT_NAME(GvIOp(PL_defoutgv)));
2d8e6c8d 1843 IoFMT_NAME(GvIOp(PL_defoutgv)) = s = savepv(SvPV(sv,len));
3280af22 1844 IoFMT_GV(GvIOp(PL_defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
1845 break;
1846 case '=':
3280af22 1847 IoPAGE_LEN(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1848 break;
1849 case '-':
3280af22
NIS
1850 IoLINES_LEFT(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1851 if (IoLINES_LEFT(GvIOp(PL_defoutgv)) < 0L)
1852 IoLINES_LEFT(GvIOp(PL_defoutgv)) = 0L;
79072805
LW
1853 break;
1854 case '%':
3280af22 1855 IoPAGE(GvIOp(PL_defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1856 break;
1857 case '|':
4b65379b 1858 {
3280af22 1859 IO *io = GvIOp(PL_defoutgv);
4b65379b
CS
1860 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1861 IoFLAGS(io) &= ~IOf_FLUSH;
1862 else {
1863 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1864 PerlIO *ofp = IoOFP(io);
1865 if (ofp)
1866 (void)PerlIO_flush(ofp);
1867 IoFLAGS(io) |= IOf_FLUSH;
1868 }
1869 }
79072805
LW
1870 }
1871 break;
1872 case '*':
463ee0b2 1873 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
3280af22 1874 PL_multiline = (i != 0);
79072805
LW
1875 break;
1876 case '/':
3280af22
NIS
1877 SvREFCNT_dec(PL_nrs);
1878 PL_nrs = newSVsv(sv);
1879 SvREFCNT_dec(PL_rs);
1880 PL_rs = SvREFCNT_inc(PL_nrs);
79072805
LW
1881 break;
1882 case '\\':
7889fe52
NIS
1883 if (PL_ors_sv)
1884 SvREFCNT_dec(PL_ors_sv);
009c130f 1885 if (SvOK(sv) || SvGMAGICAL(sv)) {
7889fe52 1886 PL_ors_sv = newSVsv(sv);
009c130f 1887 }
e3c19b7b 1888 else {
7889fe52 1889 PL_ors_sv = Nullsv;
e3c19b7b 1890 }
79072805
LW
1891 break;
1892 case ',':
7889fe52
NIS
1893 if (PL_ofs_sv)
1894 SvREFCNT_dec(PL_ofs_sv);
1895 if (SvOK(sv) || SvGMAGICAL(sv)) {
1896 PL_ofs_sv = newSVsv(sv);
1897 }
1898 else {
1899 PL_ofs_sv = Nullsv;
1900 }
79072805
LW
1901 break;
1902 case '#':
3280af22
NIS
1903 if (PL_ofmt)
1904 Safefree(PL_ofmt);
2d8e6c8d 1905 PL_ofmt = savepv(SvPV(sv,len));
79072805
LW
1906 break;
1907 case '[':
3280af22 1908 PL_compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1909 break;
1910 case '?':
ff0cee69 1911#ifdef COMPLEX_STATUS
6b88bc9c
GS
1912 if (PL_localizing == 2) {
1913 PL_statusvalue = LvTARGOFF(sv);
1914 PL_statusvalue_vms = LvTARGLEN(sv);
ff0cee69 1915 }
1916 else
1917#endif
1918#ifdef VMSISH_STATUS
1919 if (VMSISH_STATUS)
1920 STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1921 else
1922#endif
1923 STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1924 break;
1925 case '!':
78987ded 1926 SETERRNO(SvIOK(sv) ? SvIVX(sv) : SvOK(sv) ? sv_2iv(sv) : 0,
f86702cc 1927 (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
79072805
LW
1928 break;
1929 case '<':
3280af22
NIS
1930 PL_uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1931 if (PL_delaymagic) {
1932 PL_delaymagic |= DM_RUID;
79072805
LW
1933 break; /* don't do magic till later */
1934 }
1935#ifdef HAS_SETRUID
b28d0864 1936 (void)setruid((Uid_t)PL_uid);
79072805
LW
1937#else
1938#ifdef HAS_SETREUID
3280af22 1939 (void)setreuid((Uid_t)PL_uid, (Uid_t)-1);
748a9306 1940#else
85e6fe83 1941#ifdef HAS_SETRESUID
b28d0864 1942 (void)setresuid((Uid_t)PL_uid, (Uid_t)-1, (Uid_t)-1);
79072805 1943#else
b28d0864
NIS
1944 if (PL_uid == PL_euid) /* special case $< = $> */
1945 (void)PerlProc_setuid(PL_uid);
a0d0e21e 1946 else {
d8eceb89 1947 PL_uid = PerlProc_getuid();
cea2e8a9 1948 Perl_croak(aTHX_ "setruid() not implemented");
a0d0e21e 1949 }
79072805
LW
1950#endif
1951#endif
85e6fe83 1952#endif
d8eceb89 1953 PL_uid = PerlProc_getuid();
3280af22 1954 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805
LW
1955 break;
1956 case '>':
3280af22
NIS
1957 PL_euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1958 if (PL_delaymagic) {
1959 PL_delaymagic |= DM_EUID;
79072805
LW
1960 break; /* don't do magic till later */
1961 }
1962#ifdef HAS_SETEUID
3280af22 1963 (void)seteuid((Uid_t)PL_euid);
79072805
LW
1964#else
1965#ifdef HAS_SETREUID
b28d0864 1966 (void)setreuid((Uid_t)-1, (Uid_t)PL_euid);
85e6fe83
LW
1967#else
1968#ifdef HAS_SETRESUID
6b88bc9c 1969 (void)setresuid((Uid_t)-1, (Uid_t)PL_euid, (Uid_t)-1);
79072805 1970#else
b28d0864
NIS
1971 if (PL_euid == PL_uid) /* special case $> = $< */
1972 PerlProc_setuid(PL_euid);
a0d0e21e 1973 else {
e8ee3774 1974 PL_euid = PerlProc_geteuid();
cea2e8a9 1975 Perl_croak(aTHX_ "seteuid() not implemented");
a0d0e21e 1976 }
79072805
LW
1977#endif
1978#endif
85e6fe83 1979#endif
d8eceb89 1980 PL_euid = PerlProc_geteuid();
3280af22 1981 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805
LW
1982 break;
1983 case '(':
3280af22
NIS
1984 PL_gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1985 if (PL_delaymagic) {
1986 PL_delaymagic |= DM_RGID;
79072805
LW
1987 break; /* don't do magic till later */
1988 }
1989#ifdef HAS_SETRGID
b28d0864 1990 (void)setrgid((Gid_t)PL_gid);
79072805
LW
1991#else
1992#ifdef HAS_SETREGID
3280af22 1993 (void)setregid((Gid_t)PL_gid, (Gid_t)-1);
85e6fe83
LW
1994#else
1995#ifdef HAS_SETRESGID
b28d0864 1996 (void)setresgid((Gid_t)PL_gid, (Gid_t)-1, (Gid_t) 1);
79072805 1997#else
b28d0864
NIS
1998 if (PL_gid == PL_egid) /* special case $( = $) */
1999 (void)PerlProc_setgid(PL_gid);
748a9306 2000 else {
d8eceb89 2001 PL_gid = PerlProc_getgid();
cea2e8a9 2002 Perl_croak(aTHX_ "setrgid() not implemented");
748a9306 2003 }
79072805
LW
2004#endif
2005#endif
85e6fe83 2006#endif
d8eceb89 2007 PL_gid = PerlProc_getgid();
3280af22 2008 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805
LW
2009 break;
2010 case ')':
5cd24f17 2011#ifdef HAS_SETGROUPS
2012 {
2d8e6c8d 2013 char *p = SvPV(sv, len);
5cd24f17 2014 Groups_t gary[NGROUPS];
2015
5cd24f17 2016 while (isSPACE(*p))
2017 ++p;
2d4389e4 2018 PL_egid = Atol(p);
5cd24f17 2019 for (i = 0; i < NGROUPS; ++i) {
2020 while (*p && !isSPACE(*p))
2021 ++p;
2022 while (isSPACE(*p))
2023 ++p;
2024 if (!*p)
2025 break;
2d4389e4 2026 gary[i] = Atol(p);
5cd24f17 2027 }
8cc95fdb 2028 if (i)
2029 (void)setgroups(i, gary);
5cd24f17 2030 }
2031#else /* HAS_SETGROUPS */
b28d0864 2032 PL_egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
5cd24f17 2033#endif /* HAS_SETGROUPS */
3280af22
NIS
2034 if (PL_delaymagic) {
2035 PL_delaymagic |= DM_EGID;
79072805
LW
2036 break; /* don't do magic till later */
2037 }
2038#ifdef HAS_SETEGID
3280af22 2039 (void)setegid((Gid_t)PL_egid);
79072805
LW
2040#else
2041#ifdef HAS_SETREGID
b28d0864 2042 (void)setregid((Gid_t)-1, (Gid_t)PL_egid);
85e6fe83
LW
2043#else
2044#ifdef HAS_SETRESGID
b28d0864 2045 (void)setresgid((Gid_t)-1, (Gid_t)PL_egid, (Gid_t)-1);
79072805 2046#else
b28d0864
NIS
2047 if (PL_egid == PL_gid) /* special case $) = $( */
2048 (void)PerlProc_setgid(PL_egid);
748a9306 2049 else {
d8eceb89 2050 PL_egid = PerlProc_getegid();
cea2e8a9 2051 Perl_croak(aTHX_ "setegid() not implemented");
748a9306 2052 }
79072805
LW
2053#endif
2054#endif
85e6fe83 2055#endif
d8eceb89 2056 PL_egid = PerlProc_getegid();
3280af22 2057 PL_tainting |= (PL_uid && (PL_euid != PL_uid || PL_egid != PL_gid));
79072805
LW
2058 break;
2059 case ':':
2d8e6c8d 2060 PL_chopset = SvPV_force(sv,len);
79072805 2061 break;
cd39f2b6 2062#ifndef MACOS_TRADITIONAL
79072805 2063 case '0':
4bc88a62
PS
2064#ifdef HAS_SETPROCTITLE
2065 /* The BSDs don't show the argv[] in ps(1) output, they
2066 * show a string from the process struct and provide
2067 * the setproctitle() routine to manipulate that. */
2068 {
2069 s = SvPV(sv, len);
9aad2c0e
JH
2070# if __FreeBSD_version >= 410001
2071 /* The leading "-" removes the "perl: " prefix,
4bc88a62
PS
2072 * but not the "(perl) suffix from the ps(1)
2073 * output, because that's what ps(1) shows if the
2074 * argv[] is modified. */
2075 setproctitle("-%s", s, len + 1);
9aad2c0e 2076# else /* old FreeBSDs, NetBSD, OpenBSD, anyBSD */
4bc88a62
PS
2077 /* This doesn't really work if you assume that
2078 * $0 = 'foobar'; will wipe out 'perl' from the $0
2079 * because in ps(1) output the result will be like
2080 * sprintf("perl: %s (perl)", s)
2081 * I guess this is a security feature:
2082 * one (a user process) cannot get rid of the original name.
2083 * --jhi */
2084 setproctitle("%s", s);
2085# endif
2086 }
2087#endif
3280af22
NIS
2088 if (!PL_origalen) {
2089 s = PL_origargv[0];
79072805
LW
2090 s += strlen(s);
2091 /* See if all the arguments are contiguous in memory */
3280af22
NIS
2092 for (i = 1; i < PL_origargc; i++) {
2093 if (PL_origargv[i] == s + 1
fb73857a 2094#ifdef OS2
6b88bc9c 2095 || PL_origargv[i] == s + 2
ac27b0f5 2096#endif
fb73857a 2097 )
379c4362
GS
2098 {
2099 ++s;
2100 s += strlen(s); /* this one is ok too */
2101 }
fb73857a 2102 else
2103 break;
79072805 2104 }
bbce6d69 2105 /* can grab env area too? */
3280af22 2106 if (PL_origenviron && (PL_origenviron[0] == s + 1
fb73857a 2107#ifdef OS2
6b88bc9c 2108 || (PL_origenviron[0] == s + 9 && (s += 8))
ac27b0f5 2109#endif
fb73857a 2110 )) {
66b1d557 2111 my_setenv("NoNe SuCh", Nullch);
79072805 2112 /* force copy of environment */
3280af22 2113 for (i = 0; PL_origenviron[i]; i++)
379c4362
GS
2114 if (PL_origenviron[i] == s + 1) {
2115 ++s;
2116 s += strlen(s);
2117 }
fb73857a 2118 else
2119 break;
79072805 2120 }
3280af22 2121 PL_origalen = s - PL_origargv[0];
79072805 2122 }
a0d0e21e 2123 s = SvPV_force(sv,len);
8990e307 2124 i = len;
3280af22
NIS
2125 if (i >= PL_origalen) {
2126 i = PL_origalen;
fb73857a 2127 /* don't allow system to limit $0 seen by script */
2128 /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
3280af22
NIS
2129 Copy(s, PL_origargv[0], i, char);
2130 s = PL_origargv[0]+i;
fb73857a 2131 *s = '\0';
79072805
LW
2132 }
2133 else {
3280af22
NIS
2134 Copy(s, PL_origargv[0], i, char);
2135 s = PL_origargv[0]+i;
79072805 2136 *s++ = '\0';
3280af22 2137 while (++i < PL_origalen)
8990e307 2138 *s++ = ' ';
3280af22
NIS
2139 s = PL_origargv[0]+i;
2140 for (i = 1; i < PL_origargc; i++)
2141 PL_origargv[i] = Nullch;
79072805
LW
2142 }
2143 break;
cd39f2b6 2144#endif
a863c7d1
MB
2145#ifdef USE_THREADS
2146 case '@':
38a03e6e 2147 sv_setsv(thr->errsv, sv);
a863c7d1
MB
2148 break;
2149#endif /* USE_THREADS */
79072805
LW
2150 }
2151 return 0;
2152}
2153
f93b4edd
MB
2154#ifdef USE_THREADS
2155int
864dbfa3 2156Perl_magic_mutexfree(pTHX_ SV *sv, MAGIC *mg)
f93b4edd 2157{
b900a521
JH
2158 DEBUG_S(PerlIO_printf(Perl_debug_log,
2159 "0x%"UVxf": magic_mutexfree 0x%"UVxf"\n",
2160 PTR2UV(thr), PTR2UV(sv));)
f93b4edd 2161 if (MgOWNER(mg))
cea2e8a9 2162 Perl_croak(aTHX_ "panic: magic_mutexfree");
f93b4edd
MB
2163 MUTEX_DESTROY(MgMUTEXP(mg));
2164 COND_DESTROY(MgCONDP(mg));
2165 return 0;
2166}
2167#endif /* USE_THREADS */
2168
79072805 2169I32
864dbfa3 2170Perl_whichsig(pTHX_ char *sig)
79072805
LW
2171{
2172 register char **sigv;
2173
22c35a8c 2174 for (sigv = PL_sig_name+1; *sigv; sigv++)
79072805 2175 if (strEQ(sig,*sigv))
22c35a8c 2176 return PL_sig_num[sigv - PL_sig_name];
79072805
LW
2177#ifdef SIGCLD
2178 if (strEQ(sig,"CHLD"))
2179 return SIGCLD;
2180#endif
2181#ifdef SIGCHLD
2182 if (strEQ(sig,"CLD"))
2183 return SIGCHLD;
2184#endif
2185 return 0;
2186}
2187
84902520
TB
2188static SV* sig_sv;
2189
ecfc5424 2190Signal_t
cea2e8a9 2191Perl_sighandler(int sig)
79072805 2192{
71d280e3
GS
2193#if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2194 dTHXoa(PL_curinterp); /* fake TLS, because signals don't do TLS */
2195#else
cea2e8a9 2196 dTHX;
71d280e3 2197#endif
79072805 2198 dSP;
00d579c5 2199 GV *gv = Nullgv;
a0d0e21e 2200 HV *st;
b7953727 2201 SV *sv = Nullsv, *tSv = PL_Sv;
00d579c5 2202 CV *cv = Nullcv;
533c011a 2203 OP *myop = PL_op;
84902520 2204 U32 flags = 0;
155aba94 2205 I32 o_save_i = PL_savestack_ix;
3280af22 2206 XPV *tXpv = PL_Xpv;
71d280e3
GS
2207
2208#if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT)
2209 PERL_SET_THX(aTHXo); /* fake TLS, see above */
2210#endif
ac27b0f5 2211
3280af22 2212 if (PL_savestack_ix + 15 <= PL_savestack_max)
84902520 2213 flags |= 1;
3280af22 2214 if (PL_markstack_ptr < PL_markstack_max - 2)
84902520 2215 flags |= 4;
3280af22 2216 if (PL_retstack_ix < PL_retstack_max - 2)
84902520 2217 flags |= 8;
3280af22 2218 if (PL_scopestack_ix < PL_scopestack_max - 3)
84902520
TB
2219 flags |= 16;
2220
22c35a8c 2221 if (!PL_psig_ptr[sig])
cea2e8a9 2222 Perl_die(aTHX_ "Signal SIG%s received, but no signal handler set.\n",
22c35a8c 2223 PL_sig_name[sig]);
ff0cee69 2224
84902520
TB
2225 /* Max number of items pushed there is 3*n or 4. We cannot fix
2226 infinity, so we fix 4 (in fact 5): */
2227 if (flags & 1) {
3280af22
NIS
2228 PL_savestack_ix += 5; /* Protect save in progress. */
2229 o_save_i = PL_savestack_ix;
c76ac1ee 2230 SAVEDESTRUCTOR_X(unwind_handler_stack, (void*)&flags);
84902520 2231 }
ac27b0f5 2232 if (flags & 4)
3280af22 2233 PL_markstack_ptr++; /* Protect mark. */
84902520 2234 if (flags & 8) {
3280af22
NIS
2235 PL_retstack_ix++;
2236 PL_retstack[PL_retstack_ix] = NULL;
84902520
TB
2237 }
2238 if (flags & 16)
3280af22 2239 PL_scopestack_ix += 1;
84902520 2240 /* sv_2cv is too complicated, try a simpler variant first: */
ac27b0f5 2241 if (!SvROK(PL_psig_ptr[sig]) || !(cv = (CV*)SvRV(PL_psig_ptr[sig]))
84902520 2242 || SvTYPE(cv) != SVt_PVCV)
22c35a8c 2243 cv = sv_2cv(PL_psig_ptr[sig],&st,&gv,TRUE);
84902520 2244
a0d0e21e 2245 if (!cv || !CvROOT(cv)) {
599cee73 2246 if (ckWARN(WARN_SIGNAL))
cea2e8a9 2247 Perl_warner(aTHX_ WARN_SIGNAL, "SIG%s handler \"%s\" not defined.\n",
22c35a8c 2248 PL_sig_name[sig], (gv ? GvENAME(gv)
00d579c5
GS
2249 : ((cv && CvGV(cv))
2250 ? GvENAME(CvGV(cv))
2251 : "__ANON__")));
2252 goto cleanup;
79072805
LW
2253 }
2254
22c35a8c
GS
2255 if(PL_psig_name[sig]) {
2256 sv = SvREFCNT_inc(PL_psig_name[sig]);
84902520
TB
2257 flags |= 64;
2258 sig_sv = sv;
2259 } else {
ff0cee69 2260 sv = sv_newmortal();
22c35a8c 2261 sv_setpv(sv,PL_sig_name[sig]);
88e89b8a 2262 }
e336de0d 2263
e788e7d3 2264 PUSHSTACKi(PERLSI_SIGNAL);
924508f0 2265 PUSHMARK(SP);
79072805 2266 PUSHs(sv);
79072805 2267 PUTBACK;
a0d0e21e 2268
1b266415 2269 call_sv((SV*)cv, G_DISCARD|G_EVAL);
79072805 2270
d3acc0f7 2271 POPSTACK;
1b266415 2272 if (SvTRUE(ERRSV)) {
1d615522 2273#ifndef PERL_MICRO
983dbef6 2274#ifdef HAS_SIGPROCMASK
1b266415
NIS
2275 /* Handler "died", for example to get out of a restart-able read().
2276 * Before we re-do that on its behalf re-enable the signal which was
2277 * blocked by the system when we entered.
2278 */
2279 sigset_t set;
2280 sigemptyset(&set);
2281 sigaddset(&set,sig);
2282 sigprocmask(SIG_UNBLOCK, &set, NULL);
2283#else
2284 /* Not clear if this will work */
2285 (void)rsignal(sig, SIG_IGN);
0a8e0eff 2286 (void)rsignal(sig, &Perl_csighandler);
1b266415 2287#endif
1d615522 2288#endif /* !PERL_MICRO */
1b266415
NIS
2289 Perl_die(aTHX_ Nullch);
2290 }
00d579c5 2291cleanup:
84902520 2292 if (flags & 1)
3280af22 2293 PL_savestack_ix -= 8; /* Unprotect save in progress. */
ac27b0f5 2294 if (flags & 4)
3280af22 2295 PL_markstack_ptr--;
ac27b0f5 2296 if (flags & 8)
3280af22 2297 PL_retstack_ix--;
84902520 2298 if (flags & 16)
3280af22 2299 PL_scopestack_ix -= 1;
84902520
TB
2300 if (flags & 64)
2301 SvREFCNT_dec(sv);
533c011a 2302 PL_op = myop; /* Apparently not needed... */
ac27b0f5 2303
3280af22
NIS
2304 PL_Sv = tSv; /* Restore global temporaries. */
2305 PL_Xpv = tXpv;
79072805
LW
2306 return;
2307}
4e35701f
NIS
2308
2309
51371543 2310#ifdef PERL_OBJECT
51371543
GS
2311#include "XSUB.h"
2312#endif
2313
2314static void
2315restore_magic(pTHXo_ void *p)
2316{
48944bdf 2317 MGS* mgs = SSPTR(PTR2IV(p), MGS*);
51371543
GS
2318 SV* sv = mgs->mgs_sv;
2319
2320 if (!sv)
2321 return;
2322
2323 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
2324 {
2325 if (mgs->mgs_flags)
2326 SvFLAGS(sv) |= mgs->mgs_flags;
2327 else
2328 mg_magical(sv);
2329 if (SvGMAGICAL(sv))
2330 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
2331 }
2332
2333 mgs->mgs_sv = NULL; /* mark the MGS structure as restored */
2334
2335 /* If we're still on top of the stack, pop us off. (That condition
2336 * will be satisfied if restore_magic was called explicitly, but *not*
2337 * if it's being called via leave_scope.)
2338 * The reason for doing this is that otherwise, things like sv_2cv()
2339 * may leave alloc gunk on the savestack, and some code
2340 * (e.g. sighandler) doesn't expect that...
2341 */
2342 if (PL_savestack_ix == mgs->mgs_ss_ix)
2343 {
2344 I32 popval = SSPOPINT;
c76ac1ee 2345 assert(popval == SAVEt_DESTRUCTOR_X);
51371543
GS
2346 PL_savestack_ix -= 2;
2347 popval = SSPOPINT;
2348 assert(popval == SAVEt_ALLOC);
2349 popval = SSPOPINT;
2350 PL_savestack_ix -= popval;
2351 }
2352
2353}
2354
2355static void
2356unwind_handler_stack(pTHXo_ void *p)
2357{
51371543
GS
2358 U32 flags = *(U32*)p;
2359
2360 if (flags & 1)
2361 PL_savestack_ix -= 5; /* Unprotect save in progress. */
2362 /* cxstack_ix-- Not needed, die already unwound it. */
2363 if (flags & 64)
2364 SvREFCNT_dec(sig_sv);
2365}