This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[shell changes from patch from perl5.003_10 to perl5.003_11]
[perl5.git] / mg.c
CommitLineData
a0d0e21e 1/* mg.c
79072805 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, 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"
16#include "perl.h"
17
e6d9441c 18/* XXX If this causes problems, set i_unistd=undef in the hint file. */
a0d0e21e
LW
19#ifdef I_UNISTD
20# include <unistd.h>
21#endif
a0d0e21e 22
188ea221
CS
23#ifdef HAS_GETGROUPS
24# ifndef NGROUPS
25# define NGROUPS 32
26# endif
27#endif
28
bbce6d69 29#define TAINT_FROM_REGEX(sv,rx) \
30 if ((rx)->exec_tainted) { \
31 SvTAINTED_on(sv); \
32 } else \
33 SvTAINTED_off(sv);
34
c07a80fd 35/*
36 * Use the "DESTRUCTOR" scope cleanup to reinstate magic.
37 */
38
39struct magic_state {
40 SV* mgs_sv;
41 U32 mgs_flags;
42};
43typedef struct magic_state MGS;
44
45static void restore_magic _((void *p));
46
47static MGS *
48save_magic(sv)
49SV* sv;
50{
51 MGS* mgs;
52
53 assert(SvMAGICAL(sv));
54
55 mgs = (MGS*)safemalloc(sizeof(MGS));
56 mgs->mgs_sv = sv;
57 mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
58 SAVEDESTRUCTOR(restore_magic, mgs);
59
60 SvMAGICAL_off(sv);
61 SvREADONLY_off(sv);
62 SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
63
64 return mgs;
65}
66
67static void
68restore_magic(p)
69void* p;
70{
71 MGS *mgs = (MGS*)p;
72 SV* sv = mgs->mgs_sv;
73
74 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
75 {
76 if (mgs->mgs_flags)
77 SvFLAGS(sv) |= mgs->mgs_flags;
78 else
79 mg_magical(sv);
80 if (SvGMAGICAL(sv))
81 SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
82 }
83
e6d9441c 84 Safefree(mgs);
c07a80fd 85}
86
8e07c86e 87
8990e307
LW
88void
89mg_magical(sv)
90SV* sv;
91{
92 MAGIC* mg;
93 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
94 MGVTBL* vtbl = mg->mg_virtual;
95 if (vtbl) {
a0d0e21e 96 if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
8990e307
LW
97 SvGMAGICAL_on(sv);
98 if (vtbl->svt_set)
99 SvSMAGICAL_on(sv);
100 if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
101 SvRMAGICAL_on(sv);
102 }
103 }
104}
105
79072805
LW
106int
107mg_get(sv)
108SV* sv;
109{
c07a80fd 110 MGS* mgs;
79072805 111 MAGIC* mg;
c6496cc7 112 MAGIC** mgp;
760ac839 113 int mgp_valid = 0;
463ee0b2 114
c07a80fd 115 ENTER;
116 mgs = save_magic(sv);
463ee0b2 117
c6496cc7 118 mgp = &SvMAGIC(sv);
119 while ((mg = *mgp) != 0) {
79072805 120 MGVTBL* vtbl = mg->mg_virtual;
a0d0e21e 121 if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
79072805 122 (*vtbl->svt_get)(sv, mg);
c6496cc7 123 /* Ignore this magic if it's been deleted */
760ac839 124 if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) && (mg->mg_flags & MGf_GSKIP))
c07a80fd 125 mgs->mgs_flags = 0;
a0d0e21e 126 }
c6496cc7 127 /* Advance to next magic (complicated by possible deletion) */
760ac839 128 if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
c6496cc7 129 mgp = &mg->mg_moremagic;
760ac839
LW
130 mgp_valid = 1;
131 }
132 else
133 mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
79072805 134 }
463ee0b2 135
c07a80fd 136 LEAVE;
79072805
LW
137 return 0;
138}
139
140int
141mg_set(sv)
142SV* sv;
143{
c07a80fd 144 MGS* mgs;
79072805 145 MAGIC* mg;
463ee0b2
LW
146 MAGIC* nextmg;
147
c07a80fd 148 ENTER;
149 mgs = save_magic(sv);
463ee0b2
LW
150
151 for (mg = SvMAGIC(sv); mg; mg = nextmg) {
79072805 152 MGVTBL* vtbl = mg->mg_virtual;
463ee0b2 153 nextmg = mg->mg_moremagic; /* it may delete itself */
a0d0e21e
LW
154 if (mg->mg_flags & MGf_GSKIP) {
155 mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
c07a80fd 156 mgs->mgs_flags = 0;
a0d0e21e 157 }
79072805
LW
158 if (vtbl && vtbl->svt_set)
159 (*vtbl->svt_set)(sv, mg);
160 }
463ee0b2 161
c07a80fd 162 LEAVE;
79072805
LW
163 return 0;
164}
165
166U32
167mg_len(sv)
168SV* sv;
169{
170 MAGIC* mg;
748a9306 171 char *junk;
463ee0b2 172 STRLEN len;
463ee0b2 173
79072805
LW
174 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
175 MGVTBL* vtbl = mg->mg_virtual;
85e6fe83 176 if (vtbl && vtbl->svt_len) {
c07a80fd 177 ENTER;
178 save_magic(sv);
a0d0e21e 179 /* omit MGf_GSKIP -- not changed here */
85e6fe83 180 len = (*vtbl->svt_len)(sv, mg);
c07a80fd 181 LEAVE;
85e6fe83
LW
182 return len;
183 }
184 }
185
748a9306 186 junk = SvPV(sv, len);
463ee0b2 187 return len;
79072805
LW
188}
189
190int
191mg_clear(sv)
192SV* sv;
193{
194 MAGIC* mg;
463ee0b2 195
c07a80fd 196 ENTER;
197 save_magic(sv);
463ee0b2 198
79072805
LW
199 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
200 MGVTBL* vtbl = mg->mg_virtual;
a0d0e21e
LW
201 /* omit GSKIP -- never set here */
202
79072805
LW
203 if (vtbl && vtbl->svt_clear)
204 (*vtbl->svt_clear)(sv, mg);
205 }
463ee0b2 206
c07a80fd 207 LEAVE;
79072805
LW
208 return 0;
209}
210
93a17b20
LW
211MAGIC*
212mg_find(sv, type)
213SV* sv;
a0d0e21e 214int type;
93a17b20
LW
215{
216 MAGIC* mg;
93a17b20
LW
217 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
218 if (mg->mg_type == type)
219 return mg;
220 }
221 return 0;
222}
223
79072805 224int
463ee0b2 225mg_copy(sv, nsv, key, klen)
79072805 226SV* sv;
463ee0b2
LW
227SV* nsv;
228char *key;
88e89b8a 229I32 klen;
79072805 230{
463ee0b2 231 int count = 0;
79072805 232 MAGIC* mg;
463ee0b2
LW
233 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
234 if (isUPPER(mg->mg_type)) {
a0d0e21e 235 sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
463ee0b2 236 count++;
79072805 237 }
79072805 238 }
463ee0b2 239 return count;
79072805
LW
240}
241
242int
463ee0b2 243mg_free(sv)
79072805
LW
244SV* sv;
245{
246 MAGIC* mg;
247 MAGIC* moremagic;
248 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
249 MGVTBL* vtbl = mg->mg_virtual;
250 moremagic = mg->mg_moremagic;
251 if (vtbl && vtbl->svt_free)
252 (*vtbl->svt_free)(sv, mg);
93a17b20 253 if (mg->mg_ptr && mg->mg_type != 'g')
88e89b8a 254 if (mg->mg_len >= 0)
255 Safefree(mg->mg_ptr);
256 else if (mg->mg_len == HEf_SVKEY)
257 SvREFCNT_dec((SV*)mg->mg_ptr);
85e6fe83 258 if (mg->mg_flags & MGf_REFCOUNTED)
8990e307 259 SvREFCNT_dec(mg->mg_obj);
79072805
LW
260 Safefree(mg);
261 }
262 SvMAGIC(sv) = 0;
263 return 0;
264}
265
266#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
267#include <signal.h>
268#endif
269
93a17b20
LW
270U32
271magic_len(sv, mg)
272SV *sv;
273MAGIC *mg;
274{
275 register I32 paren;
276 register char *s;
277 register I32 i;
bbce6d69 278 register REGEXP *rx;
748a9306 279 char *t;
93a17b20
LW
280
281 switch (*mg->mg_ptr) {
282 case '1': case '2': case '3': case '4':
283 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 284 if (curpm && (rx = curpm->op_pmregexp)) {
93a17b20
LW
285 paren = atoi(mg->mg_ptr);
286 getparen:
bbce6d69 287 if (paren <= rx->nparens &&
288 (s = rx->startp[paren]) &&
289 (t = rx->endp[paren]))
290 {
748a9306 291 i = t - s;
bbce6d69 292 if (i >= 0) {
293 TAINT_IF(rx->exec_tainted);
93a17b20 294 return i;
bbce6d69 295 }
93a17b20 296 }
93a17b20 297 }
748a9306 298 return 0;
93a17b20
LW
299 break;
300 case '+':
bbce6d69 301 if (curpm && (rx = curpm->op_pmregexp)) {
302 paren = rx->lastparen;
a0d0e21e
LW
303 if (!paren)
304 return 0;
93a17b20
LW
305 goto getparen;
306 }
748a9306 307 return 0;
93a17b20
LW
308 break;
309 case '`':
bbce6d69 310 if (curpm && (rx = curpm->op_pmregexp)) {
311 if ((s = rx->subbeg)) {
312 i = rx->startp[0] - s;
313 if (i >= 0) {
314 TAINT_IF(rx->exec_tainted);
93a17b20 315 return i;
bbce6d69 316 }
93a17b20 317 }
93a17b20 318 }
748a9306 319 return 0;
93a17b20 320 case '\'':
bbce6d69 321 if (curpm && (rx = curpm->op_pmregexp)) {
322 if ((s = rx->endp[0])) {
323 TAINT_IF(rx->exec_tainted);
324 return (STRLEN) (rx->subend - s);
93a17b20 325 }
93a17b20 326 }
748a9306 327 return 0;
93a17b20
LW
328 case ',':
329 return (STRLEN)ofslen;
330 case '\\':
331 return (STRLEN)orslen;
332 }
333 magic_get(sv,mg);
334 if (!SvPOK(sv) && SvNIOK(sv))
463ee0b2 335 sv_2pv(sv, &na);
93a17b20
LW
336 if (SvPOK(sv))
337 return SvCUR(sv);
338 return 0;
339}
340
79072805
LW
341int
342magic_get(sv, mg)
343SV *sv;
344MAGIC *mg;
345{
346 register I32 paren;
347 register char *s;
348 register I32 i;
bbce6d69 349 register REGEXP *rx;
748a9306 350 char *t;
79072805
LW
351
352 switch (*mg->mg_ptr) {
748a9306
LW
353 case '\001': /* ^A */
354 sv_setsv(sv, bodytarget);
355 break;
79072805 356 case '\004': /* ^D */
188ea221 357 sv_setiv(sv, (IV)(debug & 32767));
79072805 358 break;
28f23441 359 case '\005': /* ^E */
360#ifdef VMS
361 {
362# include <descrip.h>
363# include <starlet.h>
364 char msg[255];
365 $DESCRIPTOR(msgdsc,msg);
946ec16e 366 sv_setnv(sv,(double) vaxc$errno);
28f23441 367 if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
368 sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
369 else
370 sv_setpv(sv,"");
371 }
372#else
88e89b8a 373#ifdef OS2
946ec16e 374 sv_setnv(sv, (double)Perl_rc);
88e89b8a 375 sv_setpv(sv, os2error(Perl_rc));
376#else
946ec16e 377 sv_setnv(sv, (double)errno);
28f23441 378 sv_setpv(sv, errno ? Strerror(errno) : "");
379#endif
88e89b8a 380#endif
946ec16e 381 SvNOK_on(sv); /* what a wonderful hack! */
28f23441 382 break;
79072805 383 case '\006': /* ^F */
188ea221 384 sv_setiv(sv, (IV)maxsysfd);
79072805 385 break;
a0d0e21e 386 case '\010': /* ^H */
188ea221 387 sv_setiv(sv, (IV)hints);
a0d0e21e 388 break;
79072805
LW
389 case '\t': /* ^I */
390 if (inplace)
391 sv_setpv(sv, inplace);
392 else
188ea221 393 sv_setsv(sv, &sv_undef);
79072805 394 break;
28f23441 395 case '\017': /* ^O */
188ea221 396 sv_setpv(sv, osname);
28f23441 397 break;
79072805 398 case '\020': /* ^P */
188ea221 399 sv_setiv(sv, (IV)perldb);
79072805
LW
400 break;
401 case '\024': /* ^T */
88e89b8a 402#ifdef BIG_TIME
188ea221 403 sv_setnv(sv, basetime);
88e89b8a 404#else
188ea221 405 sv_setiv(sv, (IV)basetime);
88e89b8a 406#endif
79072805
LW
407 break;
408 case '\027': /* ^W */
188ea221 409 sv_setiv(sv, (IV)dowarn);
79072805
LW
410 break;
411 case '1': case '2': case '3': case '4':
412 case '5': case '6': case '7': case '8': case '9': case '&':
bbce6d69 413 if (curpm && (rx = curpm->op_pmregexp)) {
88e89b8a 414 paren = atoi(GvENAME((GV*)mg->mg_obj));
79072805 415 getparen:
bbce6d69 416 if (paren <= rx->nparens &&
417 (s = rx->startp[paren]) &&
418 (t = rx->endp[paren]))
419 {
748a9306
LW
420 i = t - s;
421 if (i >= 0) {
79072805 422 sv_setpvn(sv,s,i);
bbce6d69 423 TAINT_FROM_REGEX(sv,rx);
748a9306
LW
424 break;
425 }
79072805 426 }
79072805 427 }
748a9306 428 sv_setsv(sv,&sv_undef);
79072805
LW
429 break;
430 case '+':
bbce6d69 431 if (curpm && (rx = curpm->op_pmregexp)) {
432 paren = rx->lastparen;
a0d0e21e
LW
433 if (paren)
434 goto getparen;
79072805 435 }
748a9306 436 sv_setsv(sv,&sv_undef);
79072805
LW
437 break;
438 case '`':
bbce6d69 439 if (curpm && (rx = curpm->op_pmregexp)) {
440 if ((s = rx->subbeg)) {
441 i = rx->startp[0] - s;
748a9306 442 if (i >= 0) {
79072805 443 sv_setpvn(sv,s,i);
bbce6d69 444 TAINT_FROM_REGEX(sv,rx);
748a9306
LW
445 break;
446 }
79072805 447 }
79072805 448 }
748a9306 449 sv_setsv(sv,&sv_undef);
79072805
LW
450 break;
451 case '\'':
bbce6d69 452 if (curpm && (rx = curpm->op_pmregexp)) {
453 if ((s = rx->endp[0])) {
454 sv_setpvn(sv,s, rx->subend - s);
455 TAINT_FROM_REGEX(sv,rx);
748a9306 456 break;
79072805 457 }
79072805 458 }
748a9306 459 sv_setsv(sv,&sv_undef);
79072805
LW
460 break;
461 case '.':
462#ifndef lint
a0d0e21e 463 if (GvIO(last_in_gv)) {
188ea221 464 sv_setiv(sv, (IV)IoLINES(GvIO(last_in_gv)));
79072805
LW
465 }
466#endif
467 break;
468 case '?':
188ea221 469 sv_setiv(sv, (IV)statusvalue);
79072805
LW
470 break;
471 case '^':
a0d0e21e 472 s = IoTOP_NAME(GvIOp(defoutgv));
79072805
LW
473 if (s)
474 sv_setpv(sv,s);
475 else {
476 sv_setpv(sv,GvENAME(defoutgv));
477 sv_catpv(sv,"_TOP");
478 }
479 break;
480 case '~':
a0d0e21e 481 s = IoFMT_NAME(GvIOp(defoutgv));
79072805
LW
482 if (!s)
483 s = GvENAME(defoutgv);
484 sv_setpv(sv,s);
485 break;
486#ifndef lint
487 case '=':
188ea221 488 sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(defoutgv)));
79072805
LW
489 break;
490 case '-':
188ea221 491 sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(defoutgv)));
79072805
LW
492 break;
493 case '%':
188ea221 494 sv_setiv(sv, (IV)IoPAGE(GvIOp(defoutgv)));
79072805
LW
495 break;
496#endif
497 case ':':
498 break;
499 case '/':
500 break;
501 case '[':
188ea221 502 sv_setiv(sv, (IV)curcop->cop_arybase);
79072805
LW
503 break;
504 case '|':
188ea221 505 sv_setiv(sv, (IV)(IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
79072805
LW
506 break;
507 case ',':
508 sv_setpvn(sv,ofs,ofslen);
509 break;
510 case '\\':
511 sv_setpvn(sv,ors,orslen);
512 break;
513 case '#':
514 sv_setpv(sv,ofmt);
515 break;
516 case '!':
a5f75d66 517#ifdef VMS
946ec16e 518 sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
88e89b8a 519 sv_setpv(sv, errno ? Strerror(errno) : "");
a5f75d66 520#else
88e89b8a 521 {
522 int saveerrno = errno;
946ec16e 523 sv_setnv(sv, (double)errno);
88e89b8a 524#ifdef OS2
525 if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
526 else
a5f75d66 527#endif
2304df62 528 sv_setpv(sv, errno ? Strerror(errno) : "");
88e89b8a 529 errno = saveerrno;
530 }
531#endif
946ec16e 532 SvNOK_on(sv); /* what a wonderful hack! */
79072805
LW
533 break;
534 case '<':
188ea221 535 sv_setiv(sv, (IV)uid);
79072805
LW
536 break;
537 case '>':
188ea221 538 sv_setiv(sv, (IV)euid);
79072805
LW
539 break;
540 case '(':
188ea221 541 sv_setiv(sv, (IV)gid);
79072805
LW
542 s = buf;
543 (void)sprintf(s,"%d",(int)gid);
544 goto add_groups;
545 case ')':
188ea221 546 sv_setiv(sv, (IV)egid);
79072805
LW
547 s = buf;
548 (void)sprintf(s,"%d",(int)egid);
549 add_groups:
550 while (*s) s++;
551#ifdef HAS_GETGROUPS
79072805 552 {
a0d0e21e 553 Groups_t gary[NGROUPS];
79072805
LW
554
555 i = getgroups(NGROUPS,gary);
556 while (--i >= 0) {
188ea221 557 (void)sprintf(s," %d", (int)gary[i]);
79072805
LW
558 while (*s) s++;
559 }
560 }
561#endif
562 sv_setpv(sv,buf);
29355cf7 563 SvIOK_on(sv); /* what a wonderful hack! */
79072805
LW
564 break;
565 case '*':
566 break;
567 case '0':
568 break;
569 }
a0d0e21e 570 return 0;
79072805
LW
571}
572
573int
574magic_getuvar(sv, mg)
575SV *sv;
576MAGIC *mg;
577{
578 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
579
580 if (uf && uf->uf_val)
581 (*uf->uf_val)(uf->uf_index, sv);
582 return 0;
583}
584
585int
586magic_setenv(sv,mg)
587SV* sv;
588MAGIC* mg;
589{
590 register char *s;
88e89b8a 591 char *ptr;
a0d0e21e
LW
592 STRLEN len;
593 I32 i;
594 s = SvPV(sv,len);
188ea221 595 ptr = MgPV(mg);
88e89b8a 596 my_setenv(ptr, s);
a0d0e21e
LW
597#ifdef DYNAMIC_ENV_FETCH
598 /* We just undefd an environment var. Is a replacement */
599 /* waiting in the wings? */
600 if (!len) {
88e89b8a 601 HE *envhe;
188ea221
CS
602 SV *keysv;
603 if (mg->mg_len == HEf_SVKEY) keysv = (SV *)mg->mg_ptr;
604 else keysv = newSVpv(mg->mg_ptr,mg->mg_len);
605 if (envhe = hv_fetch_ent(GvHVn(envgv),keysv,FALSE,0))
88e89b8a 606 s = SvPV(HeVAL(envhe),len);
188ea221 607 if (mg->mg_len != HEf_SVKEY) SvREFCNT_dec(keysv);
a0d0e21e
LW
608 }
609#endif
79072805
LW
610 /* And you'll never guess what the dog had */
611 /* in its mouth... */
463ee0b2 612 if (tainting) {
88e89b8a 613 if (s && strEQ(ptr,"PATH")) {
a0d0e21e 614 char *strend = s + len;
463ee0b2
LW
615
616 while (s < strend) {
617 s = cpytill(tokenbuf,s,strend,':',&i);
618 s++;
619 if (*tokenbuf != '/'
a0d0e21e 620 || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
8990e307 621 MgTAINTEDDIR_on(mg);
463ee0b2 622 }
79072805
LW
623 }
624 }
79072805
LW
625 return 0;
626}
627
628int
85e6fe83
LW
629magic_clearenv(sv,mg)
630SV* sv;
631MAGIC* mg;
632{
188ea221 633 my_setenv(MgPV(mg),Nullch);
85e6fe83
LW
634 return 0;
635}
636
88e89b8a 637int
638magic_getsig(sv,mg)
639SV* sv;
640MAGIC* mg;
641{
642 I32 i;
643 /* Are we fetching a signal entry? */
188ea221 644 i = whichsig(MgPV(mg));
88e89b8a 645 if (i) {
646 if(psig_ptr[i])
647 sv_setsv(sv,psig_ptr[i]);
648 else {
ff68c719 649 Sighandler_t sigstate = rsignal_state(i);
650
88e89b8a 651 /* cache state so we don't fetch it again */
ff68c719 652 if(sigstate == SIG_IGN)
88e89b8a 653 sv_setpv(sv,"IGNORE");
654 else
655 sv_setsv(sv,&sv_undef);
656 psig_ptr[i] = SvREFCNT_inc(sv);
657 SvTEMP_off(sv);
658 }
659 }
660 return 0;
661}
662int
663magic_clearsig(sv,mg)
664SV* sv;
665MAGIC* mg;
666{
667 I32 i;
668 /* Are we clearing a signal entry? */
188ea221 669 i = whichsig(MgPV(mg));
88e89b8a 670 if (i) {
671 if(psig_ptr[i]) {
672 SvREFCNT_dec(psig_ptr[i]);
673 psig_ptr[i]=0;
674 }
675 if(psig_name[i]) {
676 SvREFCNT_dec(psig_name[i]);
677 psig_name[i]=0;
678 }
679 }
680 return 0;
681}
3d37d572 682
85e6fe83 683int
79072805
LW
684magic_setsig(sv,mg)
685SV* sv;
686MAGIC* mg;
687{
688 register char *s;
689 I32 i;
748a9306 690 SV** svp;
a0d0e21e 691
188ea221 692 s = MgPV(mg);
748a9306
LW
693 if (*s == '_') {
694 if (strEQ(s,"__DIE__"))
695 svp = &diehook;
696 else if (strEQ(s,"__WARN__"))
697 svp = &warnhook;
698 else if (strEQ(s,"__PARSE__"))
699 svp = &parsehook;
700 else
701 croak("No such hook: %s", s);
702 i = 0;
4633a7c4
LW
703 if (*svp) {
704 SvREFCNT_dec(*svp);
705 *svp = 0;
706 }
748a9306
LW
707 }
708 else {
709 i = whichsig(s); /* ...no, a brick */
710 if (!i) {
711 if (dowarn || strEQ(s,"ALARM"))
712 warn("No such signal: SIG%s", s);
713 return 0;
714 }
88e89b8a 715 if(psig_ptr[i])
716 SvREFCNT_dec(psig_ptr[i]);
717 psig_ptr[i] = SvREFCNT_inc(sv);
718 if(psig_name[i])
719 SvREFCNT_dec(psig_name[i]);
8646b087 720 psig_name[i] = newSVpv(s,strlen(s));
88e89b8a 721 SvTEMP_off(sv); /* Make sure it doesn't go away on us */
722 SvREADONLY_on(psig_name[i]);
748a9306 723 }
a0d0e21e 724 if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
748a9306 725 if (i)
ff68c719 726 (void)rsignal(i, sighandler);
748a9306
LW
727 else
728 *svp = SvREFCNT_inc(sv);
a0d0e21e
LW
729 return 0;
730 }
731 s = SvPV_force(sv,na);
748a9306
LW
732 if (strEQ(s,"IGNORE")) {
733 if (i)
ff68c719 734 (void)rsignal(i, SIG_IGN);
748a9306
LW
735 else
736 *svp = 0;
737 }
738 else if (strEQ(s,"DEFAULT") || !*s) {
739 if (i)
ff68c719 740 (void)rsignal(i, SIG_DFL);
748a9306
LW
741 else
742 *svp = 0;
743 }
79072805 744 else {
760ac839
LW
745 if(hints & HINT_STRICT_REFS)
746 die(no_symref,s,"a subroutine");
2304df62
AD
747 if (!strchr(s,':') && !strchr(s,'\'')) {
748 sprintf(tokenbuf, "main::%s",s);
79072805
LW
749 sv_setpv(sv,tokenbuf);
750 }
748a9306 751 if (i)
ff68c719 752 (void)rsignal(i, sighandler);
748a9306
LW
753 else
754 *svp = SvREFCNT_inc(sv);
79072805
LW
755 }
756 return 0;
757}
758
759int
463ee0b2 760magic_setisa(sv,mg)
79072805
LW
761SV* sv;
762MAGIC* mg;
763{
463ee0b2
LW
764 sub_generation++;
765 return 0;
766}
767
a0d0e21e
LW
768#ifdef OVERLOAD
769
463ee0b2 770int
a0d0e21e 771magic_setamagic(sv,mg)
463ee0b2
LW
772SV* sv;
773MAGIC* mg;
774{
a0d0e21e
LW
775 /* HV_badAMAGIC_on(Sv_STASH(sv)); */
776 amagic_generation++;
463ee0b2 777
a0d0e21e
LW
778 return 0;
779}
780#endif /* OVERLOAD */
463ee0b2 781
946ec16e 782int
783magic_setnkeys(sv,mg)
784SV* sv;
785MAGIC* mg;
786{
787 if (LvTARG(sv)) {
788 hv_ksplit((HV*)LvTARG(sv), SvIV(sv));
789 LvTARG(sv) = Nullsv; /* Don't allow a ref to reassign this. */
790 }
791 return 0;
792}
793
a0d0e21e
LW
794static int
795magic_methpack(sv,mg,meth)
796SV* sv;
797MAGIC* mg;
798char *meth;
799{
800 dSP;
463ee0b2 801
a0d0e21e
LW
802 ENTER;
803 SAVETMPS;
804 PUSHMARK(sp);
805 EXTEND(sp, 2);
806 PUSHs(mg->mg_obj);
88e89b8a 807 if (mg->mg_ptr) {
808 if (mg->mg_len >= 0)
809 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
810 else if (mg->mg_len == HEf_SVKEY)
811 PUSHs((SV*)mg->mg_ptr);
812 }
a0d0e21e
LW
813 else if (mg->mg_type == 'p')
814 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2
LW
815 PUTBACK;
816
a0d0e21e
LW
817 if (perl_call_method(meth, G_SCALAR))
818 sv_setsv(sv, *stack_sp--);
463ee0b2 819
a0d0e21e
LW
820 FREETMPS;
821 LEAVE;
822 return 0;
823}
463ee0b2 824
a0d0e21e
LW
825int
826magic_getpack(sv,mg)
827SV* sv;
828MAGIC* mg;
829{
830 magic_methpack(sv,mg,"FETCH");
831 if (mg->mg_ptr)
832 mg->mg_flags |= MGf_GSKIP;
463ee0b2
LW
833 return 0;
834}
835
836int
837magic_setpack(sv,mg)
838SV* sv;
839MAGIC* mg;
840{
463ee0b2 841 dSP;
463ee0b2 842
a0d0e21e
LW
843 PUSHMARK(sp);
844 EXTEND(sp, 3);
845 PUSHs(mg->mg_obj);
88e89b8a 846 if (mg->mg_ptr) {
847 if (mg->mg_len >= 0)
848 PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
849 else if (mg->mg_len == HEf_SVKEY)
850 PUSHs((SV*)mg->mg_ptr);
851 }
a0d0e21e
LW
852 else if (mg->mg_type == 'p')
853 PUSHs(sv_2mortal(newSViv(mg->mg_len)));
463ee0b2
LW
854 PUSHs(sv);
855 PUTBACK;
856
a0d0e21e 857 perl_call_method("STORE", G_SCALAR|G_DISCARD);
463ee0b2
LW
858
859 return 0;
860}
861
862int
863magic_clearpack(sv,mg)
864SV* sv;
865MAGIC* mg;
866{
a0d0e21e
LW
867 return magic_methpack(sv,mg,"DELETE");
868}
463ee0b2 869
a0d0e21e
LW
870int magic_wipepack(sv,mg)
871SV* sv;
872MAGIC* mg;
873{
874 dSP;
463ee0b2 875
a0d0e21e
LW
876 PUSHMARK(sp);
877 XPUSHs(mg->mg_obj);
463ee0b2 878 PUTBACK;
463ee0b2 879
a0d0e21e 880 perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
463ee0b2
LW
881
882 return 0;
883}
884
885int
886magic_nextpack(sv,mg,key)
887SV* sv;
888MAGIC* mg;
889SV* key;
890{
463ee0b2 891 dSP;
a0d0e21e 892 char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
463ee0b2
LW
893
894 ENTER;
a0d0e21e
LW
895 SAVETMPS;
896 PUSHMARK(sp);
897 EXTEND(sp, 2);
898 PUSHs(mg->mg_obj);
463ee0b2
LW
899 if (SvOK(key))
900 PUSHs(key);
901 PUTBACK;
902
a0d0e21e
LW
903 if (perl_call_method(meth, G_SCALAR))
904 sv_setsv(key, *stack_sp--);
463ee0b2 905
a0d0e21e
LW
906 FREETMPS;
907 LEAVE;
79072805
LW
908 return 0;
909}
910
911int
a0d0e21e
LW
912magic_existspack(sv,mg)
913SV* sv;
914MAGIC* mg;
915{
916 return magic_methpack(sv,mg,"EXISTS");
917}
918
919int
79072805
LW
920magic_setdbline(sv,mg)
921SV* sv;
922MAGIC* mg;
923{
924 OP *o;
925 I32 i;
926 GV* gv;
927 SV** svp;
928
929 gv = DBline;
930 i = SvTRUE(sv);
188ea221
CS
931 svp = av_fetch(GvAV(gv),
932 atoi(MgPV(mg)), FALSE);
8990e307 933 if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
93a17b20 934 o->op_private = i;
79072805
LW
935 else
936 warn("Can't break at that line\n");
937 return 0;
938}
939
940int
941magic_getarylen(sv,mg)
942SV* sv;
943MAGIC* mg;
944{
a0d0e21e 945 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
79072805
LW
946 return 0;
947}
948
949int
950magic_setarylen(sv,mg)
951SV* sv;
952MAGIC* mg;
953{
a0d0e21e
LW
954 av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
955 return 0;
956}
957
958int
959magic_getpos(sv,mg)
960SV* sv;
961MAGIC* mg;
962{
963 SV* lsv = LvTARG(sv);
964
965 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
966 mg = mg_find(lsv, 'g');
967 if (mg && mg->mg_len >= 0) {
968 sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
969 return 0;
970 }
971 }
972 (void)SvOK_off(sv);
973 return 0;
974}
975
976int
977magic_setpos(sv,mg)
978SV* sv;
979MAGIC* mg;
980{
981 SV* lsv = LvTARG(sv);
982 SSize_t pos;
983 STRLEN len;
984
985 mg = 0;
986
987 if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
988 mg = mg_find(lsv, 'g');
989 if (!mg) {
990 if (!SvOK(sv))
991 return 0;
992 sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
993 mg = mg_find(lsv, 'g');
994 }
995 else if (!SvOK(sv)) {
996 mg->mg_len = -1;
997 return 0;
998 }
999 len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
1000
1001 pos = SvIV(sv) - curcop->cop_arybase;
1002 if (pos < 0) {
1003 pos += len;
1004 if (pos < 0)
1005 pos = 0;
1006 }
1007 else if (pos > len)
1008 pos = len;
1009 mg->mg_len = pos;
1010
79072805
LW
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
LW
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
LW
1040 if (*s == '*' && s[1])
1041 s++;
85e6fe83 1042 gv = gv_fetchpv(s,TRUE, SVt_PVGV);
79072805
LW
1043 if (sv == (SV*)gv)
1044 return 0;
1045 if (GvGP(sv))
88e89b8a 1046 gp_free((GV*)sv);
79072805
LW
1047 GvGP(sv) = gp_ref(GvGP(gv));
1048 if (!GvAV(gv))
1049 gv_AVadd(gv);
1050 if (!GvHV(gv))
1051 gv_HVadd(gv);
a0d0e21e
LW
1052 if (!GvIOp(gv))
1053 GvIOp(gv) = newIO();
79072805
LW
1054 return 0;
1055}
1056
1057int
1058magic_setsubstr(sv,mg)
1059SV* sv;
1060MAGIC* mg;
1061{
8990e307
LW
1062 STRLEN len;
1063 char *tmps = SvPV(sv,len);
1064 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
79072805
LW
1065 return 0;
1066}
1067
1068int
463ee0b2
LW
1069magic_gettaint(sv,mg)
1070SV* sv;
1071MAGIC* mg;
1072{
bbce6d69 1073 TAINT_IF((mg->mg_len & 1) ||
1074 (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */
463ee0b2
LW
1075 return 0;
1076}
1077
1078int
1079magic_settaint(sv,mg)
1080SV* sv;
1081MAGIC* mg;
1082{
748a9306
LW
1083 if (localizing) {
1084 if (localizing == 1)
1085 mg->mg_len <<= 1;
1086 else
1087 mg->mg_len >>= 1;
a0d0e21e 1088 }
748a9306
LW
1089 else if (tainted)
1090 mg->mg_len |= 1;
1091 else
1092 mg->mg_len &= ~1;
463ee0b2
LW
1093 return 0;
1094}
1095
1096int
79072805
LW
1097magic_setvec(sv,mg)
1098SV* sv;
1099MAGIC* mg;
1100{
1101 do_vecset(sv); /* XXX slurp this routine */
1102 return 0;
1103}
1104
1105int
93a17b20
LW
1106magic_setmglob(sv,mg)
1107SV* sv;
1108MAGIC* mg;
1109{
a0d0e21e 1110 mg->mg_len = -1;
c6496cc7 1111 SvSCREAM_off(sv);
93a17b20
LW
1112 return 0;
1113}
1114
1115int
79072805
LW
1116magic_setbm(sv,mg)
1117SV* sv;
1118MAGIC* mg;
1119{
463ee0b2 1120 sv_unmagic(sv, 'B');
79072805
LW
1121 SvVALID_off(sv);
1122 return 0;
1123}
1124
1125int
55497cff 1126magic_setfm(sv,mg)
1127SV* sv;
1128MAGIC* mg;
1129{
1130 sv_unmagic(sv, 'f');
1131 SvCOMPILED_off(sv);
1132 return 0;
1133}
1134
1135int
79072805
LW
1136magic_setuvar(sv,mg)
1137SV* sv;
1138MAGIC* mg;
1139{
1140 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
1141
1142 if (uf && uf->uf_set)
1143 (*uf->uf_set)(uf->uf_index, sv);
1144 return 0;
1145}
1146
1147int
bbce6d69 1148magic_setcollxfrm(sv,mg)
1149SV* sv;
1150MAGIC* mg;
1151{
1152 /*
1153 * René Descartes said "I think not."
1154 * and vanished with a faint plop.
1155 */
1156 sv_unmagic(sv, 'o');
1157 return 0;
1158}
1159
1160int
79072805
LW
1161magic_set(sv,mg)
1162SV* sv;
1163MAGIC* mg;
1164{
1165 register char *s;
1166 I32 i;
8990e307 1167 STRLEN len;
79072805 1168 switch (*mg->mg_ptr) {
748a9306
LW
1169 case '\001': /* ^A */
1170 sv_setsv(bodytarget, sv);
1171 break;
79072805 1172 case '\004': /* ^D */
8990e307 1173 debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
79072805
LW
1174 DEBUG_x(dump_all());
1175 break;
28f23441 1176 case '\005': /* ^E */
1177#ifdef VMS
1178 set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1179#else
1180 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),4); /* will anyone ever use this? */
1181#endif
1182 break;
79072805 1183 case '\006': /* ^F */
463ee0b2 1184 maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805 1185 break;
a0d0e21e
LW
1186 case '\010': /* ^H */
1187 hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
1188 break;
79072805
LW
1189 case '\t': /* ^I */
1190 if (inplace)
1191 Safefree(inplace);
1192 if (SvOK(sv))
a0d0e21e 1193 inplace = savepv(SvPV(sv,na));
79072805
LW
1194 else
1195 inplace = Nullch;
1196 break;
28f23441 1197 case '\017': /* ^O */
1198 if (osname)
1199 Safefree(osname);
1200 if (SvOK(sv))
1201 osname = savepv(SvPV(sv,na));
1202 else
1203 osname = Nullch;
1204 break;
79072805 1205 case '\020': /* ^P */
463ee0b2 1206 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1207 if (i != perldb) {
1208 if (perldb)
1209 oldlastpm = curpm;
1210 else
1211 curpm = oldlastpm;
1212 }
1213 perldb = i;
1214 break;
1215 case '\024': /* ^T */
88e89b8a 1216#ifdef BIG_TIME
1217 basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv));
1218#else
85e6fe83 1219 basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
88e89b8a 1220#endif
79072805
LW
1221 break;
1222 case '\027': /* ^W */
463ee0b2 1223 dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1224 break;
1225 case '.':
748a9306
LW
1226 if (localizing) {
1227 if (localizing == 1)
1228 save_sptr((SV**)&last_in_gv);
1229 }
88e89b8a 1230 else if (SvOK(sv) && GvIO(last_in_gv))
a0d0e21e 1231 IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
79072805
LW
1232 break;
1233 case '^':
a0d0e21e
LW
1234 Safefree(IoTOP_NAME(GvIOp(defoutgv)));
1235 IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1236 IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
1237 break;
1238 case '~':
a0d0e21e
LW
1239 Safefree(IoFMT_NAME(GvIOp(defoutgv)));
1240 IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
1241 IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
79072805
LW
1242 break;
1243 case '=':
a0d0e21e 1244 IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1245 break;
1246 case '-':
a0d0e21e
LW
1247 IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
1248 if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
1249 IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
79072805
LW
1250 break;
1251 case '%':
a0d0e21e 1252 IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1253 break;
1254 case '|':
a0d0e21e 1255 IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
463ee0b2 1256 if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
a0d0e21e 1257 IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
79072805
LW
1258 }
1259 break;
1260 case '*':
463ee0b2 1261 i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1262 multiline = (i != 0);
1263 break;
1264 case '/':
c07a80fd 1265 SvREFCNT_dec(nrs);
1266 nrs = newSVsv(sv);
1267 SvREFCNT_dec(rs);
1268 rs = SvREFCNT_inc(nrs);
79072805
LW
1269 break;
1270 case '\\':
1271 if (ors)
1272 Safefree(ors);
a0d0e21e 1273 ors = savepv(SvPV(sv,orslen));
79072805
LW
1274 break;
1275 case ',':
1276 if (ofs)
1277 Safefree(ofs);
a0d0e21e 1278 ofs = savepv(SvPV(sv, ofslen));
79072805
LW
1279 break;
1280 case '#':
1281 if (ofmt)
1282 Safefree(ofmt);
a0d0e21e 1283 ofmt = savepv(SvPV(sv,na));
79072805
LW
1284 break;
1285 case '[':
a0d0e21e 1286 compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1287 break;
1288 case '?':
748a9306 1289 statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
79072805
LW
1290 break;
1291 case '!':
28f23441 1292 SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SvIV(sv) == EVMSERR ? 4 : vaxc$errno); /* will anyone ever use this? */
79072805
LW
1293 break;
1294 case '<':
463ee0b2 1295 uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1296 if (delaymagic) {
1297 delaymagic |= DM_RUID;
1298 break; /* don't do magic till later */
1299 }
1300#ifdef HAS_SETRUID
85e6fe83 1301 (void)setruid((Uid_t)uid);
79072805
LW
1302#else
1303#ifdef HAS_SETREUID
85e6fe83 1304 (void)setreuid((Uid_t)uid, (Uid_t)-1);
748a9306 1305#else
85e6fe83
LW
1306#ifdef HAS_SETRESUID
1307 (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
79072805
LW
1308#else
1309 if (uid == euid) /* special case $< = $> */
1310 (void)setuid(uid);
a0d0e21e
LW
1311 else {
1312 uid = (I32)getuid();
463ee0b2 1313 croak("setruid() not implemented");
a0d0e21e 1314 }
79072805
LW
1315#endif
1316#endif
85e6fe83 1317#endif
748a9306 1318 uid = (I32)getuid();
4633a7c4 1319 tainting |= (uid && (euid != uid || egid != gid));
79072805
LW
1320 break;
1321 case '>':
463ee0b2 1322 euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1323 if (delaymagic) {
1324 delaymagic |= DM_EUID;
1325 break; /* don't do magic till later */
1326 }
1327#ifdef HAS_SETEUID
85e6fe83 1328 (void)seteuid((Uid_t)euid);
79072805
LW
1329#else
1330#ifdef HAS_SETREUID
85e6fe83
LW
1331 (void)setreuid((Uid_t)-1, (Uid_t)euid);
1332#else
1333#ifdef HAS_SETRESUID
1334 (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
79072805
LW
1335#else
1336 if (euid == uid) /* special case $> = $< */
1337 setuid(euid);
a0d0e21e
LW
1338 else {
1339 euid = (I32)geteuid();
463ee0b2 1340 croak("seteuid() not implemented");
a0d0e21e 1341 }
79072805
LW
1342#endif
1343#endif
85e6fe83 1344#endif
79072805 1345 euid = (I32)geteuid();
4633a7c4 1346 tainting |= (uid && (euid != uid || egid != gid));
79072805
LW
1347 break;
1348 case '(':
463ee0b2 1349 gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1350 if (delaymagic) {
1351 delaymagic |= DM_RGID;
1352 break; /* don't do magic till later */
1353 }
1354#ifdef HAS_SETRGID
85e6fe83 1355 (void)setrgid((Gid_t)gid);
79072805
LW
1356#else
1357#ifdef HAS_SETREGID
85e6fe83
LW
1358 (void)setregid((Gid_t)gid, (Gid_t)-1);
1359#else
1360#ifdef HAS_SETRESGID
1361 (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
79072805
LW
1362#else
1363 if (gid == egid) /* special case $( = $) */
1364 (void)setgid(gid);
748a9306
LW
1365 else {
1366 gid = (I32)getgid();
463ee0b2 1367 croak("setrgid() not implemented");
748a9306 1368 }
79072805
LW
1369#endif
1370#endif
85e6fe83 1371#endif
79072805 1372 gid = (I32)getgid();
4633a7c4 1373 tainting |= (uid && (euid != uid || egid != gid));
79072805
LW
1374 break;
1375 case ')':
463ee0b2 1376 egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
79072805
LW
1377 if (delaymagic) {
1378 delaymagic |= DM_EGID;
1379 break; /* don't do magic till later */
1380 }
1381#ifdef HAS_SETEGID
85e6fe83 1382 (void)setegid((Gid_t)egid);
79072805
LW
1383#else
1384#ifdef HAS_SETREGID
85e6fe83
LW
1385 (void)setregid((Gid_t)-1, (Gid_t)egid);
1386#else
1387#ifdef HAS_SETRESGID
1388 (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
79072805
LW
1389#else
1390 if (egid == gid) /* special case $) = $( */
1391 (void)setgid(egid);
748a9306
LW
1392 else {
1393 egid = (I32)getegid();
463ee0b2 1394 croak("setegid() not implemented");
748a9306 1395 }
79072805
LW
1396#endif
1397#endif
85e6fe83 1398#endif
79072805 1399 egid = (I32)getegid();
4633a7c4 1400 tainting |= (uid && (euid != uid || egid != gid));
79072805
LW
1401 break;
1402 case ':':
a0d0e21e 1403 chopset = SvPV_force(sv,na);
79072805
LW
1404 break;
1405 case '0':
1406 if (!origalen) {
1407 s = origargv[0];
1408 s += strlen(s);
1409 /* See if all the arguments are contiguous in memory */
1410 for (i = 1; i < origargc; i++) {
1411 if (origargv[i] == s + 1)
1412 s += strlen(++s); /* this one is ok too */
1413 }
bbce6d69 1414 /* can grab env area too? */
1415 if (origenviron && origenviron[0] == s + 1) {
79072805
LW
1416 my_setenv("NoNeSuCh", Nullch);
1417 /* force copy of environment */
1418 for (i = 0; origenviron[i]; i++)
1419 if (origenviron[i] == s + 1)
1420 s += strlen(++s);
1421 }
1422 origalen = s - origargv[0];
1423 }
a0d0e21e 1424 s = SvPV_force(sv,len);
8990e307 1425 i = len;
79072805
LW
1426 if (i >= origalen) {
1427 i = origalen;
1428 SvCUR_set(sv, i);
1429 *SvEND(sv) = '\0';
1430 Copy(s, origargv[0], i, char);
1431 }
1432 else {
1433 Copy(s, origargv[0], i, char);
1434 s = origargv[0]+i;
1435 *s++ = '\0';
1436 while (++i < origalen)
8990e307
LW
1437 *s++ = ' ';
1438 s = origargv[0]+i;
ed6116ce 1439 for (i = 1; i < origargc; i++)
8990e307 1440 origargv[i] = Nullch;
79072805
LW
1441 }
1442 break;
1443 }
1444 return 0;
1445}
1446
1447I32
1448whichsig(sig)
1449char *sig;
1450{
1451 register char **sigv;
1452
1453 for (sigv = sig_name+1; *sigv; sigv++)
1454 if (strEQ(sig,*sigv))
8e07c86e 1455 return sig_num[sigv - sig_name];
79072805
LW
1456#ifdef SIGCLD
1457 if (strEQ(sig,"CHLD"))
1458 return SIGCLD;
1459#endif
1460#ifdef SIGCHLD
1461 if (strEQ(sig,"CLD"))
1462 return SIGCHLD;
1463#endif
1464 return 0;
1465}
1466
ecfc5424 1467Signal_t
79072805 1468sighandler(sig)
a0d0e21e 1469int sig;
79072805
LW
1470{
1471 dSP;
1472 GV *gv;
a0d0e21e 1473 HV *st;
79072805
LW
1474 SV *sv;
1475 CV *cv;
79072805 1476 AV *oldstack;
760ac839
LW
1477
1478 if(!psig_ptr[sig])
1479 die("Signal SIG%s received, but no signal handler set.\n",
1480 sig_name[sig]);
79072805 1481
88e89b8a 1482 cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
a0d0e21e 1483 if (!cv || !CvROOT(cv)) {
79072805
LW
1484 if (dowarn)
1485 warn("SIG%s handler \"%s\" not defined.\n",
88e89b8a 1486 sig_name[sig], GvENAME(gv) );
79072805
LW
1487 return;
1488 }
1489
88e89b8a 1490 oldstack = curstack;
1491 if (curstack != signalstack)
a0d0e21e 1492 AvFILL(signalstack) = 0;
88e89b8a 1493 SWITCHSTACK(curstack, signalstack);
79072805 1494
88e89b8a 1495 if(psig_name[sig])
1496 sv = SvREFCNT_inc(psig_name[sig]);
1497 else {
1498 sv = sv_newmortal();
1499 sv_setpv(sv,sig_name[sig]);
1500 }
a0d0e21e 1501 PUSHMARK(sp);
79072805 1502 PUSHs(sv);
79072805 1503 PUTBACK;
a0d0e21e
LW
1504
1505 perl_call_sv((SV*)cv, G_DISCARD);
79072805
LW
1506
1507 SWITCHSTACK(signalstack, oldstack);
79072805
LW
1508
1509 return;
1510}