Change pp_tie and pp_dbmopen to use perl_call_sv instead of a
[p5sagit/p5-mst-13.2.git] / mg.c
CommitLineData
a0d0e21e 1/* mg.c
79072805 2 *
9607fc9c 3 * Copyright (c) 1991-1997, Larry Wall
79072805 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 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 13 */
14
15#include "EXTERN.h"
16#include "perl.h"
17
e6d9441c 18/* XXX If this causes problems, set i_unistd=undef in the hint file. */
a0d0e21e 19#ifdef I_UNISTD
20# include <unistd.h>
21#endif
a0d0e21e 22
5cd24f17 23#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
188ea221 24# ifndef NGROUPS
25# define NGROUPS 32
26# endif
27#endif
28
c07a80fd 29/*
30 * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
31 */
32
33struct magic_state {
34 SV* mgs_sv;
35 U32 mgs_flags;
36};
37typedef struct magic_state MGS;
38
39static void restore_magic _((void *p));
40
48e43a1c 41static void
42save_magic(mgs, sv)
43MGS* mgs;
c07a80fd 44SV* sv;
45{
c07a80fd 46 assert(SvMAGICAL(sv));
47
c07a80fd 48 mgs->mgs_sv = sv;
49 mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
50 SAVEDESTRUCTOR(restore_magic, mgs);
51
52 SvMAGICAL_off(sv);
53 SvREADONLY_off(sv);
54 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
c07a80fd 55}
56
57static void
58restore_magic(p)
59void* p;
60{
48e43a1c 61 MGS* mgs = (MGS*)p;
c07a80fd 62 SV* sv = mgs->mgs_sv;
63
64 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
65 {
66 if (mgs->mgs_flags)
67 SvFLAGS(sv) |= mgs->mgs_flags;
68 else
69 mg_magical(sv);
70 if (SvGMAGICAL(sv))
71 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
72 }
c07a80fd 73}
74
8e07c86e 75
8990e307 76void
77mg_magical(sv)
78SV* sv;
79{
80 MAGIC* mg;
81 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
82 MGVTBL* vtbl = mg->mg_virtual;
83 if (vtbl) {
a0d0e21e 84 if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
8990e307 85 SvGMAGICAL_on(sv);
86 if (vtbl->svt_set)
87 SvSMAGICAL_on(sv);
88 if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
89 SvRMAGICAL_on(sv);
90 }
91 }
92}
93
79072805 94int
95mg_get(sv)
96SV* sv;
97{
48e43a1c 98 MGS mgs;
79072805 99 MAGIC* mg;
c6496cc7 100 MAGIC** mgp;
760ac839 101 int mgp_valid = 0;
463ee0b2 102
c07a80fd 103 ENTER;
48e43a1c 104 save_magic(&mgs, sv);
463ee0b2 105
c6496cc7 106 mgp = &SvMAGIC(sv);
107 while ((mg = *mgp) != 0) {
79072805 108 MGVTBL* vtbl = mg->mg_virtual;
a0d0e21e 109 if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
79072805 110 (*vtbl->svt_get)(sv, mg);
c6496cc7 111 /* Ignore this magic if it's been deleted */
48e43a1c 112 if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
113 (mg->mg_flags & MGf_GSKIP))
114 mgs.mgs_flags = 0;
a0d0e21e 115 }
c6496cc7 116 /* Advance to next magic (complicated by possible deletion) */
760ac839 117 if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
c6496cc7 118 mgp = &mg->mg_moremagic;
760ac839 119 mgp_valid = 1;
120 }
121 else
122 mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
79072805 123 }
463ee0b2 124
c07a80fd 125 LEAVE;
79072805 126 return 0;
127}
128
129int
130mg_set(sv)
131SV* sv;
132{
48e43a1c 133 MGS mgs;
79072805 134 MAGIC* mg;
463ee0b2 135 MAGIC* nextmg;
136
c07a80fd 137 ENTER;
48e43a1c 138 save_magic(&mgs, sv);
463ee0b2 139
140 for (mg = SvMAGIC(sv); mg; mg = nextmg) {
79072805 141 MGVTBL* vtbl = mg->mg_virtual;
463ee0b2 142 nextmg = mg->mg_moremagic; /* it may delete itself */
a0d0e21e 143 if (mg->mg_flags & MGf_GSKIP) {
144 mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
48e43a1c 145 mgs.mgs_flags = 0;
a0d0e21e 146 }
79072805 147 if (vtbl && vtbl->svt_set)
148 (*vtbl->svt_set)(sv, mg);
149 }
463ee0b2 150
c07a80fd 151 LEAVE;
79072805 152 return 0;
153}
154
155U32
156mg_len(sv)
157SV* sv;
158{
159 MAGIC* mg;
748a9306 160 char *junk;
463ee0b2 161 STRLEN len;
463ee0b2 162
79072805 163 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
164 MGVTBL* vtbl = mg->mg_virtual;
85e6fe83 165 if (vtbl && vtbl->svt_len) {
48e43a1c 166 MGS mgs;
167
c07a80fd 168 ENTER;
48e43a1c 169 save_magic(&mgs, sv);
a0d0e21e 170 /* omit MGf_GSKIP -- not changed here */
85e6fe83 171 len = (*vtbl->svt_len)(sv, mg);
c07a80fd 172 LEAVE;
85e6fe83 173 return len;
174 }
175 }
176
748a9306 177 junk = SvPV(sv, len);
463ee0b2 178 return len;
79072805 179}
180
181int
182mg_clear(sv)
183SV* sv;
184{
48e43a1c 185 MGS mgs;
79072805 186 MAGIC* mg;
463ee0b2 187
c07a80fd 188 ENTER;
48e43a1c 189 save_magic(&mgs, sv);
463ee0b2 190
79072805 191 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
192 MGVTBL* vtbl = mg->mg_virtual;
a0d0e21e 193 /* omit GSKIP -- never set here */
194
79072805 195 if (vtbl && vtbl->svt_clear)
196 (*vtbl->svt_clear)(sv, mg);
197 }
463ee0b2 198
c07a80fd 199 LEAVE;
79072805 200 return 0;
201}
202
93a17b20 203MAGIC*
204mg_find(sv, type)
205SV* sv;
a0d0e21e 206int type;
93a17b20 207{
208 MAGIC* mg;
93a17b20 209 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
210 if (mg->mg_type == type)
211 return mg;
212 }
213 return 0;
214}
215
79072805 216int
463ee0b2 217mg_copy(sv, nsv, key, klen)
79072805 218SV* sv;
463ee0b2 219SV* nsv;
220char *key;
88e89b8a 221I32 klen;
79072805 222{
463ee0b2 223 int count = 0;
79072805 224 MAGIC* mg;
463ee0b2 225 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
226 if (isUPPER(mg->mg_type)) {
a0d0e21e 227 sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
463ee0b2 228 count++;
79072805 229 }
79072805 230 }
463ee0b2 231 return count;
79072805 232}
233
234int
463ee0b2 235mg_free(sv)
79072805 236SV* sv;
237{
238 MAGIC* mg;
239 MAGIC* moremagic;
240 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
241 MGVTBL* vtbl = mg->mg_virtual;
242 moremagic = mg->mg_moremagic;
243 if (vtbl && vtbl->svt_free)
244 (*vtbl->svt_free)(sv, mg);
93a17b20 245 if (mg->mg_ptr && mg->mg_type != 'g')
88e89b8a 246 if (mg->mg_len >= 0)
247 Safefree(mg->mg_ptr);
248 else if (mg->mg_len == HEf_SVKEY)
249 SvREFCNT_dec((SV*)mg->mg_ptr);
85e6fe83 250 if (mg->mg_flags & MGf_REFCOUNTED)
8990e307 251 SvREFCNT_dec(mg->mg_obj);
79072805 252 Safefree(mg);
253 }
254 SvMAGIC(sv) = 0;
255 return 0;
256}
257
258#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
259#include <signal.h>
260#endif
261
93a17b20 262U32
263magic_len(sv, mg)
264SV *sv;
265MAGIC *mg;
266{
a863c7d1 267 dTHR;
93a17b20 268 register I32 paren;
269 register char *s;
270 register I32 i;
bbce6d69 271 register REGEXP *rx;
748a9306 272 char *t;
93a17b20 273
274 switch (*mg->mg_ptr) {
275 case '1': case '2': case '3': case '4':
276 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 277 if (curpm && (rx = curpm->op_pmregexp)) {
93a17b20 278 paren = atoi(mg->mg_ptr);
279 getparen:
bbce6d69 280 if (paren <= rx->nparens &&
281 (s = rx->startp[paren]) &&
282 (t = rx->endp[paren]))
283 {
748a9306 284 i = t - s;
71be2cbc 285 if (i >= 0)
93a17b20 286 return i;
93a17b20 287 }
93a17b20 288 }
748a9306 289 return 0;
93a17b20 290 case '+':
bbce6d69 291 if (curpm && (rx = curpm->op_pmregexp)) {
292 paren = rx->lastparen;
13f57bf8 293 if (paren)
294 goto getparen;
93a17b20 295 }
748a9306 296 return 0;
93a17b20 297 case '`':
bbce6d69 298 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 299 if ((s = rx->subbeg) && rx->startp[0]) {
bbce6d69 300 i = rx->startp[0] - s;
71be2cbc 301 if (i >= 0)
93a17b20 302 return i;
93a17b20 303 }
93a17b20 304 }
748a9306 305 return 0;
93a17b20 306 case '\'':
bbce6d69 307 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 308 if (rx->subend && (s = rx->endp[0])) {
309 i = rx->subend - s;
310 if (i >= 0)
5cd24f17 311 return i;
93a17b20 312 }
93a17b20 313 }
748a9306 314 return 0;
93a17b20 315 case ',':
316 return (STRLEN)ofslen;
317 case '\\':
318 return (STRLEN)orslen;
319 }
320 magic_get(sv,mg);
321 if (!SvPOK(sv) && SvNIOK(sv))
463ee0b2 322 sv_2pv(sv, &na);
93a17b20 323 if (SvPOK(sv))
324 return SvCUR(sv);
325 return 0;
326}
327
79072805 328int
329magic_get(sv, mg)
330SV *sv;
331MAGIC *mg;
332{
a863c7d1 333 dTHR;
79072805 334 register I32 paren;
335 register char *s;
336 register I32 i;
bbce6d69 337 register REGEXP *rx;
748a9306 338 char *t;
79072805 339
340 switch (*mg->mg_ptr) {
748a9306 341 case '\001': /* ^A */
342 sv_setsv(sv, bodytarget);
343 break;
79072805 344 case '\004': /* ^D */
188ea221 345 sv_setiv(sv, (IV)(debug & 32767));
79072805 346 break;
28f23441 347 case '\005': /* ^E */
348#ifdef VMS
349 {
350# include <descrip.h>
351# include <starlet.h>
352 char msg[255];
353 $DESCRIPTOR(msgdsc,msg);
946ec16e 354 sv_setnv(sv,(double) vaxc$errno);
28f23441 355 if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
356 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
357 else
358 sv_setpv(sv,"");
359 }
360#else
88e89b8a 361#ifdef OS2
fb73857a 362 if (!(_emx_env & 0x200)) { /* Under DOS */
363 sv_setnv(sv, (double)errno);
364 sv_setpv(sv, errno ? Strerror(errno) : "");
365 } else {
366 if (errno != errno_isOS2)
367 Perl_rc = _syserrno();
368 sv_setnv(sv, (double)Perl_rc);
369 sv_setpv(sv, os2error(Perl_rc));
370 }
88e89b8a 371#else
946ec16e 372 sv_setnv(sv, (double)errno);
28f23441 373 sv_setpv(sv, errno ? Strerror(errno) : "");
374#endif
88e89b8a 375#endif
946ec16e 376 SvNOK_on(sv); /* what a wonderful hack! */
28f23441 377 break;
79072805 378 case '\006': /* ^F */
188ea221 379 sv_setiv(sv, (IV)maxsysfd);
79072805 380 break;
a0d0e21e 381 case '\010': /* ^H */
188ea221 382 sv_setiv(sv, (IV)hints);
a0d0e21e 383 break;
79072805 384 case '\t': /* ^I */
385 if (inplace)
386 sv_setpv(sv, inplace);
387 else
188ea221 388 sv_setsv(sv, &sv_undef);
79072805 389 break;
28f23441 390 case '\017': /* ^O */
188ea221 391 sv_setpv(sv, osname);
28f23441 392 break;
79072805 393 case '\020': /* ^P */
188ea221 394 sv_setiv(sv, (IV)perldb);
79072805 395 break;
fb73857a 396 case '\023': /* ^S */
d58bf5aa 397 {
398 dTHR;
399 if (lex_state != LEX_NOTPARSING)
400 SvOK_off(sv);
401 else if (in_eval)
402 sv_setiv(sv, 1);
403 else
404 sv_setiv(sv, 0);
405 }
fb73857a 406 break;
79072805 407 case '\024': /* ^T */
88e89b8a 408#ifdef BIG_TIME
188ea221 409 sv_setnv(sv, basetime);
88e89b8a 410#else
188ea221 411 sv_setiv(sv, (IV)basetime);
88e89b8a 412#endif
79072805 413 break;
414 case '\027': /* ^W */
188ea221 415 sv_setiv(sv, (IV)dowarn);
79072805 416 break;
417 case '1': case '2': case '3': case '4':
418 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 419 if (curpm && (rx = curpm->op_pmregexp)) {
a863c7d1 420 /*
421 * Pre-threads, this was paren = atoi(GvENAME((GV*)mg->mg_obj));
422 * XXX Does the new way break anything?
423 */
424 paren = atoi(mg->mg_ptr);
79072805 425 getparen:
bbce6d69 426 if (paren <= rx->nparens &&
427 (s = rx->startp[paren]) &&
428 (t = rx->endp[paren]))
429 {
748a9306 430 i = t - s;
13f57bf8 431 getrx:
748a9306 432 if (i >= 0) {
13f57bf8 433 bool was_tainted;
434 if (tainting) {
435 was_tainted = tainted;
436 tainted = FALSE;
437 }
79072805 438 sv_setpvn(sv,s,i);
13f57bf8 439 if (tainting)
440 tainted = was_tainted || rx->exec_tainted;
748a9306 441 break;
442 }
79072805 443 }
79072805 444 }
748a9306 445 sv_setsv(sv,&sv_undef);
79072805 446 break;
447 case '+':
bbce6d69 448 if (curpm && (rx = curpm->op_pmregexp)) {
449 paren = rx->lastparen;
a0d0e21e 450 if (paren)
451 goto getparen;
79072805 452 }
748a9306 453 sv_setsv(sv,&sv_undef);
79072805 454 break;
455 case '`':
bbce6d69 456 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 457 if ((s = rx->subbeg) && rx->startp[0]) {
bbce6d69 458 i = rx->startp[0] - s;
13f57bf8 459 goto getrx;
79072805 460 }
79072805 461 }
748a9306 462 sv_setsv(sv,&sv_undef);
79072805 463 break;
464 case '\'':
bbce6d69 465 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 466 if (rx->subend && (s = rx->endp[0])) {
467 i = rx->subend - s;
468 goto getrx;
79072805 469 }
79072805 470 }
748a9306 471 sv_setsv(sv,&sv_undef);
79072805 472 break;
473 case '.':
474#ifndef lint
a0d0e21e 475 if (GvIO(last_in_gv)) {
188ea221 476 sv_setiv(sv, (IV)IoLINES(GvIO(last_in_gv)));
79072805 477 }
478#endif
479 break;
480 case '?':
809a5acc 481 {
482 dTHR;
483 sv_setiv(sv, (IV)STATUS_CURRENT);
ff0cee69 484#ifdef COMPLEX_STATUS
809a5acc 485 LvTARGOFF(sv) = statusvalue;
486 LvTARGLEN(sv) = statusvalue_vms;
ff0cee69 487#endif
809a5acc 488 }
79072805 489 break;
490 case '^':
a0d0e21e 491 s = IoTOP_NAME(GvIOp(defoutgv));
79072805 492 if (s)
493 sv_setpv(sv,s);
494 else {
495 sv_setpv(sv,GvENAME(defoutgv));
496 sv_catpv(sv,"_TOP");
497 }
498 break;
499 case '~':
a0d0e21e 500 s = IoFMT_NAME(GvIOp(defoutgv));
79072805 501 if (!s)
502 s = GvENAME(defoutgv);
503 sv_setpv(sv,s);
504 break;
505#ifndef lint
506 case '=':
188ea221 507 sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(defoutgv)));
79072805 508 break;
509 case '-':
188ea221 510 sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(defoutgv)));
79072805 511 break;
512 case '%':
188ea221 513 sv_setiv(sv, (IV)IoPAGE(GvIOp(defoutgv)));
79072805 514 break;
515#endif
516 case ':':
517 break;
518 case '/':
519 break;
520 case '[':
0f15f207 521 WITH_THR(sv_setiv(sv, (IV)curcop->cop_arybase));
79072805 522 break;
523 case '|':
188ea221 524 sv_setiv(sv, (IV)(IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
79072805 525 break;
526 case ',':
527 sv_setpvn(sv,ofs,ofslen);
528 break;
529 case '\\':
530 sv_setpvn(sv,ors,orslen);
531 break;
532 case '#':
533 sv_setpv(sv,ofmt);
534 break;
535 case '!':
a5f75d66 536#ifdef VMS
946ec16e 537 sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
88e89b8a 538 sv_setpv(sv, errno ? Strerror(errno) : "");
a5f75d66 539#else
88e89b8a 540 {
541 int saveerrno = errno;
946ec16e 542 sv_setnv(sv, (double)errno);
88e89b8a 543#ifdef OS2
544 if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
545 else
a5f75d66 546#endif
2304df62 547 sv_setpv(sv, errno ? Strerror(errno) : "");
88e89b8a 548 errno = saveerrno;
549 }
550#endif
946ec16e 551 SvNOK_on(sv); /* what a wonderful hack! */
79072805 552 break;
553 case '<':
188ea221 554 sv_setiv(sv, (IV)uid);
79072805 555 break;
556 case '>':
188ea221 557 sv_setiv(sv, (IV)euid);
79072805 558 break;
559 case '(':
188ea221 560 sv_setiv(sv, (IV)gid);
fc36a67e 561 sv_setpvf(sv, "%Vd", (IV)gid);
79072805 562 goto add_groups;
563 case ')':
188ea221 564 sv_setiv(sv, (IV)egid);
fc36a67e 565 sv_setpvf(sv, "%Vd", (IV)egid);
79072805 566 add_groups:
79072805 567#ifdef HAS_GETGROUPS
79072805 568 {
a0d0e21e 569 Groups_t gary[NGROUPS];
79072805 570 i = getgroups(NGROUPS,gary);
46fc3d4c 571 while (--i >= 0)
fc36a67e 572 sv_catpvf(sv, " %Vd", (IV)gary[i]);
79072805 573 }
574#endif
29355cf7 575 SvIOK_on(sv); /* what a wonderful hack! */
79072805 576 break;
577 case '*':
578 break;
579 case '0':
580 break;
a863c7d1 581#ifdef USE_THREADS
582 case '@':
583 sv_setsv(sv, errsv);
584 break;
585#endif /* USE_THREADS */
79072805 586 }
a0d0e21e 587 return 0;
79072805 588}
589
590int
591magic_getuvar(sv, mg)
592SV *sv;
593MAGIC *mg;
594{
595 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
596
597 if (uf && uf->uf_val)
598 (*uf->uf_val)(uf->uf_index, sv);
599 return 0;
600}
601
602int
603magic_setenv(sv,mg)
604SV* sv;
605MAGIC* mg;
606{
607 register char *s;
88e89b8a 608 char *ptr;
5aabfad6 609 STRLEN len, klen;
a0d0e21e 610 I32 i;
1e422769 611
a0d0e21e 612 s = SvPV(sv,len);
5aabfad6 613 ptr = MgPV(mg,klen);
88e89b8a 614 my_setenv(ptr, s);
1e422769 615
a0d0e21e 616#ifdef DYNAMIC_ENV_FETCH
617 /* We just undefd an environment var. Is a replacement */
618 /* waiting in the wings? */
619 if (!len) {
5aabfad6 620 SV **valp;
621 if ((valp = hv_fetch(GvHVn(envgv), ptr, klen, FALSE)))
622 s = SvPV(*valp, len);
a0d0e21e 623 }
624#endif
1e422769 625
3e3baf6d 626#if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32)
79072805 627 /* And you'll never guess what the dog had */
628 /* in its mouth... */
463ee0b2 629 if (tainting) {
1e422769 630 MgTAINTEDDIR_off(mg);
631#ifdef VMS
5aabfad6 632 if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) {
1e422769 633 char pathbuf[256], eltbuf[256], *cp, *elt = s;
634 struct stat sbuf;
635 int i = 0, j = 0;
636
637 do { /* DCL$PATH may be a search list */
638 while (1) { /* as may dev portion of any element */
639 if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
640 if ( *(cp+1) == '.' || *(cp+1) == '-' ||
641 cando_by_name(S_IWUSR,0,elt) ) {
642 MgTAINTEDDIR_on(mg);
643 return 0;
644 }
645 }
646 if ((cp = strchr(elt, ':')) != Nullch)
647 *cp = '\0';
648 if (my_trnlnm(elt, eltbuf, j++))
649 elt = eltbuf;
650 else
651 break;
652 }
653 j = 0;
654 } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
655 }
656#endif /* VMS */
5aabfad6 657 if (s && klen == 4 && strEQ(ptr,"PATH")) {
a0d0e21e 658 char *strend = s + len;
463ee0b2 659
660 while (s < strend) {
96827780 661 char tmpbuf[256];
1e422769 662 struct stat st;
96827780 663 s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf,
fc36a67e 664 s, strend, ':', &i);
463ee0b2 665 s++;
96827780 666 if (i >= sizeof tmpbuf /* too long -- assume the worst */
667 || *tmpbuf != '/'
668 || (Stat(tmpbuf, &st) == 0 && (st.st_mode & 2)) ) {
8990e307 669 MgTAINTEDDIR_on(mg);
1e422769 670 return 0;
671 }
463ee0b2 672 }
79072805 673 }
674 }
3e3baf6d 675#endif /* neither OS2 nor AMIGAOS nor WIN32 */
1e422769 676
79072805 677 return 0;
678}
679
680int
85e6fe83 681magic_clearenv(sv,mg)
682SV* sv;
683MAGIC* mg;
684{
5aabfad6 685 my_setenv(MgPV(mg,na),Nullch);
85e6fe83 686 return 0;
687}
688
88e89b8a 689int
fb73857a 690magic_set_all_env(sv,mg)
691SV* sv;
692MAGIC* mg;
693{
694#if defined(VMS)
695 die("Can't make list assignment to %%ENV on this system");
696#else
d58bf5aa 697 dTHR;
fb73857a 698 if (localizing) {
699 HE* entry;
700 magic_clear_all_env(sv,mg);
701 hv_iterinit((HV*)sv);
702 while (entry = hv_iternext((HV*)sv)) {
703 I32 keylen;
704 my_setenv(hv_iterkey(entry, &keylen),
705 SvPV(hv_iterval((HV*)sv, entry), na));
706 }
707 }
708#endif
709 return 0;
710}
711
712int
3e3baf6d 713magic_clear_all_env(sv,mg)
714SV* sv;
715MAGIC* mg;
66b1d557 716{
3e3baf6d 717#if defined(VMS)
718 die("Can't make list assignment to %%ENV on this system");
719#else
720#ifdef WIN32
721 char *envv = GetEnvironmentStrings();
722 char *cur = envv;
723 STRLEN len;
724 while (*cur) {
725 char *end = strchr(cur,'=');
726 if (end && end != cur) {
727 *end = '\0';
728 my_setenv(cur,Nullch);
729 *end = '=';
730 cur += strlen(end+1)+1;
731 }
732 else if ((len = strlen(cur)))
733 cur += len+1;
734 }
735 FreeEnvironmentStrings(envv);
66b1d557 736#else
737 I32 i;
738
739 if (environ == origenviron)
740 New(901, environ, 1, char*);
741 else
742 for (i = 0; environ[i]; i++)
743 Safefree(environ[i]);
744 environ[0] = Nullch;
745
66b1d557 746#endif
3e3baf6d 747#endif
748 return 0;
66b1d557 749}
750
751int
88e89b8a 752magic_getsig(sv,mg)
753SV* sv;
754MAGIC* mg;
755{
756 I32 i;
757 /* Are we fetching a signal entry? */
5aabfad6 758 i = whichsig(MgPV(mg,na));
88e89b8a 759 if (i) {
760 if(psig_ptr[i])
761 sv_setsv(sv,psig_ptr[i]);
762 else {
ff68c719 763 Sighandler_t sigstate = rsignal_state(i);
764
88e89b8a 765 /* cache state so we don't fetch it again */
ff68c719 766 if(sigstate == SIG_IGN)
88e89b8a 767 sv_setpv(sv,"IGNORE");
768 else
769 sv_setsv(sv,&sv_undef);
770 psig_ptr[i] = SvREFCNT_inc(sv);
771 SvTEMP_off(sv);
772 }
773 }
774 return 0;
775}
776int
777magic_clearsig(sv,mg)
778SV* sv;
779MAGIC* mg;
780{
781 I32 i;
782 /* Are we clearing a signal entry? */
5aabfad6 783 i = whichsig(MgPV(mg,na));
88e89b8a 784 if (i) {
785 if(psig_ptr[i]) {
786 SvREFCNT_dec(psig_ptr[i]);
787 psig_ptr[i]=0;
788 }
789 if(psig_name[i]) {
790 SvREFCNT_dec(psig_name[i]);
791 psig_name[i]=0;
792 }
793 }
794 return 0;
795}
3d37d572 796
85e6fe83 797int
79072805 798magic_setsig(sv,mg)
799SV* sv;
800MAGIC* mg;
801{
11343788 802 dTHR;
79072805 803 register char *s;
804 I32 i;
748a9306 805 SV** svp;
a0d0e21e 806
5aabfad6 807 s = MgPV(mg,na);
748a9306 808 if (*s == '_') {
809 if (strEQ(s,"__DIE__"))
810 svp = &diehook;
811 else if (strEQ(s,"__WARN__"))
812 svp = &warnhook;
813 else if (strEQ(s,"__PARSE__"))
814 svp = &parsehook;
815 else
816 croak("No such hook: %s", s);
817 i = 0;
4633a7c4 818 if (*svp) {
819 SvREFCNT_dec(*svp);
820 *svp = 0;
821 }
748a9306 822 }
823 else {
824 i = whichsig(s); /* ...no, a brick */
825 if (!i) {
826 if (dowarn || strEQ(s,"ALARM"))
827 warn("No such signal: SIG%s", s);
828 return 0;
829 }
ff0cee69 830 SvREFCNT_dec(psig_name[i]);
831 SvREFCNT_dec(psig_ptr[i]);
88e89b8a 832 psig_ptr[i] = SvREFCNT_inc(sv);
88e89b8a 833 SvTEMP_off(sv); /* Make sure it doesn't go away on us */
ff0cee69 834 psig_name[i] = newSVpv(s, strlen(s));
88e89b8a 835 SvREADONLY_on(psig_name[i]);
748a9306 836 }
a0d0e21e 837 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
748a9306 838 if (i)
c23142e2 839 (void)rsignal(i, sighandlerp);
748a9306 840 else
841 *svp = SvREFCNT_inc(sv);
a0d0e21e 842 return 0;
843 }
844 s = SvPV_force(sv,na);
748a9306 845 if (strEQ(s,"IGNORE")) {
846 if (i)
ff68c719 847 (void)rsignal(i, SIG_IGN);
748a9306 848 else
849 *svp = 0;
850 }
851 else if (strEQ(s,"DEFAULT") || !*s) {
852 if (i)
ff68c719 853 (void)rsignal(i, SIG_DFL);
748a9306 854 else
855 *svp = 0;
856 }
79072805 857 else {
5aabfad6 858 /*
859 * We should warn if HINT_STRICT_REFS, but without
860 * access to a known hint bit in a known OP, we can't
861 * tell whether HINT_STRICT_REFS is in force or not.
862 */
46fc3d4c 863 if (!strchr(s,':') && !strchr(s,'\''))
864 sv_setpv(sv, form("main::%s", s));
748a9306 865 if (i)
c23142e2 866 (void)rsignal(i, sighandlerp);
748a9306 867 else
868 *svp = SvREFCNT_inc(sv);
79072805 869 }
870 return 0;
871}
872
873int
463ee0b2 874magic_setisa(sv,mg)
79072805 875SV* sv;
876MAGIC* mg;
877{
463ee0b2 878 sub_generation++;
879 return 0;
880}
881
a0d0e21e 882#ifdef OVERLOAD
883
463ee0b2 884int
a0d0e21e 885magic_setamagic(sv,mg)
463ee0b2 886SV* sv;
887MAGIC* mg;
888{
a0d0e21e 889 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
890 amagic_generation++;
463ee0b2 891
a0d0e21e 892 return 0;
893}
894#endif /* OVERLOAD */
463ee0b2 895
946ec16e 896int
897magic_setnkeys(sv,mg)
898SV* sv;
899MAGIC* mg;
900{
901 if (LvTARG(sv)) {
902 hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
903 LvTARG(sv) = Nullsv; /* Don't allow a ref to reassign this. */
904 }
905 return 0;
906}
907
a0d0e21e 908static int
909magic_methpack(sv,mg,meth)
910SV* sv;
911MAGIC* mg;
912char *meth;
913{
11343788 914 dTHR;
a0d0e21e 915 dSP;
463ee0b2 916
a0d0e21e 917 ENTER;
918 SAVETMPS;
919 PUSHMARK(sp);
920 EXTEND(sp, 2);
921 PUSHs(mg->mg_obj);
88e89b8a 922 if (mg->mg_ptr) {
923 if (mg->mg_len >= 0)
924 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
925 else if (mg->mg_len == HEf_SVKEY)
926 PUSHs((SV*)mg->mg_ptr);
927 }
a0d0e21e 928 else if (mg->mg_type == 'p')
929 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2 930 PUTBACK;
931
a0d0e21e 932 if (perl_call_method(meth, G_SCALAR))
933 sv_setsv(sv, *stack_sp--);
463ee0b2 934
a0d0e21e 935 FREETMPS;
936 LEAVE;
937 return 0;
938}
463ee0b2 939
a0d0e21e 940int
941magic_getpack(sv,mg)
942SV* sv;
943MAGIC* mg;
944{
945 magic_methpack(sv,mg,"FETCH");
946 if (mg->mg_ptr)
947 mg->mg_flags |= MGf_GSKIP;
463ee0b2 948 return 0;
949}
950
951int
952magic_setpack(sv,mg)
953SV* sv;
954MAGIC* mg;
955{
11343788 956 dTHR;
463ee0b2 957 dSP;
463ee0b2 958
a0d0e21e 959 PUSHMARK(sp);
960 EXTEND(sp, 3);
961 PUSHs(mg->mg_obj);
88e89b8a 962 if (mg->mg_ptr) {
963 if (mg->mg_len >= 0)
964 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
965 else if (mg->mg_len == HEf_SVKEY)
966 PUSHs((SV*)mg->mg_ptr);
967 }
a0d0e21e 968 else if (mg->mg_type == 'p')
969 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2 970 PUSHs(sv);
971 PUTBACK;
972
a0d0e21e 973 perl_call_method("STORE", G_SCALAR|G_DISCARD);
463ee0b2 974
975 return 0;
976}
977
978int
979magic_clearpack(sv,mg)
980SV* sv;
981MAGIC* mg;
982{
a0d0e21e 983 return magic_methpack(sv,mg,"DELETE");
984}
463ee0b2 985
a0d0e21e 986int magic_wipepack(sv,mg)
987SV* sv;
988MAGIC* mg;
989{
11343788 990 dTHR;
a0d0e21e 991 dSP;
463ee0b2 992
a0d0e21e 993 PUSHMARK(sp);
994 XPUSHs(mg->mg_obj);
463ee0b2 995 PUTBACK;
463ee0b2 996
a0d0e21e 997 perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
463ee0b2 998
999 return 0;
1000}
1001
1002int
1003magic_nextpack(sv,mg,key)
1004SV* sv;
1005MAGIC* mg;
1006SV* key;
1007{
11343788 1008 dTHR;
463ee0b2 1009 dSP;
a0d0e21e 1010 char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2 1011
1012 ENTER;
a0d0e21e 1013 SAVETMPS;
1014 PUSHMARK(sp);
1015 EXTEND(sp, 2);
1016 PUSHs(mg->mg_obj);
463ee0b2 1017 if (SvOK(key))
1018 PUSHs(key);
1019 PUTBACK;
1020
a0d0e21e 1021 if (perl_call_method(meth, G_SCALAR))
1022 sv_setsv(key, *stack_sp--);
463ee0b2 1023
a0d0e21e 1024 FREETMPS;
1025 LEAVE;
79072805 1026 return 0;
1027}
1028
1029int
a0d0e21e 1030magic_existspack(sv,mg)
1031SV* sv;
1032MAGIC* mg;
1033{
1034 return magic_methpack(sv,mg,"EXISTS");
1035}
1036
1037int
79072805 1038magic_setdbline(sv,mg)
1039SV* sv;
1040MAGIC* mg;
1041{
11343788 1042 dTHR;
79072805 1043 OP *o;
1044 I32 i;
1045 GV* gv;
1046 SV** svp;
1047
1048 gv = DBline;
1049 i = SvTRUE(sv);
188ea221 1050 svp = av_fetch(GvAV(gv),
5aabfad6 1051 atoi(MgPV(mg,na)), FALSE);
8990e307 1052 if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
93a17b20 1053 o->op_private = i;
79072805 1054 else
1055 warn("Can't break at that line\n");
1056 return 0;
1057}
1058
1059int
1060magic_getarylen(sv,mg)
1061SV* sv;
1062MAGIC* mg;
1063{
0f15f207 1064 dTHR;
a0d0e21e 1065 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
79072805 1066 return 0;
1067}
1068
1069int
1070magic_setarylen(sv,mg)
1071SV* sv;
1072MAGIC* mg;
1073{
0f15f207 1074 dTHR;
a0d0e21e 1075 av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
1076 return 0;
1077}
1078
1079int
1080magic_getpos(sv,mg)
1081SV* sv;
1082MAGIC* mg;
1083{
1084 SV* lsv = LvTARG(sv);
1085
1086 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
1087 mg = mg_find(lsv, 'g');
1088 if (mg && mg->mg_len >= 0) {
0f15f207 1089 dTHR;
a0d0e21e 1090 sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
1091 return 0;
1092 }
1093 }
1094 (void)SvOK_off(sv);
1095 return 0;
1096}
1097
1098int
1099magic_setpos(sv,mg)
1100SV* sv;
1101MAGIC* mg;
1102{
1103 SV* lsv = LvTARG(sv);
1104 SSize_t pos;
1105 STRLEN len;
1106
1107 mg = 0;
1108
1109 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
1110 mg = mg_find(lsv, 'g');
1111 if (!mg) {
1112 if (!SvOK(sv))
1113 return 0;
1114 sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
1115 mg = mg_find(lsv, 'g');
1116 }
1117 else if (!SvOK(sv)) {
1118 mg->mg_len = -1;
1119 return 0;
1120 }
1121 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1122
0f15f207 1123 WITH_THR(pos = SvIV(sv) - curcop->cop_arybase);
a0d0e21e 1124 if (pos < 0) {
1125 pos += len;
1126 if (pos < 0)
1127 pos = 0;
1128 }
1129 else if (pos > len)
1130 pos = len;
1131 mg->mg_len = pos;
71be2cbc 1132 mg->mg_flags &= ~MGf_MINMATCH;
a0d0e21e 1133
79072805 1134 return 0;
1135}
1136
1137int
1138magic_getglob(sv,mg)
1139SV* sv;
1140MAGIC* mg;
1141{
8646b087 1142 if (SvFAKE(sv)) { /* FAKE globs can get coerced */
1143 SvFAKE_off(sv);
946ec16e 1144 gv_efullname3(sv,((GV*)sv), "*");
8646b087 1145 SvFAKE_on(sv);
1146 }
1147 else
946ec16e 1148 gv_efullname3(sv,((GV*)sv), "*"); /* a gv value, be nice */
79072805 1149 return 0;
1150}
1151
1152int
1153magic_setglob(sv,mg)
1154SV* sv;
1155MAGIC* mg;
1156{
1157 register char *s;
1158 GV* gv;
1159
1160 if (!SvOK(sv))
1161 return 0;
463ee0b2 1162 s = SvPV(sv, na);
79072805 1163 if (*s == '*' && s[1])
1164 s++;
85e6fe83 1165 gv = gv_fetchpv(s,TRUE, SVt_PVGV);
79072805 1166 if (sv == (SV*)gv)
1167 return 0;
1168 if (GvGP(sv))
88e89b8a 1169 gp_free((GV*)sv);
79072805 1170 GvGP(sv) = gp_ref(GvGP(gv));
79072805 1171 return 0;
1172}
1173
1174int
1175magic_setsubstr(sv,mg)
1176SV* sv;
1177MAGIC* mg;
1178{
8990e307 1179 STRLEN len;
1180 char *tmps = SvPV(sv,len);
1181 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
79072805 1182 return 0;
1183}
1184
1185int
463ee0b2 1186magic_gettaint(sv,mg)
1187SV* sv;
1188MAGIC* mg;
1189{
a863c7d1 1190 dTHR;
bbce6d69 1191 TAINT_IF((mg->mg_len & 1) ||
1192 (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */
463ee0b2 1193 return 0;
1194}
1195
1196int
1197magic_settaint(sv,mg)
1198SV* sv;
1199MAGIC* mg;
1200{
11343788 1201 dTHR;
748a9306 1202 if (localizing) {
1203 if (localizing == 1)
1204 mg->mg_len <<= 1;
1205 else
1206 mg->mg_len >>= 1;
a0d0e21e 1207 }
748a9306 1208 else if (tainted)
1209 mg->mg_len |= 1;
1210 else
1211 mg->mg_len &= ~1;
463ee0b2 1212 return 0;
1213}
1214
1215int
79072805 1216magic_setvec(sv,mg)
1217SV* sv;
1218MAGIC* mg;
1219{
1220 do_vecset(sv); /* XXX slurp this routine */
1221 return 0;
1222}
1223
1224int
68dc0745 1225magic_getdefelem(sv,mg)
5f05dabc 1226SV* sv;
1227MAGIC* mg;
1228{
71be2cbc 1229 SV *targ = Nullsv;
5f05dabc 1230 if (LvTARGLEN(sv)) {
68dc0745 1231 if (mg->mg_obj) {
1232 HV* hv = (HV*)LvTARG(sv);
1233 HE* he = hv_fetch_ent(hv, mg->mg_obj, FALSE, 0);
1234 if (he)
1235 targ = HeVAL(he);
1236 }
1237 else {
1238 AV* av = (AV*)LvTARG(sv);
1239 if ((I32)LvTARGOFF(sv) <= AvFILL(av))
1240 targ = AvARRAY(av)[LvTARGOFF(sv)];
1241 }
1242 if (targ && targ != &sv_undef) {
e858de61 1243 dTHR; /* just for SvREFCNT_dec */
68dc0745 1244 /* somebody else defined it for us */
1245 SvREFCNT_dec(LvTARG(sv));
1246 LvTARG(sv) = SvREFCNT_inc(targ);
1247 LvTARGLEN(sv) = 0;
1248 SvREFCNT_dec(mg->mg_obj);
1249 mg->mg_obj = Nullsv;
1250 mg->mg_flags &= ~MGf_REFCOUNTED;
1251 }
5f05dabc 1252 }
71be2cbc 1253 else
1254 targ = LvTARG(sv);
1255 sv_setsv(sv, targ ? targ : &sv_undef);
1256 return 0;
1257}
1258
1259int
68dc0745 1260magic_setdefelem(sv,mg)
71be2cbc 1261SV* sv;
1262MAGIC* mg;
1263{
1264 if (LvTARGLEN(sv))
68dc0745 1265 vivify_defelem(sv);
1266 if (LvTARG(sv)) {
5f05dabc 1267 sv_setsv(LvTARG(sv), sv);
68dc0745 1268 SvSETMAGIC(LvTARG(sv));
1269 }
5f05dabc 1270 return 0;
1271}
1272
1273int
68dc0745 1274magic_freedefelem(sv,mg)
5f05dabc 1275SV* sv;
1276MAGIC* mg;
1277{
1278 SvREFCNT_dec(LvTARG(sv));
71be2cbc 1279 return 0;
1280}
1281
1282void
68dc0745 1283vivify_defelem(sv)
71be2cbc 1284SV* sv;
1285{
e858de61 1286 dTHR; /* just for SvREFCNT_inc and SvREFCNT_dec*/
68dc0745 1287 MAGIC* mg;
1288 SV* value;
71be2cbc 1289
68dc0745 1290 if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y')))
71be2cbc 1291 return;
68dc0745 1292 if (mg->mg_obj) {
1293 HV* hv = (HV*)LvTARG(sv);
1294 HE* he = hv_fetch_ent(hv, mg->mg_obj, TRUE, 0);
1295 if (!he || (value = HeVAL(he)) == &sv_undef)
1296 croak(no_helem, SvPV(mg->mg_obj, na));
71be2cbc 1297 }
68dc0745 1298 else {
1299 AV* av = (AV*)LvTARG(sv);
5aabfad6 1300 if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av))
68dc0745 1301 LvTARG(sv) = Nullsv; /* array can't be extended */
1302 else {
1303 SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE);
1304 if (!svp || (value = *svp) == &sv_undef)
1305 croak(no_aelem, (I32)LvTARGOFF(sv));
1306 }
1307 }
3e3baf6d 1308 (void)SvREFCNT_inc(value);
68dc0745 1309 SvREFCNT_dec(LvTARG(sv));
1310 LvTARG(sv) = value;
71be2cbc 1311 LvTARGLEN(sv) = 0;
68dc0745 1312 SvREFCNT_dec(mg->mg_obj);
1313 mg->mg_obj = Nullsv;
1314 mg->mg_flags &= ~MGf_REFCOUNTED;
5f05dabc 1315}
1316
1317int
93a17b20 1318magic_setmglob(sv,mg)
1319SV* sv;
1320MAGIC* mg;
1321{
a0d0e21e 1322 mg->mg_len = -1;
c6496cc7 1323 SvSCREAM_off(sv);
93a17b20 1324 return 0;
1325}
1326
1327int
79072805 1328magic_setbm(sv,mg)
1329SV* sv;
1330MAGIC* mg;
1331{
463ee0b2 1332 sv_unmagic(sv, 'B');
79072805 1333 SvVALID_off(sv);
1334 return 0;
1335}
1336
1337int
55497cff 1338magic_setfm(sv,mg)
1339SV* sv;
1340MAGIC* mg;
1341{
1342 sv_unmagic(sv, 'f');
1343 SvCOMPILED_off(sv);
1344 return 0;
1345}
1346
1347int
79072805 1348magic_setuvar(sv,mg)
1349SV* sv;
1350MAGIC* mg;
1351{
1352 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1353
1354 if (uf && uf->uf_set)
1355 (*uf->uf_set)(uf->uf_index, sv);
1356 return 0;
1357}
1358
7a4c00b4 1359#ifdef USE_LOCALE_COLLATE
79072805 1360int
bbce6d69 1361magic_setcollxfrm(sv,mg)
1362SV* sv;
1363MAGIC* mg;
1364{
1365 /*
1366 * René Descartes said "I think not."
1367 * and vanished with a faint plop.
1368 */
7a4c00b4 1369 if (mg->mg_ptr) {
1370 Safefree(mg->mg_ptr);
1371 mg->mg_ptr = NULL;
1372 mg->mg_len = -1;
1373 }
bbce6d69 1374 return 0;
1375}
7a4c00b4 1376#endif /* USE_LOCALE_COLLATE */
bbce6d69 1377
1378int
79072805 1379magic_set(sv,mg)
1380SV* sv;
1381MAGIC* mg;
1382{
11343788 1383 dTHR;
79072805 1384 register char *s;
1385 I32 i;
8990e307 1386 STRLEN len;
79072805 1387 switch (*mg->mg_ptr) {
748a9306 1388 case '\001': /* ^A */
1389 sv_setsv(bodytarget, sv);
1390 break;
79072805 1391 case '\004': /* ^D */
8990e307 1392 debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
79072805 1393 DEBUG_x(dump_all());
1394 break;
28f23441 1395 case '\005': /* ^E */
1396#ifdef VMS
1397 set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1398#else
f86702cc 1399 /* will anyone ever use this? */
1400 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
28f23441 1401#endif
1402 break;
79072805 1403 case '\006': /* ^F */
463ee0b2 1404 maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1405 break;
a0d0e21e 1406 case '\010': /* ^H */
1407 hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1408 break;
79072805 1409 case '\t': /* ^I */
1410 if (inplace)
1411 Safefree(inplace);
1412 if (SvOK(sv))
a0d0e21e 1413 inplace = savepv(SvPV(sv,na));
79072805 1414 else
1415 inplace = Nullch;
1416 break;
28f23441 1417 case '\017': /* ^O */
1418 if (osname)
1419 Safefree(osname);
1420 if (SvOK(sv))
1421 osname = savepv(SvPV(sv,na));
1422 else
1423 osname = Nullch;
1424 break;
79072805 1425 case '\020': /* ^P */
84902520 1426 perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1427 break;
1428 case '\024': /* ^T */
88e89b8a 1429#ifdef BIG_TIME
1430 basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1431#else
85e6fe83 1432 basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
88e89b8a 1433#endif
79072805 1434 break;
1435 case '\027': /* ^W */
463ee0b2 1436 dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1437 break;
1438 case '.':
748a9306 1439 if (localizing) {
1440 if (localizing == 1)
1441 save_sptr((SV**)&last_in_gv);
1442 }
88e89b8a 1443 else if (SvOK(sv) && GvIO(last_in_gv))
a0d0e21e 1444 IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
79072805 1445 break;
1446 case '^':
a0d0e21e 1447 Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1448 IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1449 IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805 1450 break;
1451 case '~':
a0d0e21e 1452 Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1453 IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1454 IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805 1455 break;
1456 case '=':
a0d0e21e 1457 IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1458 break;
1459 case '-':
a0d0e21e 1460 IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1461 if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1462 IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
79072805 1463 break;
1464 case '%':
a0d0e21e 1465 IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1466 break;
1467 case '|':
4b65379b 1468 {
1469 IO *io = GvIOp(defoutgv);
1470 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0)
1471 IoFLAGS(io) &= ~IOf_FLUSH;
1472 else {
1473 if (!(IoFLAGS(io) & IOf_FLUSH)) {
1474 PerlIO *ofp = IoOFP(io);
1475 if (ofp)
1476 (void)PerlIO_flush(ofp);
1477 IoFLAGS(io) |= IOf_FLUSH;
1478 }
1479 }
79072805 1480 }
1481 break;
1482 case '*':
463ee0b2 1483 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1484 multiline = (i != 0);
1485 break;
1486 case '/':
c07a80fd 1487 SvREFCNT_dec(nrs);
1488 nrs = newSVsv(sv);
1489 SvREFCNT_dec(rs);
1490 rs = SvREFCNT_inc(nrs);
79072805 1491 break;
1492 case '\\':
1493 if (ors)
1494 Safefree(ors);
e3c19b7b 1495 if (SvOK(sv) || SvGMAGICAL(sv))
1496 ors = savepv(SvPV(sv,orslen));
1497 else {
1498 ors = Nullch;
1499 orslen = 0;
1500 }
79072805 1501 break;
1502 case ',':
1503 if (ofs)
1504 Safefree(ofs);
a0d0e21e 1505 ofs = savepv(SvPV(sv, ofslen));
79072805 1506 break;
1507 case '#':
1508 if (ofmt)
1509 Safefree(ofmt);
a0d0e21e 1510 ofmt = savepv(SvPV(sv,na));
79072805 1511 break;
1512 case '[':
a0d0e21e 1513 compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1514 break;
1515 case '?':
ff0cee69 1516#ifdef COMPLEX_STATUS
1517 if (localizing == 2) {
1518 statusvalue = LvTARGOFF(sv);
1519 statusvalue_vms = LvTARGLEN(sv);
1520 }
1521 else
1522#endif
1523#ifdef VMSISH_STATUS
1524 if (VMSISH_STATUS)
1525 STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
1526 else
1527#endif
1528 STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1529 break;
1530 case '!':
f86702cc 1531 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),
1532 (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
79072805 1533 break;
1534 case '<':
463ee0b2 1535 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1536 if (delaymagic) {
1537 delaymagic |= DM_RUID;
1538 break; /* don't do magic till later */
1539 }
1540#ifdef HAS_SETRUID
85e6fe83 1541 (void)setruid((Uid_t)uid);
79072805 1542#else
1543#ifdef HAS_SETREUID
85e6fe83 1544 (void)setreuid((Uid_t)uid, (Uid_t)-1);
748a9306 1545#else
85e6fe83 1546#ifdef HAS_SETRESUID
1547 (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
79072805 1548#else
1549 if (uid == euid) /* special case $< = $> */
1550 (void)setuid(uid);
a0d0e21e 1551 else {
1552 uid = (I32)getuid();
463ee0b2 1553 croak("setruid() not implemented");
a0d0e21e 1554 }
79072805 1555#endif
1556#endif
85e6fe83 1557#endif
748a9306 1558 uid = (I32)getuid();
4633a7c4 1559 tainting |= (uid && (euid != uid || egid != gid));
79072805 1560 break;
1561 case '>':
463ee0b2 1562 euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1563 if (delaymagic) {
1564 delaymagic |= DM_EUID;
1565 break; /* don't do magic till later */
1566 }
1567#ifdef HAS_SETEUID
85e6fe83 1568 (void)seteuid((Uid_t)euid);
79072805 1569#else
1570#ifdef HAS_SETREUID
85e6fe83 1571 (void)setreuid((Uid_t)-1, (Uid_t)euid);
1572#else
1573#ifdef HAS_SETRESUID
1574 (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
79072805 1575#else
1576 if (euid == uid) /* special case $> = $< */
1577 setuid(euid);
a0d0e21e 1578 else {
1579 euid = (I32)geteuid();
463ee0b2 1580 croak("seteuid() not implemented");
a0d0e21e 1581 }
79072805 1582#endif
1583#endif
85e6fe83 1584#endif
79072805 1585 euid = (I32)geteuid();
4633a7c4 1586 tainting |= (uid && (euid != uid || egid != gid));
79072805 1587 break;
1588 case '(':
463ee0b2 1589 gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1590 if (delaymagic) {
1591 delaymagic |= DM_RGID;
1592 break; /* don't do magic till later */
1593 }
1594#ifdef HAS_SETRGID
85e6fe83 1595 (void)setrgid((Gid_t)gid);
79072805 1596#else
1597#ifdef HAS_SETREGID
85e6fe83 1598 (void)setregid((Gid_t)gid, (Gid_t)-1);
1599#else
1600#ifdef HAS_SETRESGID
1601 (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
79072805 1602#else
1603 if (gid == egid) /* special case $( = $) */
1604 (void)setgid(gid);
748a9306 1605 else {
1606 gid = (I32)getgid();
463ee0b2 1607 croak("setrgid() not implemented");
748a9306 1608 }
79072805 1609#endif
1610#endif
85e6fe83 1611#endif
79072805 1612 gid = (I32)getgid();
4633a7c4 1613 tainting |= (uid && (euid != uid || egid != gid));
79072805 1614 break;
1615 case ')':
5cd24f17 1616#ifdef HAS_SETGROUPS
1617 {
1618 char *p = SvPV(sv, na);
1619 Groups_t gary[NGROUPS];
1620
1621 SET_NUMERIC_STANDARD();
1622 while (isSPACE(*p))
1623 ++p;
1624 egid = I_V(atof(p));
1625 for (i = 0; i < NGROUPS; ++i) {
1626 while (*p && !isSPACE(*p))
1627 ++p;
1628 while (isSPACE(*p))
1629 ++p;
1630 if (!*p)
1631 break;
1632 gary[i] = I_V(atof(p));
1633 }
8cc95fdb 1634 if (i)
1635 (void)setgroups(i, gary);
5cd24f17 1636 }
1637#else /* HAS_SETGROUPS */
463ee0b2 1638 egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
5cd24f17 1639#endif /* HAS_SETGROUPS */
79072805 1640 if (delaymagic) {
1641 delaymagic |= DM_EGID;
1642 break; /* don't do magic till later */
1643 }
1644#ifdef HAS_SETEGID
85e6fe83 1645 (void)setegid((Gid_t)egid);
79072805 1646#else
1647#ifdef HAS_SETREGID
85e6fe83 1648 (void)setregid((Gid_t)-1, (Gid_t)egid);
1649#else
1650#ifdef HAS_SETRESGID
1651 (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
79072805 1652#else
1653 if (egid == gid) /* special case $) = $( */
1654 (void)setgid(egid);
748a9306 1655 else {
1656 egid = (I32)getegid();
463ee0b2 1657 croak("setegid() not implemented");
748a9306 1658 }
79072805 1659#endif
1660#endif
85e6fe83 1661#endif
79072805 1662 egid = (I32)getegid();
4633a7c4 1663 tainting |= (uid && (euid != uid || egid != gid));
79072805 1664 break;
1665 case ':':
a0d0e21e 1666 chopset = SvPV_force(sv,na);
79072805 1667 break;
1668 case '0':
1669 if (!origalen) {
1670 s = origargv[0];
1671 s += strlen(s);
1672 /* See if all the arguments are contiguous in memory */
1673 for (i = 1; i < origargc; i++) {
fb73857a 1674 if (origargv[i] == s + 1
1675#ifdef OS2
1676 || origargv[i] == s + 2
1677#endif
1678 )
79072805 1679 s += strlen(++s); /* this one is ok too */
fb73857a 1680 else
1681 break;
79072805 1682 }
bbce6d69 1683 /* can grab env area too? */
fb73857a 1684 if (origenviron && (origenviron[0] == s + 1
1685#ifdef OS2
1686 || (origenviron[0] == s + 9 && (s += 8))
1687#endif
1688 )) {
66b1d557 1689 my_setenv("NoNe SuCh", Nullch);
79072805 1690 /* force copy of environment */
1691 for (i = 0; origenviron[i]; i++)
1692 if (origenviron[i] == s + 1)
1693 s += strlen(++s);
fb73857a 1694 else
1695 break;
79072805 1696 }
1697 origalen = s - origargv[0];
1698 }
a0d0e21e 1699 s = SvPV_force(sv,len);
8990e307 1700 i = len;
79072805 1701 if (i >= origalen) {
1702 i = origalen;
fb73857a 1703 /* don't allow system to limit $0 seen by script */
1704 /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */
79072805 1705 Copy(s, origargv[0], i, char);
fb73857a 1706 s = origargv[0]+i;
1707 *s = '\0';
79072805 1708 }
1709 else {
1710 Copy(s, origargv[0], i, char);
1711 s = origargv[0]+i;
1712 *s++ = '\0';
1713 while (++i < origalen)
8990e307 1714 *s++ = ' ';
1715 s = origargv[0]+i;
ed6116ce 1716 for (i = 1; i < origargc; i++)
8990e307 1717 origargv[i] = Nullch;
79072805 1718 }
1719 break;
a863c7d1 1720#ifdef USE_THREADS
1721 case '@':
1722 sv_setsv(errsv, sv);
1723 break;
1724#endif /* USE_THREADS */
79072805 1725 }
1726 return 0;
1727}
1728
f93b4edd 1729#ifdef USE_THREADS
1730int
1731magic_mutexfree(sv, mg)
1732SV *sv;
1733MAGIC *mg;
1734{
1735 dTHR;
bc1f4c86 1736 DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: magic_mutexfree 0x%lx\n",
1737 (unsigned long)thr, (unsigned long)sv);)
f93b4edd 1738 if (MgOWNER(mg))
1739 croak("panic: magic_mutexfree");
1740 MUTEX_DESTROY(MgMUTEXP(mg));
1741 COND_DESTROY(MgCONDP(mg));
e55aaa0e 1742 SvREFCNT_dec(sv);
f93b4edd 1743 return 0;
1744}
1745#endif /* USE_THREADS */
1746
79072805 1747I32
1748whichsig(sig)
1749char *sig;
1750{
1751 register char **sigv;
1752
1753 for (sigv = sig_name+1; *sigv; sigv++)
1754 if (strEQ(sig,*sigv))
8e07c86e 1755 return sig_num[sigv - sig_name];
79072805 1756#ifdef SIGCLD
1757 if (strEQ(sig,"CHLD"))
1758 return SIGCLD;
1759#endif
1760#ifdef SIGCHLD
1761 if (strEQ(sig,"CLD"))
1762 return SIGCHLD;
1763#endif
1764 return 0;
1765}
1766
84902520 1767static SV* sig_sv;
1768
1769static void
1770unwind_handler_stack(p)
1771 void *p;
1772{
ff26ac79 1773 dTHR;
84902520 1774 U32 flags = *(U32*)p;
1775
1776 if (flags & 1)
1777 savestack_ix -= 5; /* Unprotect save in progress. */
1778 /* cxstack_ix-- Not needed, die already unwound it. */
1779 if (flags & 64)
1780 SvREFCNT_dec(sig_sv);
1781}
1782
ecfc5424 1783Signal_t
79072805 1784sighandler(sig)
a0d0e21e 1785int sig;
79072805 1786{
11343788 1787 dTHR;
79072805 1788 dSP;
1789 GV *gv;
a0d0e21e 1790 HV *st;
84902520 1791 SV *sv, *tSv = Sv;
79072805 1792 CV *cv;
79072805 1793 AV *oldstack;
84902520 1794 OP *myop = op;
1795 U32 flags = 0;
1796 I32 o_save_i = savestack_ix, type;
1797 CONTEXT *cx;
1798 XPV *tXpv = Xpv;
1799
1800 if (savestack_ix + 15 <= savestack_max)
1801 flags |= 1;
1802 if (cxstack_ix < cxstack_max - 2)
1803 flags |= 2;
1804 if (markstack_ptr < markstack_max - 2)
1805 flags |= 4;
1806 if (retstack_ix < retstack_max - 2)
1807 flags |= 8;
1808 if (scopestack_ix < scopestack_max - 3)
1809 flags |= 16;
1810
1811 if (flags & 2) { /* POPBLOCK may decrease cxstack too early. */
1812 cxstack_ix++; /* Protect from overwrite. */
1813 cx = &cxstack[cxstack_ix];
1814 type = cx->cx_type; /* Can be during partial write. */
1815 cx->cx_type = CXt_NULL; /* Make it safe for unwind. */
1816 }
ff0cee69 1817 if (!psig_ptr[sig])
1818 die("Signal SIG%s received, but no signal handler set.\n",
1819 sig_name[sig]);
1820
84902520 1821 /* Max number of items pushed there is 3*n or 4. We cannot fix
1822 infinity, so we fix 4 (in fact 5): */
1823 if (flags & 1) {
1824 savestack_ix += 5; /* Protect save in progress. */
1825 o_save_i = savestack_ix;
1826 SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags);
1827 }
1828 if (flags & 4)
1829 markstack_ptr++; /* Protect mark. */
1830 if (flags & 8) {
1831 retstack_ix++;
1832 retstack[retstack_ix] = NULL;
1833 }
1834 if (flags & 16)
1835 scopestack_ix += 1;
1836 /* sv_2cv is too complicated, try a simpler variant first: */
1837 if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig]))
1838 || SvTYPE(cv) != SVt_PVCV)
1839 cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
1840
a0d0e21e 1841 if (!cv || !CvROOT(cv)) {
79072805 1842 if (dowarn)
1843 warn("SIG%s handler \"%s\" not defined.\n",
88e89b8a 1844 sig_name[sig], GvENAME(gv) );
79072805 1845 return;
1846 }
1847
88e89b8a 1848 oldstack = curstack;
1849 if (curstack != signalstack)
a0d0e21e 1850 AvFILL(signalstack) = 0;
88e89b8a 1851 SWITCHSTACK(curstack, signalstack);
79072805 1852
84902520 1853 if(psig_name[sig]) {
88e89b8a 1854 sv = SvREFCNT_inc(psig_name[sig]);
84902520 1855 flags |= 64;
1856 sig_sv = sv;
1857 } else {
ff0cee69 1858 sv = sv_newmortal();
1859 sv_setpv(sv,sig_name[sig]);
88e89b8a 1860 }
a0d0e21e 1861 PUSHMARK(sp);
79072805 1862 PUSHs(sv);
79072805 1863 PUTBACK;
a0d0e21e 1864
1865 perl_call_sv((SV*)cv, G_DISCARD);
79072805 1866
1867 SWITCHSTACK(signalstack, oldstack);
84902520 1868 if (flags & 1)
1869 savestack_ix -= 8; /* Unprotect save in progress. */
1870 if (flags & 2) {
1871 cxstack[cxstack_ix].cx_type = type;
1872 cxstack_ix -= 1;
1873 }
1874 if (flags & 4)
1875 markstack_ptr--;
1876 if (flags & 8)
1877 retstack_ix--;
1878 if (flags & 16)
1879 scopestack_ix -= 1;
1880 if (flags & 64)
1881 SvREFCNT_dec(sv);
1882 op = myop; /* Apparently not needed... */
1883
1884 Sv = tSv; /* Restore global temporaries. */
1885 Xpv = tXpv;
79072805 1886 return;
1887}