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