home *** CD-ROM | disk | FTP | other *** search
- /* mg.c
- *
- * Copyright (c) 1991-1994, Larry Wall
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Artistic License, as specified in the README file.
- *
- */
-
- /*
- * "Sam sat on the ground and put his head in his hands. 'I wish I had never
- * come here, and I don't want to see no more magic,' he said, and fell silent."
- */
-
- #include "EXTERN.h"
- #include "perl.h"
-
- /* Omit -- it causes too much grief on mixed systems.
- #ifdef I_UNISTD
- # include <unistd.h>
- #endif
- */
-
- void
- mg_magical(sv)
- SV* sv;
- {
- MAGIC* mg;
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- MGVTBL* vtbl = mg->mg_virtual;
- if (vtbl) {
- if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
- SvGMAGICAL_on(sv);
- if (vtbl->svt_set)
- SvSMAGICAL_on(sv);
- if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
- SvRMAGICAL_on(sv);
- }
- }
- }
-
- int
- mg_get(sv)
- SV* sv;
- {
- MAGIC* mg;
- U32 savemagic = SvMAGICAL(sv) | SvREADONLY(sv);
-
- assert(SvGMAGICAL(sv));
- SvMAGICAL_off(sv);
- SvREADONLY_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- MGVTBL* vtbl = mg->mg_virtual;
- if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
- (*vtbl->svt_get)(sv, mg);
- if (mg->mg_flags & MGf_GSKIP)
- savemagic = 0;
- }
- }
-
- if (savemagic)
- SvFLAGS(sv) |= savemagic;
- else
- mg_magical(sv);
- if (SvGMAGICAL(sv))
- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
-
- return 0;
- }
-
- int
- mg_set(sv)
- SV* sv;
- {
- MAGIC* mg;
- MAGIC* nextmg;
- U32 savemagic = SvMAGICAL(sv);
-
- SvMAGICAL_off(sv);
-
- for (mg = SvMAGIC(sv); mg; mg = nextmg) {
- MGVTBL* vtbl = mg->mg_virtual;
- nextmg = mg->mg_moremagic; /* it may delete itself */
- if (mg->mg_flags & MGf_GSKIP) {
- mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
- savemagic = 0;
- }
- if (vtbl && vtbl->svt_set)
- (*vtbl->svt_set)(sv, mg);
- }
-
- if (SvMAGIC(sv)) {
- if (savemagic)
- SvFLAGS(sv) |= savemagic;
- else
- mg_magical(sv);
- if (SvGMAGICAL(sv))
- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
- }
-
- return 0;
- }
-
- U32
- mg_len(sv)
- SV* sv;
- {
- MAGIC* mg;
- char *junk;
- STRLEN len;
-
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- MGVTBL* vtbl = mg->mg_virtual;
- if (vtbl && vtbl->svt_len) {
- U32 savemagic = SvMAGICAL(sv);
-
- SvMAGICAL_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv)&(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-
- /* omit MGf_GSKIP -- not changed here */
- len = (*vtbl->svt_len)(sv, mg);
-
- SvFLAGS(sv) |= savemagic;
- if (SvGMAGICAL(sv))
- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
-
- return len;
- }
- }
-
- junk = SvPV(sv, len);
- return len;
- }
-
- int
- mg_clear(sv)
- SV* sv;
- {
- MAGIC* mg;
- U32 savemagic = SvMAGICAL(sv);
-
- SvMAGICAL_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- MGVTBL* vtbl = mg->mg_virtual;
- /* omit GSKIP -- never set here */
-
- if (vtbl && vtbl->svt_clear)
- (*vtbl->svt_clear)(sv, mg);
- }
-
- SvFLAGS(sv) |= savemagic;
- if (SvGMAGICAL(sv))
- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
-
- return 0;
- }
-
- MAGIC*
- mg_find(sv, type)
- SV* sv;
- int type;
- {
- MAGIC* mg;
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- if (mg->mg_type == type)
- return mg;
- }
- return 0;
- }
-
- int
- mg_copy(sv, nsv, key, klen)
- SV* sv;
- SV* nsv;
- char *key;
- STRLEN klen;
- {
- int count = 0;
- MAGIC* mg;
- for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
- if (isUPPER(mg->mg_type)) {
- sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
- count++;
- }
- }
- return count;
- }
-
- int
- mg_free(sv)
- SV* sv;
- {
- MAGIC* mg;
- MAGIC* moremagic;
- for (mg = SvMAGIC(sv); mg; mg = moremagic) {
- MGVTBL* vtbl = mg->mg_virtual;
- moremagic = mg->mg_moremagic;
- if (vtbl && vtbl->svt_free)
- (*vtbl->svt_free)(sv, mg);
- if (mg->mg_ptr && mg->mg_type != 'g')
- Safefree(mg->mg_ptr);
- if (mg->mg_flags & MGf_REFCOUNTED)
- SvREFCNT_dec(mg->mg_obj);
- Safefree(mg);
- }
- SvMAGIC(sv) = 0;
- return 0;
- }
-
- #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
- #include <signal.h>
- #endif
-
- U32
- magic_len(sv, mg)
- SV *sv;
- MAGIC *mg;
- {
- register I32 paren;
- register char *s;
- register I32 i;
- char *t;
-
- switch (*mg->mg_ptr) {
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': case '&':
- if (curpm) {
- paren = atoi(mg->mg_ptr);
- getparen:
- if (curpm->op_pmregexp &&
- paren <= curpm->op_pmregexp->nparens &&
- (s = curpm->op_pmregexp->startp[paren]) &&
- (t = curpm->op_pmregexp->endp[paren]) ) {
- i = t - s;
- if (i >= 0)
- return i;
- }
- }
- return 0;
- break;
- case '+':
- if (curpm) {
- paren = curpm->op_pmregexp->lastparen;
- if (!paren)
- return 0;
- goto getparen;
- }
- return 0;
- break;
- case '`':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->subbeg) ) {
- i = curpm->op_pmregexp->startp[0] - s;
- if (i >= 0)
- return i;
- }
- }
- return 0;
- case '\'':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->endp[0]) ) {
- return (STRLEN) (curpm->op_pmregexp->subend - s);
- }
- }
- return 0;
- case ',':
- return (STRLEN)ofslen;
- case '\\':
- return (STRLEN)orslen;
- }
- magic_get(sv,mg);
- if (!SvPOK(sv) && SvNIOK(sv))
- sv_2pv(sv, &na);
- if (SvPOK(sv))
- return SvCUR(sv);
- return 0;
- }
-
- int
- magic_get(sv, mg)
- SV *sv;
- MAGIC *mg;
- {
- register I32 paren;
- register char *s;
- register I32 i;
- char *t;
-
- switch (*mg->mg_ptr) {
- case '\001': /* ^A */
- sv_setsv(sv, bodytarget);
- break;
- case '\004': /* ^D */
- sv_setiv(sv,(I32)(debug & 32767));
- break;
- case '\006': /* ^F */
- sv_setiv(sv,(I32)maxsysfd);
- break;
- case '\010': /* ^H */
- sv_setiv(sv,(I32)hints);
- break;
- case '\t': /* ^I */
- if (inplace)
- sv_setpv(sv, inplace);
- else
- sv_setsv(sv,&sv_undef);
- break;
- case '\020': /* ^P */
- sv_setiv(sv,(I32)perldb);
- break;
- case '\024': /* ^T */
- sv_setiv(sv,(I32)basetime);
- break;
- case '\027': /* ^W */
- sv_setiv(sv,(I32)dowarn);
- break;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': case '&':
- if (curpm) {
- paren = atoi(GvENAME(mg->mg_obj));
- getparen:
- if (curpm->op_pmregexp &&
- paren <= curpm->op_pmregexp->nparens &&
- (s = curpm->op_pmregexp->startp[paren]) &&
- (t = curpm->op_pmregexp->endp[paren]) ) {
- i = t - s;
- if (i >= 0) {
- MAGIC *tmg;
- sv_setpvn(sv,s,i);
- if (tainting && (tmg = mg_find(sv,'t')))
- tmg->mg_len = 0; /* guarantee $1 untainted */
- break;
- }
- }
- }
- sv_setsv(sv,&sv_undef);
- break;
- case '+':
- if (curpm) {
- paren = curpm->op_pmregexp->lastparen;
- if (paren)
- goto getparen;
- }
- sv_setsv(sv,&sv_undef);
- break;
- case '`':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->subbeg) ) {
- i = curpm->op_pmregexp->startp[0] - s;
- if (i >= 0) {
- sv_setpvn(sv,s,i);
- break;
- }
- }
- }
- sv_setsv(sv,&sv_undef);
- break;
- case '\'':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->endp[0]) ) {
- sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
- break;
- }
- }
- sv_setsv(sv,&sv_undef);
- break;
- case '.':
- #ifndef lint
- if (GvIO(last_in_gv)) {
- sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
- }
- #endif
- break;
- case '?':
- sv_setiv(sv,(I32)statusvalue);
- break;
- case '^':
- s = IoTOP_NAME(GvIOp(defoutgv));
- if (s)
- sv_setpv(sv,s);
- else {
- sv_setpv(sv,GvENAME(defoutgv));
- sv_catpv(sv,"_TOP");
- }
- break;
- case '~':
- s = IoFMT_NAME(GvIOp(defoutgv));
- if (!s)
- s = GvENAME(defoutgv);
- sv_setpv(sv,s);
- break;
- #ifndef lint
- case '=':
- sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
- break;
- case '-':
- sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
- break;
- case '%':
- sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
- break;
- #endif
- case ':':
- break;
- case '/':
- break;
- case '[':
- sv_setiv(sv,(I32)curcop->cop_arybase);
- break;
- case '|':
- sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
- break;
- case ',':
- sv_setpvn(sv,ofs,ofslen);
- break;
- case '\\':
- sv_setpvn(sv,ors,orslen);
- break;
- case '#':
- sv_setpv(sv,ofmt);
- break;
- case '!':
- sv_setnv(sv,(double)errno);
- sv_setpv(sv, errno ? Strerror(errno) : "");
- SvNOK_on(sv); /* what a wonderful hack! */
- break;
- case '<':
- sv_setiv(sv,(I32)uid);
- break;
- case '>':
- sv_setiv(sv,(I32)euid);
- break;
- case '(':
- s = buf;
- (void)sprintf(s,"%d",(int)gid);
- goto add_groups;
- case ')':
- s = buf;
- (void)sprintf(s,"%d",(int)egid);
- add_groups:
- while (*s) s++;
- #ifdef HAS_GETGROUPS
- #ifndef NGROUPS
- #define NGROUPS 32
- #endif
- {
- Groups_t gary[NGROUPS];
-
- i = getgroups(NGROUPS,gary);
- while (--i >= 0) {
- (void)sprintf(s," %ld", (long)gary[i]);
- while (*s) s++;
- }
- }
- #endif
- sv_setpv(sv,buf);
- break;
- case '*':
- break;
- case '0':
- break;
- }
- return 0;
- }
-
- int
- magic_getuvar(sv, mg)
- SV *sv;
- MAGIC *mg;
- {
- struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
-
- if (uf && uf->uf_val)
- (*uf->uf_val)(uf->uf_index, sv);
- return 0;
- }
-
- int
- magic_setenv(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- register char *s;
- STRLEN len;
- I32 i;
- s = SvPV(sv,len);
- my_setenv(mg->mg_ptr,s);
- #ifdef DYNAMIC_ENV_FETCH
- /* We just undefd an environment var. Is a replacement */
- /* waiting in the wings? */
- if (!len) {
- SV **envsvp;
- if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE))
- s = SvPV(*envsvp,len);
- }
- #endif
- /* And you'll never guess what the dog had */
- /* in its mouth... */
- if (tainting) {
- if (s && strEQ(mg->mg_ptr,"PATH")) {
- char *strend = s + len;
-
- while (s < strend) {
- s = cpytill(tokenbuf,s,strend,':',&i);
- s++;
- if (*tokenbuf != '/'
- || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
- MgTAINTEDDIR_on(mg);
- }
- }
- }
- return 0;
- }
-
- int
- magic_clearenv(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- my_setenv(mg->mg_ptr,Nullch);
- return 0;
- }
-
- int
- magic_setsig(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- register char *s;
- I32 i;
- SV** svp;
-
- s = mg->mg_ptr;
- if (*s == '_') {
- if (strEQ(s,"__DIE__"))
- svp = &diehook;
- else if (strEQ(s,"__WARN__"))
- svp = &warnhook;
- else if (strEQ(s,"__PARSE__"))
- svp = &parsehook;
- else
- croak("No such hook: %s", s);
- i = 0;
- }
- else {
- i = whichsig(s); /* ...no, a brick */
- if (!i) {
- if (dowarn || strEQ(s,"ALARM"))
- warn("No such signal: SIG%s", s);
- return 0;
- }
- }
- if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
- if (i)
- (void)signal(i,sighandler);
- else
- *svp = SvREFCNT_inc(sv);
- return 0;
- }
- s = SvPV_force(sv,na);
- if (strEQ(s,"IGNORE")) {
- if (i)
- (void)signal(i,SIG_IGN);
- else
- *svp = 0;
- }
- else if (strEQ(s,"DEFAULT") || !*s) {
- if (i)
- (void)signal(i,SIG_DFL);
- else
- *svp = 0;
- }
- else {
- if (!strchr(s,':') && !strchr(s,'\'')) {
- sprintf(tokenbuf, "main::%s",s);
- sv_setpv(sv,tokenbuf);
- }
- if (i)
- (void)signal(i,sighandler);
- else
- *svp = SvREFCNT_inc(sv);
- }
- return 0;
- }
-
- int
- magic_setisa(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- sub_generation++;
- return 0;
- }
-
- #ifdef OVERLOAD
-
- int
- magic_setamagic(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- /* HV_badAMAGIC_on(Sv_STASH(sv)); */
- amagic_generation++;
-
- return 0;
- }
- #endif /* OVERLOAD */
-
- static int
- magic_methpack(sv,mg,meth)
- SV* sv;
- MAGIC* mg;
- char *meth;
- {
- dSP;
-
- ENTER;
- SAVETMPS;
- PUSHMARK(sp);
- EXTEND(sp, 2);
- PUSHs(mg->mg_obj);
- if (mg->mg_ptr)
- PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
- else if (mg->mg_type == 'p')
- PUSHs(sv_2mortal(newSViv(mg->mg_len)));
- PUTBACK;
-
- if (perl_call_method(meth, G_SCALAR))
- sv_setsv(sv, *stack_sp--);
-
- FREETMPS;
- LEAVE;
- return 0;
- }
-
- int
- magic_getpack(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- magic_methpack(sv,mg,"FETCH");
- if (mg->mg_ptr)
- mg->mg_flags |= MGf_GSKIP;
- return 0;
- }
-
- int
- magic_setpack(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- dSP;
-
- PUSHMARK(sp);
- EXTEND(sp, 3);
- PUSHs(mg->mg_obj);
- if (mg->mg_ptr)
- PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
- else if (mg->mg_type == 'p')
- PUSHs(sv_2mortal(newSViv(mg->mg_len)));
- PUSHs(sv);
- PUTBACK;
-
- perl_call_method("STORE", G_SCALAR|G_DISCARD);
-
- return 0;
- }
-
- int
- magic_clearpack(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- return magic_methpack(sv,mg,"DELETE");
- }
-
- int magic_wipepack(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- dSP;
-
- PUSHMARK(sp);
- XPUSHs(mg->mg_obj);
- PUTBACK;
-
- perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
-
- return 0;
- }
-
- int
- magic_nextpack(sv,mg,key)
- SV* sv;
- MAGIC* mg;
- SV* key;
- {
- dSP;
- char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
-
- ENTER;
- SAVETMPS;
- PUSHMARK(sp);
- EXTEND(sp, 2);
- PUSHs(mg->mg_obj);
- if (SvOK(key))
- PUSHs(key);
- PUTBACK;
-
- if (perl_call_method(meth, G_SCALAR))
- sv_setsv(key, *stack_sp--);
-
- FREETMPS;
- LEAVE;
- return 0;
- }
-
- int
- magic_existspack(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- return magic_methpack(sv,mg,"EXISTS");
- }
-
- int
- magic_setdbline(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- OP *o;
- I32 i;
- GV* gv;
- SV** svp;
-
- gv = DBline;
- i = SvTRUE(sv);
- svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
- if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
- o->op_private = i;
- else
- warn("Can't break at that line\n");
- return 0;
- }
-
- int
- magic_getarylen(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
- return 0;
- }
-
- int
- magic_setarylen(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
- return 0;
- }
-
- int
- magic_getpos(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- SV* lsv = LvTARG(sv);
-
- if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
- mg = mg_find(lsv, 'g');
- if (mg && mg->mg_len >= 0) {
- sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
- return 0;
- }
- }
- (void)SvOK_off(sv);
- return 0;
- }
-
- int
- magic_setpos(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- SV* lsv = LvTARG(sv);
- SSize_t pos;
- STRLEN len;
-
- mg = 0;
-
- if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
- mg = mg_find(lsv, 'g');
- if (!mg) {
- if (!SvOK(sv))
- return 0;
- sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
- mg = mg_find(lsv, 'g');
- }
- else if (!SvOK(sv)) {
- mg->mg_len = -1;
- return 0;
- }
- len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
-
- pos = SvIV(sv) - curcop->cop_arybase;
- if (pos < 0) {
- pos += len;
- if (pos < 0)
- pos = 0;
- }
- else if (pos > len)
- pos = len;
- mg->mg_len = pos;
-
- return 0;
- }
-
- int
- magic_getglob(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
- return 0;
- }
-
- int
- magic_setglob(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- register char *s;
- GV* gv;
-
- if (!SvOK(sv))
- return 0;
- s = SvPV(sv, na);
- if (*s == '*' && s[1])
- s++;
- gv = gv_fetchpv(s,TRUE, SVt_PVGV);
- if (sv == (SV*)gv)
- return 0;
- if (GvGP(sv))
- gp_free(sv);
- GvGP(sv) = gp_ref(GvGP(gv));
- if (!GvAV(gv))
- gv_AVadd(gv);
- if (!GvHV(gv))
- gv_HVadd(gv);
- if (!GvIOp(gv))
- GvIOp(gv) = newIO();
- return 0;
- }
-
- int
- magic_setsubstr(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- STRLEN len;
- char *tmps = SvPV(sv,len);
- sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
- return 0;
- }
-
- int
- magic_gettaint(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- if (mg->mg_len & 1)
- tainted = TRUE;
- else if (mg->mg_len & 2 && mg->mg_obj == sv) /* kludge */
- tainted = TRUE;
- return 0;
- }
-
- int
- magic_settaint(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- if (localizing) {
- if (localizing == 1)
- mg->mg_len <<= 1;
- else
- mg->mg_len >>= 1;
- }
- else if (tainted)
- mg->mg_len |= 1;
- else
- mg->mg_len &= ~1;
- return 0;
- }
-
- int
- magic_setvec(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- do_vecset(sv); /* XXX slurp this routine */
- return 0;
- }
-
- int
- magic_setmglob(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- mg->mg_len = -1;
- return 0;
- }
-
- int
- magic_setbm(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- sv_unmagic(sv, 'B');
- SvVALID_off(sv);
- return 0;
- }
-
- int
- magic_setuvar(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
-
- if (uf && uf->uf_set)
- (*uf->uf_set)(uf->uf_index, sv);
- return 0;
- }
-
- int
- magic_set(sv,mg)
- SV* sv;
- MAGIC* mg;
- {
- register char *s;
- I32 i;
- STRLEN len;
- switch (*mg->mg_ptr) {
- case '\001': /* ^A */
- sv_setsv(bodytarget, sv);
- break;
- case '\004': /* ^D */
- debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
- DEBUG_x(dump_all());
- break;
- case '\006': /* ^F */
- maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- break;
- case '\010': /* ^H */
- hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- break;
- case '\t': /* ^I */
- if (inplace)
- Safefree(inplace);
- if (SvOK(sv))
- inplace = savepv(SvPV(sv,na));
- else
- inplace = Nullch;
- break;
- case '\020': /* ^P */
- i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (i != perldb) {
- if (perldb)
- oldlastpm = curpm;
- else
- curpm = oldlastpm;
- }
- perldb = i;
- break;
- case '\024': /* ^T */
- basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- break;
- case '\027': /* ^W */
- dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- break;
- case '.':
- if (localizing) {
- if (localizing == 1)
- save_sptr((SV**)&last_in_gv);
- }
- else if (SvOK(sv))
- IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
- break;
- case '^':
- Safefree(IoTOP_NAME(GvIOp(defoutgv)));
- IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
- IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
- break;
- case '~':
- Safefree(IoFMT_NAME(GvIOp(defoutgv)));
- IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
- IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
- break;
- case '=':
- IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- break;
- case '-':
- IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
- IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
- break;
- case '%':
- IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- break;
- case '|':
- IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
- if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
- IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
- }
- break;
- case '*':
- i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- multiline = (i != 0);
- break;
- case '/':
- if (SvOK(sv)) {
- nrs = rs = SvPV_force(sv,rslen);
- nrslen = rslen;
- if (rspara = !rslen) {
- nrs = rs = "\n\n";
- nrslen = rslen = 2;
- }
- nrschar = rschar = rs[rslen - 1];
- }
- else {
- nrschar = rschar = 0777; /* fake a non-existent char */
- nrslen = rslen = 1;
- }
- break;
- case '\\':
- if (ors)
- Safefree(ors);
- ors = savepv(SvPV(sv,orslen));
- break;
- case ',':
- if (ofs)
- Safefree(ofs);
- ofs = savepv(SvPV(sv, ofslen));
- break;
- case '#':
- if (ofmt)
- Safefree(ofmt);
- ofmt = savepv(SvPV(sv,na));
- break;
- case '[':
- compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- break;
- case '?':
- statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
- break;
- case '!':
- SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SS$_ABORT); /* will anyone ever use this? */
- break;
- case '<':
- uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (delaymagic) {
- delaymagic |= DM_RUID;
- break; /* don't do magic till later */
- }
- #ifdef HAS_SETRUID
- (void)setruid((Uid_t)uid);
- #else
- #ifdef HAS_SETREUID
- (void)setreuid((Uid_t)uid, (Uid_t)-1);
- #else
- #ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
- #else
- if (uid == euid) /* special case $< = $> */
- (void)setuid(uid);
- else {
- uid = (I32)getuid();
- croak("setruid() not implemented");
- }
- #endif
- #endif
- #endif
- uid = (I32)getuid();
- tainting |= (euid != uid || egid != gid);
- break;
- case '>':
- euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (delaymagic) {
- delaymagic |= DM_EUID;
- break; /* don't do magic till later */
- }
- #ifdef HAS_SETEUID
- (void)seteuid((Uid_t)euid);
- #else
- #ifdef HAS_SETREUID
- (void)setreuid((Uid_t)-1, (Uid_t)euid);
- #else
- #ifdef HAS_SETRESUID
- (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
- #else
- if (euid == uid) /* special case $> = $< */
- setuid(euid);
- else {
- euid = (I32)geteuid();
- croak("seteuid() not implemented");
- }
- #endif
- #endif
- #endif
- euid = (I32)geteuid();
- tainting |= (euid != uid || egid != gid);
- break;
- case '(':
- gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (delaymagic) {
- delaymagic |= DM_RGID;
- break; /* don't do magic till later */
- }
- #ifdef HAS_SETRGID
- (void)setrgid((Gid_t)gid);
- #else
- #ifdef HAS_SETREGID
- (void)setregid((Gid_t)gid, (Gid_t)-1);
- #else
- #ifdef HAS_SETRESGID
- (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
- #else
- if (gid == egid) /* special case $( = $) */
- (void)setgid(gid);
- else {
- gid = (I32)getgid();
- croak("setrgid() not implemented");
- }
- #endif
- #endif
- #endif
- gid = (I32)getgid();
- tainting |= (euid != uid || egid != gid);
- break;
- case ')':
- egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
- if (delaymagic) {
- delaymagic |= DM_EGID;
- break; /* don't do magic till later */
- }
- #ifdef HAS_SETEGID
- (void)setegid((Gid_t)egid);
- #else
- #ifdef HAS_SETREGID
- (void)setregid((Gid_t)-1, (Gid_t)egid);
- #else
- #ifdef HAS_SETRESGID
- (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
- #else
- if (egid == gid) /* special case $) = $( */
- (void)setgid(egid);
- else {
- egid = (I32)getegid();
- croak("setegid() not implemented");
- }
- #endif
- #endif
- #endif
- egid = (I32)getegid();
- tainting |= (euid != uid || egid != gid);
- break;
- case ':':
- chopset = SvPV_force(sv,na);
- break;
- case '0':
- if (!origalen) {
- s = origargv[0];
- s += strlen(s);
- /* See if all the arguments are contiguous in memory */
- for (i = 1; i < origargc; i++) {
- if (origargv[i] == s + 1)
- s += strlen(++s); /* this one is ok too */
- }
- if (origenviron[0] == s + 1) { /* can grab env area too? */
- my_setenv("NoNeSuCh", Nullch);
- /* force copy of environment */
- for (i = 0; origenviron[i]; i++)
- if (origenviron[i] == s + 1)
- s += strlen(++s);
- }
- origalen = s - origargv[0];
- }
- s = SvPV_force(sv,len);
- i = len;
- if (i >= origalen) {
- i = origalen;
- SvCUR_set(sv, i);
- *SvEND(sv) = '\0';
- Copy(s, origargv[0], i, char);
- }
- else {
- Copy(s, origargv[0], i, char);
- s = origargv[0]+i;
- *s++ = '\0';
- while (++i < origalen)
- *s++ = ' ';
- s = origargv[0]+i;
- for (i = 1; i < origargc; i++)
- origargv[i] = Nullch;
- }
- break;
- }
- return 0;
- }
-
- I32
- whichsig(sig)
- char *sig;
- {
- register char **sigv;
-
- for (sigv = sig_name+1; *sigv; sigv++)
- if (strEQ(sig,*sigv))
- return sigv - sig_name;
- #ifdef SIGCLD
- if (strEQ(sig,"CHLD"))
- return SIGCLD;
- #endif
- #ifdef SIGCHLD
- if (strEQ(sig,"CLD"))
- return SIGCHLD;
- #endif
- return 0;
- }
-
- Signal_t
- sighandler(sig)
- int sig;
- {
- dSP;
- GV *gv;
- HV *st;
- SV *sv;
- CV *cv;
- AV *oldstack;
-
- #ifdef OS2 /* or anybody else who requires SIG_ACK */
- signal(sig, SIG_ACK);
- #endif
-
- cv = sv_2cv(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
- TRUE),
- &st, &gv, TRUE);
- if (!cv || !CvROOT(cv) &&
- *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
-
- if (sig_name[sig][1] == 'H')
- cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
- &st, &gv, TRUE);
- else
- cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE),
- &st, &gv, TRUE);
- /* gag */
- }
- if (!cv || !CvROOT(cv)) {
- if (dowarn)
- warn("SIG%s handler \"%s\" not defined.\n",
- sig_name[sig], GvENAME(gv) );
- return;
- }
-
- oldstack = stack;
- if (stack != signalstack)
- AvFILL(signalstack) = 0;
- SWITCHSTACK(stack, signalstack);
-
- sv = sv_newmortal();
- sv_setpv(sv,sig_name[sig]);
- PUSHMARK(sp);
- PUSHs(sv);
- PUTBACK;
-
- perl_call_sv((SV*)cv, G_DISCARD);
-
- SWITCHSTACK(signalstack, oldstack);
-
- return;
- }
-