Support '%i' format and 'h' modifier in s?printf
[p5sagit/p5-mst-13.2.git] / mg.c
CommitLineData
a0d0e21e 1/* mg.c
79072805 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, 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
188ea221 23#ifdef HAS_GETGROUPS
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{
267 register I32 paren;
268 register char *s;
269 register I32 i;
bbce6d69 270 register REGEXP *rx;
748a9306 271 char *t;
93a17b20 272
273 switch (*mg->mg_ptr) {
274 case '1': case '2': case '3': case '4':
275 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 276 if (curpm && (rx = curpm->op_pmregexp)) {
93a17b20 277 paren = atoi(mg->mg_ptr);
278 getparen:
bbce6d69 279 if (paren <= rx->nparens &&
280 (s = rx->startp[paren]) &&
281 (t = rx->endp[paren]))
282 {
748a9306 283 i = t - s;
71be2cbc 284 if (i >= 0)
93a17b20 285 return i;
93a17b20 286 }
93a17b20 287 }
748a9306 288 return 0;
93a17b20 289 break;
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 break;
298 case '`':
bbce6d69 299 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 300 if ((s = rx->subbeg) && rx->startp[0]) {
bbce6d69 301 i = rx->startp[0] - s;
71be2cbc 302 if (i >= 0)
93a17b20 303 return i;
93a17b20 304 }
93a17b20 305 }
748a9306 306 return 0;
93a17b20 307 case '\'':
bbce6d69 308 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 309 if (rx->subend && (s = rx->endp[0])) {
310 i = rx->subend - s;
311 if (i >= 0)
312 return 0;
93a17b20 313 }
93a17b20 314 }
748a9306 315 return 0;
93a17b20 316 case ',':
317 return (STRLEN)ofslen;
318 case '\\':
319 return (STRLEN)orslen;
320 }
321 magic_get(sv,mg);
322 if (!SvPOK(sv) && SvNIOK(sv))
463ee0b2 323 sv_2pv(sv, &na);
93a17b20 324 if (SvPOK(sv))
325 return SvCUR(sv);
326 return 0;
327}
328
79072805 329int
330magic_get(sv, mg)
331SV *sv;
332MAGIC *mg;
333{
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
946ec16e 362 sv_setnv(sv, (double)Perl_rc);
88e89b8a 363 sv_setpv(sv, os2error(Perl_rc));
364#else
946ec16e 365 sv_setnv(sv, (double)errno);
28f23441 366 sv_setpv(sv, errno ? Strerror(errno) : "");
367#endif
88e89b8a 368#endif
946ec16e 369 SvNOK_on(sv); /* what a wonderful hack! */
28f23441 370 break;
79072805 371 case '\006': /* ^F */
188ea221 372 sv_setiv(sv, (IV)maxsysfd);
79072805 373 break;
a0d0e21e 374 case '\010': /* ^H */
188ea221 375 sv_setiv(sv, (IV)hints);
a0d0e21e 376 break;
79072805 377 case '\t': /* ^I */
378 if (inplace)
379 sv_setpv(sv, inplace);
380 else
188ea221 381 sv_setsv(sv, &sv_undef);
79072805 382 break;
28f23441 383 case '\017': /* ^O */
188ea221 384 sv_setpv(sv, osname);
28f23441 385 break;
79072805 386 case '\020': /* ^P */
188ea221 387 sv_setiv(sv, (IV)perldb);
79072805 388 break;
f86702cc 389 case '\023': /* ^S */
390 if (STATUS_NATIVE == -1)
391 sv_setiv(sv, (IV)-1);
392 else
393 sv_setuv(sv, (UV)STATUS_NATIVE);
394 break;
79072805 395 case '\024': /* ^T */
88e89b8a 396#ifdef BIG_TIME
188ea221 397 sv_setnv(sv, basetime);
88e89b8a 398#else
188ea221 399 sv_setiv(sv, (IV)basetime);
88e89b8a 400#endif
79072805 401 break;
402 case '\027': /* ^W */
188ea221 403 sv_setiv(sv, (IV)dowarn);
79072805 404 break;
405 case '1': case '2': case '3': case '4':
406 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 407 if (curpm && (rx = curpm->op_pmregexp)) {
88e89b8a 408 paren = atoi(GvENAME((GV*)mg->mg_obj));
79072805 409 getparen:
bbce6d69 410 if (paren <= rx->nparens &&
411 (s = rx->startp[paren]) &&
412 (t = rx->endp[paren]))
413 {
748a9306 414 i = t - s;
13f57bf8 415 getrx:
748a9306 416 if (i >= 0) {
13f57bf8 417 bool was_tainted;
418 if (tainting) {
419 was_tainted = tainted;
420 tainted = FALSE;
421 }
79072805 422 sv_setpvn(sv,s,i);
13f57bf8 423 if (tainting)
424 tainted = was_tainted || rx->exec_tainted;
748a9306 425 break;
426 }
79072805 427 }
79072805 428 }
748a9306 429 sv_setsv(sv,&sv_undef);
79072805 430 break;
431 case '+':
bbce6d69 432 if (curpm && (rx = curpm->op_pmregexp)) {
433 paren = rx->lastparen;
a0d0e21e 434 if (paren)
435 goto getparen;
79072805 436 }
748a9306 437 sv_setsv(sv,&sv_undef);
79072805 438 break;
439 case '`':
bbce6d69 440 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 441 if ((s = rx->subbeg) && rx->startp[0]) {
bbce6d69 442 i = rx->startp[0] - s;
13f57bf8 443 goto getrx;
79072805 444 }
79072805 445 }
748a9306 446 sv_setsv(sv,&sv_undef);
79072805 447 break;
448 case '\'':
bbce6d69 449 if (curpm && (rx = curpm->op_pmregexp)) {
13f57bf8 450 if (rx->subend && (s = rx->endp[0])) {
451 i = rx->subend - s;
452 goto getrx;
79072805 453 }
79072805 454 }
748a9306 455 sv_setsv(sv,&sv_undef);
79072805 456 break;
457 case '.':
458#ifndef lint
a0d0e21e 459 if (GvIO(last_in_gv)) {
188ea221 460 sv_setiv(sv, (IV)IoLINES(GvIO(last_in_gv)));
79072805 461 }
462#endif
463 break;
464 case '?':
f86702cc 465 if (STATUS_POSIX == -1)
466 sv_setiv(sv, (IV)-1);
467 else
468 sv_setuv(sv, (UV)STATUS_POSIX);
79072805 469 break;
470 case '^':
a0d0e21e 471 s = IoTOP_NAME(GvIOp(defoutgv));
79072805 472 if (s)
473 sv_setpv(sv,s);
474 else {
475 sv_setpv(sv,GvENAME(defoutgv));
476 sv_catpv(sv,"_TOP");
477 }
478 break;
479 case '~':
a0d0e21e 480 s = IoFMT_NAME(GvIOp(defoutgv));
79072805 481 if (!s)
482 s = GvENAME(defoutgv);
483 sv_setpv(sv,s);
484 break;
485#ifndef lint
486 case '=':
188ea221 487 sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(defoutgv)));
79072805 488 break;
489 case '-':
188ea221 490 sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(defoutgv)));
79072805 491 break;
492 case '%':
188ea221 493 sv_setiv(sv, (IV)IoPAGE(GvIOp(defoutgv)));
79072805 494 break;
495#endif
496 case ':':
497 break;
498 case '/':
499 break;
500 case '[':
188ea221 501 sv_setiv(sv, (IV)curcop->cop_arybase);
79072805 502 break;
503 case '|':
188ea221 504 sv_setiv(sv, (IV)(IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
79072805 505 break;
506 case ',':
507 sv_setpvn(sv,ofs,ofslen);
508 break;
509 case '\\':
510 sv_setpvn(sv,ors,orslen);
511 break;
512 case '#':
513 sv_setpv(sv,ofmt);
514 break;
515 case '!':
a5f75d66 516#ifdef VMS
946ec16e 517 sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
88e89b8a 518 sv_setpv(sv, errno ? Strerror(errno) : "");
a5f75d66 519#else
88e89b8a 520 {
521 int saveerrno = errno;
946ec16e 522 sv_setnv(sv, (double)errno);
88e89b8a 523#ifdef OS2
524 if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
525 else
a5f75d66 526#endif
2304df62 527 sv_setpv(sv, errno ? Strerror(errno) : "");
88e89b8a 528 errno = saveerrno;
529 }
530#endif
946ec16e 531 SvNOK_on(sv); /* what a wonderful hack! */
79072805 532 break;
533 case '<':
188ea221 534 sv_setiv(sv, (IV)uid);
79072805 535 break;
536 case '>':
188ea221 537 sv_setiv(sv, (IV)euid);
79072805 538 break;
539 case '(':
188ea221 540 sv_setiv(sv, (IV)gid);
79072805 541 s = buf;
542 (void)sprintf(s,"%d",(int)gid);
543 goto add_groups;
544 case ')':
188ea221 545 sv_setiv(sv, (IV)egid);
79072805 546 s = buf;
547 (void)sprintf(s,"%d",(int)egid);
548 add_groups:
549 while (*s) s++;
550#ifdef HAS_GETGROUPS
79072805 551 {
a0d0e21e 552 Groups_t gary[NGROUPS];
79072805 553
554 i = getgroups(NGROUPS,gary);
555 while (--i >= 0) {
188ea221 556 (void)sprintf(s," %d", (int)gary[i]);
79072805 557 while (*s) s++;
558 }
559 }
560#endif
561 sv_setpv(sv,buf);
29355cf7 562 SvIOK_on(sv); /* what a wonderful hack! */
79072805 563 break;
564 case '*':
565 break;
566 case '0':
567 break;
568 }
a0d0e21e 569 return 0;
79072805 570}
571
572int
573magic_getuvar(sv, mg)
574SV *sv;
575MAGIC *mg;
576{
577 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
578
579 if (uf && uf->uf_val)
580 (*uf->uf_val)(uf->uf_index, sv);
581 return 0;
582}
583
584int
585magic_setenv(sv,mg)
586SV* sv;
587MAGIC* mg;
588{
589 register char *s;
88e89b8a 590 char *ptr;
a0d0e21e 591 STRLEN len;
592 I32 i;
593 s = SvPV(sv,len);
188ea221 594 ptr = MgPV(mg);
88e89b8a 595 my_setenv(ptr, s);
a0d0e21e 596#ifdef DYNAMIC_ENV_FETCH
597 /* We just undefd an environment var. Is a replacement */
598 /* waiting in the wings? */
599 if (!len) {
88e89b8a 600 HE *envhe;
188ea221 601 SV *keysv;
602 if (mg->mg_len == HEf_SVKEY) keysv = (SV *)mg->mg_ptr;
603 else keysv = newSVpv(mg->mg_ptr,mg->mg_len);
604 if (envhe = hv_fetch_ent(GvHVn(envgv),keysv,FALSE,0))
88e89b8a 605 s = SvPV(HeVAL(envhe),len);
188ea221 606 if (mg->mg_len != HEf_SVKEY) SvREFCNT_dec(keysv);
a0d0e21e 607 }
608#endif
79072805 609 /* And you'll never guess what the dog had */
610 /* in its mouth... */
463ee0b2 611 if (tainting) {
88e89b8a 612 if (s && strEQ(ptr,"PATH")) {
a0d0e21e 613 char *strend = s + len;
463ee0b2 614
615 while (s < strend) {
616 s = cpytill(tokenbuf,s,strend,':',&i);
617 s++;
618 if (*tokenbuf != '/'
a0d0e21e 619 || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
8990e307 620 MgTAINTEDDIR_on(mg);
463ee0b2 621 }
79072805 622 }
623 }
79072805 624 return 0;
625}
626
627int
85e6fe83 628magic_clearenv(sv,mg)
629SV* sv;
630MAGIC* mg;
631{
188ea221 632 my_setenv(MgPV(mg),Nullch);
85e6fe83 633 return 0;
634}
635
88e89b8a 636int
637magic_getsig(sv,mg)
638SV* sv;
639MAGIC* mg;
640{
641 I32 i;
642 /* Are we fetching a signal entry? */
188ea221 643 i = whichsig(MgPV(mg));
88e89b8a 644 if (i) {
645 if(psig_ptr[i])
646 sv_setsv(sv,psig_ptr[i]);
647 else {
ff68c719 648 Sighandler_t sigstate = rsignal_state(i);
649
88e89b8a 650 /* cache state so we don't fetch it again */
ff68c719 651 if(sigstate == SIG_IGN)
88e89b8a 652 sv_setpv(sv,"IGNORE");
653 else
654 sv_setsv(sv,&sv_undef);
655 psig_ptr[i] = SvREFCNT_inc(sv);
656 SvTEMP_off(sv);
657 }
658 }
659 return 0;
660}
661int
662magic_clearsig(sv,mg)
663SV* sv;
664MAGIC* mg;
665{
666 I32 i;
667 /* Are we clearing a signal entry? */
188ea221 668 i = whichsig(MgPV(mg));
88e89b8a 669 if (i) {
670 if(psig_ptr[i]) {
671 SvREFCNT_dec(psig_ptr[i]);
672 psig_ptr[i]=0;
673 }
674 if(psig_name[i]) {
675 SvREFCNT_dec(psig_name[i]);
676 psig_name[i]=0;
677 }
678 }
679 return 0;
680}
3d37d572 681
85e6fe83 682int
79072805 683magic_setsig(sv,mg)
684SV* sv;
685MAGIC* mg;
686{
687 register char *s;
688 I32 i;
748a9306 689 SV** svp;
a0d0e21e 690
188ea221 691 s = MgPV(mg);
748a9306 692 if (*s == '_') {
693 if (strEQ(s,"__DIE__"))
694 svp = &diehook;
695 else if (strEQ(s,"__WARN__"))
696 svp = &warnhook;
697 else if (strEQ(s,"__PARSE__"))
698 svp = &parsehook;
699 else
700 croak("No such hook: %s", s);
701 i = 0;
4633a7c4 702 if (*svp) {
703 SvREFCNT_dec(*svp);
704 *svp = 0;
705 }
748a9306 706 }
707 else {
708 i = whichsig(s); /* ...no, a brick */
709 if (!i) {
710 if (dowarn || strEQ(s,"ALARM"))
711 warn("No such signal: SIG%s", s);
712 return 0;
713 }
88e89b8a 714 if(psig_ptr[i])
715 SvREFCNT_dec(psig_ptr[i]);
716 psig_ptr[i] = SvREFCNT_inc(sv);
717 if(psig_name[i])
718 SvREFCNT_dec(psig_name[i]);
8646b087 719 psig_name[i] = newSVpv(s,strlen(s));
88e89b8a 720 SvTEMP_off(sv); /* Make sure it doesn't go away on us */
721 SvREADONLY_on(psig_name[i]);
748a9306 722 }
a0d0e21e 723 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
748a9306 724 if (i)
ff68c719 725 (void)rsignal(i, sighandler);
748a9306 726 else
727 *svp = SvREFCNT_inc(sv);
a0d0e21e 728 return 0;
729 }
730 s = SvPV_force(sv,na);
748a9306 731 if (strEQ(s,"IGNORE")) {
732 if (i)
ff68c719 733 (void)rsignal(i, SIG_IGN);
748a9306 734 else
735 *svp = 0;
736 }
737 else if (strEQ(s,"DEFAULT") || !*s) {
738 if (i)
ff68c719 739 (void)rsignal(i, SIG_DFL);
748a9306 740 else
741 *svp = 0;
742 }
79072805 743 else {
760ac839 744 if(hints & HINT_STRICT_REFS)
745 die(no_symref,s,"a subroutine");
2304df62 746 if (!strchr(s,':') && !strchr(s,'\'')) {
747 sprintf(tokenbuf, "main::%s",s);
79072805 748 sv_setpv(sv,tokenbuf);
749 }
748a9306 750 if (i)
ff68c719 751 (void)rsignal(i, sighandler);
748a9306 752 else
753 *svp = SvREFCNT_inc(sv);
79072805 754 }
755 return 0;
756}
757
758int
463ee0b2 759magic_setisa(sv,mg)
79072805 760SV* sv;
761MAGIC* mg;
762{
463ee0b2 763 sub_generation++;
764 return 0;
765}
766
a0d0e21e 767#ifdef OVERLOAD
768
463ee0b2 769int
a0d0e21e 770magic_setamagic(sv,mg)
463ee0b2 771SV* sv;
772MAGIC* mg;
773{
a0d0e21e 774 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
775 amagic_generation++;
463ee0b2 776
a0d0e21e 777 return 0;
778}
779#endif /* OVERLOAD */
463ee0b2 780
946ec16e 781int
782magic_setnkeys(sv,mg)
783SV* sv;
784MAGIC* mg;
785{
786 if (LvTARG(sv)) {
787 hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
788 LvTARG(sv) = Nullsv; /* Don't allow a ref to reassign this. */
789 }
790 return 0;
791}
792
a0d0e21e 793static int
794magic_methpack(sv,mg,meth)
795SV* sv;
796MAGIC* mg;
797char *meth;
798{
799 dSP;
463ee0b2 800
a0d0e21e 801 ENTER;
802 SAVETMPS;
803 PUSHMARK(sp);
804 EXTEND(sp, 2);
805 PUSHs(mg->mg_obj);
88e89b8a 806 if (mg->mg_ptr) {
807 if (mg->mg_len >= 0)
808 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
809 else if (mg->mg_len == HEf_SVKEY)
810 PUSHs((SV*)mg->mg_ptr);
811 }
a0d0e21e 812 else if (mg->mg_type == 'p')
813 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2 814 PUTBACK;
815
a0d0e21e 816 if (perl_call_method(meth, G_SCALAR))
817 sv_setsv(sv, *stack_sp--);
463ee0b2 818
a0d0e21e 819 FREETMPS;
820 LEAVE;
821 return 0;
822}
463ee0b2 823
a0d0e21e 824int
825magic_getpack(sv,mg)
826SV* sv;
827MAGIC* mg;
828{
829 magic_methpack(sv,mg,"FETCH");
830 if (mg->mg_ptr)
831 mg->mg_flags |= MGf_GSKIP;
463ee0b2 832 return 0;
833}
834
835int
836magic_setpack(sv,mg)
837SV* sv;
838MAGIC* mg;
839{
463ee0b2 840 dSP;
463ee0b2 841
a0d0e21e 842 PUSHMARK(sp);
843 EXTEND(sp, 3);
844 PUSHs(mg->mg_obj);
88e89b8a 845 if (mg->mg_ptr) {
846 if (mg->mg_len >= 0)
847 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
848 else if (mg->mg_len == HEf_SVKEY)
849 PUSHs((SV*)mg->mg_ptr);
850 }
a0d0e21e 851 else if (mg->mg_type == 'p')
852 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2 853 PUSHs(sv);
854 PUTBACK;
855
a0d0e21e 856 perl_call_method("STORE", G_SCALAR|G_DISCARD);
463ee0b2 857
858 return 0;
859}
860
861int
862magic_clearpack(sv,mg)
863SV* sv;
864MAGIC* mg;
865{
a0d0e21e 866 return magic_methpack(sv,mg,"DELETE");
867}
463ee0b2 868
a0d0e21e 869int magic_wipepack(sv,mg)
870SV* sv;
871MAGIC* mg;
872{
873 dSP;
463ee0b2 874
a0d0e21e 875 PUSHMARK(sp);
876 XPUSHs(mg->mg_obj);
463ee0b2 877 PUTBACK;
463ee0b2 878
a0d0e21e 879 perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
463ee0b2 880
881 return 0;
882}
883
884int
885magic_nextpack(sv,mg,key)
886SV* sv;
887MAGIC* mg;
888SV* key;
889{
463ee0b2 890 dSP;
a0d0e21e 891 char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2 892
893 ENTER;
a0d0e21e 894 SAVETMPS;
895 PUSHMARK(sp);
896 EXTEND(sp, 2);
897 PUSHs(mg->mg_obj);
463ee0b2 898 if (SvOK(key))
899 PUSHs(key);
900 PUTBACK;
901
a0d0e21e 902 if (perl_call_method(meth, G_SCALAR))
903 sv_setsv(key, *stack_sp--);
463ee0b2 904
a0d0e21e 905 FREETMPS;
906 LEAVE;
79072805 907 return 0;
908}
909
910int
a0d0e21e 911magic_existspack(sv,mg)
912SV* sv;
913MAGIC* mg;
914{
915 return magic_methpack(sv,mg,"EXISTS");
916}
917
918int
79072805 919magic_setdbline(sv,mg)
920SV* sv;
921MAGIC* mg;
922{
923 OP *o;
924 I32 i;
925 GV* gv;
926 SV** svp;
927
928 gv = DBline;
929 i = SvTRUE(sv);
188ea221 930 svp = av_fetch(GvAV(gv),
931 atoi(MgPV(mg)), FALSE);
8990e307 932 if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
93a17b20 933 o->op_private = i;
79072805 934 else
935 warn("Can't break at that line\n");
936 return 0;
937}
938
939int
940magic_getarylen(sv,mg)
941SV* sv;
942MAGIC* mg;
943{
a0d0e21e 944 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
79072805 945 return 0;
946}
947
948int
949magic_setarylen(sv,mg)
950SV* sv;
951MAGIC* mg;
952{
a0d0e21e 953 av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
954 return 0;
955}
956
957int
958magic_getpos(sv,mg)
959SV* sv;
960MAGIC* mg;
961{
962 SV* lsv = LvTARG(sv);
963
964 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
965 mg = mg_find(lsv, 'g');
966 if (mg && mg->mg_len >= 0) {
967 sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
968 return 0;
969 }
970 }
971 (void)SvOK_off(sv);
972 return 0;
973}
974
975int
976magic_setpos(sv,mg)
977SV* sv;
978MAGIC* mg;
979{
980 SV* lsv = LvTARG(sv);
981 SSize_t pos;
982 STRLEN len;
983
984 mg = 0;
985
986 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
987 mg = mg_find(lsv, 'g');
988 if (!mg) {
989 if (!SvOK(sv))
990 return 0;
991 sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
992 mg = mg_find(lsv, 'g');
993 }
994 else if (!SvOK(sv)) {
995 mg->mg_len = -1;
996 return 0;
997 }
998 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
999
1000 pos = SvIV(sv) - curcop->cop_arybase;
1001 if (pos < 0) {
1002 pos += len;
1003 if (pos < 0)
1004 pos = 0;
1005 }
1006 else if (pos > len)
1007 pos = len;
1008 mg->mg_len = pos;
71be2cbc 1009 mg->mg_flags &= ~MGf_MINMATCH;
a0d0e21e 1010
79072805 1011 return 0;
1012}
1013
1014int
1015magic_getglob(sv,mg)
1016SV* sv;
1017MAGIC* mg;
1018{
8646b087 1019 if (SvFAKE(sv)) { /* FAKE globs can get coerced */
1020 SvFAKE_off(sv);
946ec16e 1021 gv_efullname3(sv,((GV*)sv), "*");
8646b087 1022 SvFAKE_on(sv);
1023 }
1024 else
946ec16e 1025 gv_efullname3(sv,((GV*)sv), "*"); /* a gv value, be nice */
79072805 1026 return 0;
1027}
1028
1029int
1030magic_setglob(sv,mg)
1031SV* sv;
1032MAGIC* mg;
1033{
1034 register char *s;
1035 GV* gv;
1036
1037 if (!SvOK(sv))
1038 return 0;
463ee0b2 1039 s = SvPV(sv, na);
79072805 1040 if (*s == '*' && s[1])
1041 s++;
85e6fe83 1042 gv = gv_fetchpv(s,TRUE, SVt_PVGV);
79072805 1043 if (sv == (SV*)gv)
1044 return 0;
1045 if (GvGP(sv))
88e89b8a 1046 gp_free((GV*)sv);
79072805 1047 GvGP(sv) = gp_ref(GvGP(gv));
79072805 1048 return 0;
1049}
1050
1051int
1052magic_setsubstr(sv,mg)
1053SV* sv;
1054MAGIC* mg;
1055{
8990e307 1056 STRLEN len;
1057 char *tmps = SvPV(sv,len);
1058 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
79072805 1059 return 0;
1060}
1061
1062int
463ee0b2 1063magic_gettaint(sv,mg)
1064SV* sv;
1065MAGIC* mg;
1066{
bbce6d69 1067 TAINT_IF((mg->mg_len & 1) ||
1068 (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */
463ee0b2 1069 return 0;
1070}
1071
1072int
1073magic_settaint(sv,mg)
1074SV* sv;
1075MAGIC* mg;
1076{
748a9306 1077 if (localizing) {
1078 if (localizing == 1)
1079 mg->mg_len <<= 1;
1080 else
1081 mg->mg_len >>= 1;
a0d0e21e 1082 }
748a9306 1083 else if (tainted)
1084 mg->mg_len |= 1;
1085 else
1086 mg->mg_len &= ~1;
463ee0b2 1087 return 0;
1088}
1089
1090int
79072805 1091magic_setvec(sv,mg)
1092SV* sv;
1093MAGIC* mg;
1094{
1095 do_vecset(sv); /* XXX slurp this routine */
1096 return 0;
1097}
1098
1099int
71be2cbc 1100magic_getitervar(sv,mg)
5f05dabc 1101SV* sv;
1102MAGIC* mg;
1103{
71be2cbc 1104 SV *targ = Nullsv;
5f05dabc 1105 if (LvTARGLEN(sv)) {
1106 AV* av = (AV*)LvTARG(sv);
71be2cbc 1107 if (LvTARGOFF(sv) <= AvFILL(av))
1108 targ = AvARRAY(av)[LvTARGOFF(sv)];
5f05dabc 1109 }
71be2cbc 1110 else
1111 targ = LvTARG(sv);
1112 sv_setsv(sv, targ ? targ : &sv_undef);
1113 return 0;
1114}
1115
1116int
1117magic_setitervar(sv,mg)
1118SV* sv;
1119MAGIC* mg;
1120{
1121 if (LvTARGLEN(sv))
1122 vivify_itervar(sv);
5f05dabc 1123 if (LvTARG(sv))
1124 sv_setsv(LvTARG(sv), sv);
1125 return 0;
1126}
1127
1128int
71be2cbc 1129magic_freeitervar(sv,mg)
5f05dabc 1130SV* sv;
1131MAGIC* mg;
1132{
1133 SvREFCNT_dec(LvTARG(sv));
71be2cbc 1134 return 0;
1135}
1136
1137void
1138vivify_itervar(sv)
1139SV* sv;
1140{
1141 AV* av;
1142
1143 if (!LvTARGLEN(sv))
1144 return;
1145 av = (AV*)LvTARG(sv);
1146 if (LvTARGOFF(sv) <= AvFILL(av)) {
1147 SV** svp = AvARRAY(av) + LvTARGOFF(sv);
1148 LvTARG(sv) = newSVsv(*svp);
1149 SvREFCNT_dec(*svp);
1150 *svp = SvREFCNT_inc(LvTARG(sv));
1151 }
1152 else
1153 LvTARG(sv) = Nullsv;
1154 SvREFCNT_dec(av);
1155 LvTARGLEN(sv) = 0;
5f05dabc 1156}
1157
1158int
93a17b20 1159magic_setmglob(sv,mg)
1160SV* sv;
1161MAGIC* mg;
1162{
a0d0e21e 1163 mg->mg_len = -1;
c6496cc7 1164 SvSCREAM_off(sv);
93a17b20 1165 return 0;
1166}
1167
1168int
79072805 1169magic_setbm(sv,mg)
1170SV* sv;
1171MAGIC* mg;
1172{
463ee0b2 1173 sv_unmagic(sv, 'B');
79072805 1174 SvVALID_off(sv);
1175 return 0;
1176}
1177
1178int
55497cff 1179magic_setfm(sv,mg)
1180SV* sv;
1181MAGIC* mg;
1182{
1183 sv_unmagic(sv, 'f');
1184 SvCOMPILED_off(sv);
1185 return 0;
1186}
1187
1188int
79072805 1189magic_setuvar(sv,mg)
1190SV* sv;
1191MAGIC* mg;
1192{
1193 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1194
1195 if (uf && uf->uf_set)
1196 (*uf->uf_set)(uf->uf_index, sv);
1197 return 0;
1198}
1199
7a4c00b4 1200#ifdef USE_LOCALE_COLLATE
79072805 1201int
bbce6d69 1202magic_setcollxfrm(sv,mg)
1203SV* sv;
1204MAGIC* mg;
1205{
1206 /*
1207 * René Descartes said "I think not."
1208 * and vanished with a faint plop.
1209 */
7a4c00b4 1210 if (mg->mg_ptr) {
1211 Safefree(mg->mg_ptr);
1212 mg->mg_ptr = NULL;
1213 mg->mg_len = -1;
1214 }
bbce6d69 1215 return 0;
1216}
7a4c00b4 1217#endif /* USE_LOCALE_COLLATE */
bbce6d69 1218
1219int
79072805 1220magic_set(sv,mg)
1221SV* sv;
1222MAGIC* mg;
1223{
1224 register char *s;
1225 I32 i;
8990e307 1226 STRLEN len;
79072805 1227 switch (*mg->mg_ptr) {
748a9306 1228 case '\001': /* ^A */
1229 sv_setsv(bodytarget, sv);
1230 break;
79072805 1231 case '\004': /* ^D */
8990e307 1232 debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
79072805 1233 DEBUG_x(dump_all());
1234 break;
28f23441 1235 case '\005': /* ^E */
1236#ifdef VMS
1237 set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1238#else
f86702cc 1239 /* will anyone ever use this? */
1240 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
28f23441 1241#endif
1242 break;
79072805 1243 case '\006': /* ^F */
463ee0b2 1244 maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1245 break;
a0d0e21e 1246 case '\010': /* ^H */
1247 hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1248 break;
79072805 1249 case '\t': /* ^I */
1250 if (inplace)
1251 Safefree(inplace);
1252 if (SvOK(sv))
a0d0e21e 1253 inplace = savepv(SvPV(sv,na));
79072805 1254 else
1255 inplace = Nullch;
1256 break;
28f23441 1257 case '\017': /* ^O */
1258 if (osname)
1259 Safefree(osname);
1260 if (SvOK(sv))
1261 osname = savepv(SvPV(sv,na));
1262 else
1263 osname = Nullch;
1264 break;
79072805 1265 case '\020': /* ^P */
463ee0b2 1266 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1267 if (i != perldb) {
1268 if (perldb)
1269 oldlastpm = curpm;
1270 else
1271 curpm = oldlastpm;
1272 }
1273 perldb = i;
1274 break;
f86702cc 1275 case '\023': /* ^S */
1276 STATUS_NATIVE_SET(SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv));
1277 break;
79072805 1278 case '\024': /* ^T */
88e89b8a 1279#ifdef BIG_TIME
1280 basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1281#else
85e6fe83 1282 basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
88e89b8a 1283#endif
79072805 1284 break;
1285 case '\027': /* ^W */
463ee0b2 1286 dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1287 break;
1288 case '.':
748a9306 1289 if (localizing) {
1290 if (localizing == 1)
1291 save_sptr((SV**)&last_in_gv);
1292 }
88e89b8a 1293 else if (SvOK(sv) && GvIO(last_in_gv))
a0d0e21e 1294 IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
79072805 1295 break;
1296 case '^':
a0d0e21e 1297 Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1298 IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1299 IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805 1300 break;
1301 case '~':
a0d0e21e 1302 Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1303 IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1304 IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805 1305 break;
1306 case '=':
a0d0e21e 1307 IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1308 break;
1309 case '-':
a0d0e21e 1310 IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1311 if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1312 IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
79072805 1313 break;
1314 case '%':
a0d0e21e 1315 IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805 1316 break;
1317 case '|':
a0d0e21e 1318 IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
463ee0b2 1319 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
a0d0e21e 1320 IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
79072805 1321 }
1322 break;
1323 case '*':
463ee0b2 1324 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1325 multiline = (i != 0);
1326 break;
1327 case '/':
c07a80fd 1328 SvREFCNT_dec(nrs);
1329 nrs = newSVsv(sv);
1330 SvREFCNT_dec(rs);
1331 rs = SvREFCNT_inc(nrs);
79072805 1332 break;
1333 case '\\':
1334 if (ors)
1335 Safefree(ors);
e3c19b7b 1336 if (SvOK(sv) || SvGMAGICAL(sv))
1337 ors = savepv(SvPV(sv,orslen));
1338 else {
1339 ors = Nullch;
1340 orslen = 0;
1341 }
79072805 1342 break;
1343 case ',':
1344 if (ofs)
1345 Safefree(ofs);
a0d0e21e 1346 ofs = savepv(SvPV(sv, ofslen));
79072805 1347 break;
1348 case '#':
1349 if (ofmt)
1350 Safefree(ofmt);
a0d0e21e 1351 ofmt = savepv(SvPV(sv,na));
79072805 1352 break;
1353 case '[':
a0d0e21e 1354 compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1355 break;
1356 case '?':
f86702cc 1357 STATUS_POSIX_SET(SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv));
79072805 1358 break;
1359 case '!':
f86702cc 1360 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),
1361 (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
79072805 1362 break;
1363 case '<':
463ee0b2 1364 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1365 if (delaymagic) {
1366 delaymagic |= DM_RUID;
1367 break; /* don't do magic till later */
1368 }
1369#ifdef HAS_SETRUID
85e6fe83 1370 (void)setruid((Uid_t)uid);
79072805 1371#else
1372#ifdef HAS_SETREUID
85e6fe83 1373 (void)setreuid((Uid_t)uid, (Uid_t)-1);
748a9306 1374#else
85e6fe83 1375#ifdef HAS_SETRESUID
1376 (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
79072805 1377#else
1378 if (uid == euid) /* special case $< = $> */
1379 (void)setuid(uid);
a0d0e21e 1380 else {
1381 uid = (I32)getuid();
463ee0b2 1382 croak("setruid() not implemented");
a0d0e21e 1383 }
79072805 1384#endif
1385#endif
85e6fe83 1386#endif
748a9306 1387 uid = (I32)getuid();
4633a7c4 1388 tainting |= (uid && (euid != uid || egid != gid));
79072805 1389 break;
1390 case '>':
463ee0b2 1391 euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1392 if (delaymagic) {
1393 delaymagic |= DM_EUID;
1394 break; /* don't do magic till later */
1395 }
1396#ifdef HAS_SETEUID
85e6fe83 1397 (void)seteuid((Uid_t)euid);
79072805 1398#else
1399#ifdef HAS_SETREUID
85e6fe83 1400 (void)setreuid((Uid_t)-1, (Uid_t)euid);
1401#else
1402#ifdef HAS_SETRESUID
1403 (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
79072805 1404#else
1405 if (euid == uid) /* special case $> = $< */
1406 setuid(euid);
a0d0e21e 1407 else {
1408 euid = (I32)geteuid();
463ee0b2 1409 croak("seteuid() not implemented");
a0d0e21e 1410 }
79072805 1411#endif
1412#endif
85e6fe83 1413#endif
79072805 1414 euid = (I32)geteuid();
4633a7c4 1415 tainting |= (uid && (euid != uid || egid != gid));
79072805 1416 break;
1417 case '(':
463ee0b2 1418 gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1419 if (delaymagic) {
1420 delaymagic |= DM_RGID;
1421 break; /* don't do magic till later */
1422 }
1423#ifdef HAS_SETRGID
85e6fe83 1424 (void)setrgid((Gid_t)gid);
79072805 1425#else
1426#ifdef HAS_SETREGID
85e6fe83 1427 (void)setregid((Gid_t)gid, (Gid_t)-1);
1428#else
1429#ifdef HAS_SETRESGID
1430 (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
79072805 1431#else
1432 if (gid == egid) /* special case $( = $) */
1433 (void)setgid(gid);
748a9306 1434 else {
1435 gid = (I32)getgid();
463ee0b2 1436 croak("setrgid() not implemented");
748a9306 1437 }
79072805 1438#endif
1439#endif
85e6fe83 1440#endif
79072805 1441 gid = (I32)getgid();
4633a7c4 1442 tainting |= (uid && (euid != uid || egid != gid));
79072805 1443 break;
1444 case ')':
463ee0b2 1445 egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1446 if (delaymagic) {
1447 delaymagic |= DM_EGID;
1448 break; /* don't do magic till later */
1449 }
1450#ifdef HAS_SETEGID
85e6fe83 1451 (void)setegid((Gid_t)egid);
79072805 1452#else
1453#ifdef HAS_SETREGID
85e6fe83 1454 (void)setregid((Gid_t)-1, (Gid_t)egid);
1455#else
1456#ifdef HAS_SETRESGID
1457 (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
79072805 1458#else
1459 if (egid == gid) /* special case $) = $( */
1460 (void)setgid(egid);
748a9306 1461 else {
1462 egid = (I32)getegid();
463ee0b2 1463 croak("setegid() not implemented");
748a9306 1464 }
79072805 1465#endif
1466#endif
85e6fe83 1467#endif
79072805 1468 egid = (I32)getegid();
4633a7c4 1469 tainting |= (uid && (euid != uid || egid != gid));
79072805 1470 break;
1471 case ':':
a0d0e21e 1472 chopset = SvPV_force(sv,na);
79072805 1473 break;
1474 case '0':
1475 if (!origalen) {
1476 s = origargv[0];
1477 s += strlen(s);
1478 /* See if all the arguments are contiguous in memory */
1479 for (i = 1; i < origargc; i++) {
1480 if (origargv[i] == s + 1)
1481 s += strlen(++s); /* this one is ok too */
1482 }
bbce6d69 1483 /* can grab env area too? */
1484 if (origenviron && origenviron[0] == s + 1) {
79072805 1485 my_setenv("NoNeSuCh", Nullch);
1486 /* force copy of environment */
1487 for (i = 0; origenviron[i]; i++)
1488 if (origenviron[i] == s + 1)
1489 s += strlen(++s);
1490 }
1491 origalen = s - origargv[0];
1492 }
a0d0e21e 1493 s = SvPV_force(sv,len);
8990e307 1494 i = len;
79072805 1495 if (i >= origalen) {
1496 i = origalen;
1497 SvCUR_set(sv, i);
1498 *SvEND(sv) = '\0';
1499 Copy(s, origargv[0], i, char);
1500 }
1501 else {
1502 Copy(s, origargv[0], i, char);
1503 s = origargv[0]+i;
1504 *s++ = '\0';
1505 while (++i < origalen)
8990e307 1506 *s++ = ' ';
1507 s = origargv[0]+i;
ed6116ce 1508 for (i = 1; i < origargc; i++)
8990e307 1509 origargv[i] = Nullch;
79072805 1510 }
1511 break;
1512 }
1513 return 0;
1514}
1515
1516I32
1517whichsig(sig)
1518char *sig;
1519{
1520 register char **sigv;
1521
1522 for (sigv = sig_name+1; *sigv; sigv++)
1523 if (strEQ(sig,*sigv))
8e07c86e 1524 return sig_num[sigv - sig_name];
79072805 1525#ifdef SIGCLD
1526 if (strEQ(sig,"CHLD"))
1527 return SIGCLD;
1528#endif
1529#ifdef SIGCHLD
1530 if (strEQ(sig,"CLD"))
1531 return SIGCHLD;
1532#endif
1533 return 0;
1534}
1535
ecfc5424 1536Signal_t
79072805 1537sighandler(sig)
a0d0e21e 1538int sig;
79072805 1539{
1540 dSP;
1541 GV *gv;
a0d0e21e 1542 HV *st;
79072805 1543 SV *sv;
1544 CV *cv;
79072805 1545 AV *oldstack;
760ac839 1546
1547 if(!psig_ptr[sig])
1548 die("Signal SIG%s received, but no signal handler set.\n",
1549 sig_name[sig]);
79072805 1550
88e89b8a 1551 cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
a0d0e21e 1552 if (!cv || !CvROOT(cv)) {
79072805 1553 if (dowarn)
1554 warn("SIG%s handler \"%s\" not defined.\n",
88e89b8a 1555 sig_name[sig], GvENAME(gv) );
79072805 1556 return;
1557 }
1558
88e89b8a 1559 oldstack = curstack;
1560 if (curstack != signalstack)
a0d0e21e 1561 AvFILL(signalstack) = 0;
88e89b8a 1562 SWITCHSTACK(curstack, signalstack);
79072805 1563
88e89b8a 1564 if(psig_name[sig])
1565 sv = SvREFCNT_inc(psig_name[sig]);
1566 else {
1567 sv = sv_newmortal();
1568 sv_setpv(sv,sig_name[sig]);
1569 }
a0d0e21e 1570 PUSHMARK(sp);
79072805 1571 PUSHs(sv);
79072805 1572 PUTBACK;
a0d0e21e 1573
1574 perl_call_sv((SV*)cv, G_DISCARD);
79072805 1575
1576 SWITCHSTACK(signalstack, oldstack);
79072805 1577
1578 return;
1579}