home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / perl / Perl / mg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-07  |  23.5 KB  |  1,295 lines

  1. /*    mg.c
  2.  *
  3.  *    Copyright (c) 1991-1994, Larry Wall
  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.  *
  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."
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "perl.h"
  17.  
  18. /* Omit -- it causes too much grief on mixed systems.
  19. #ifdef I_UNISTD
  20. # include <unistd.h>
  21. #endif
  22. */
  23.  
  24. void
  25. mg_magical(sv)
  26. SV* sv;
  27. {
  28.     MAGIC* mg;
  29.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  30.     MGVTBL* vtbl = mg->mg_virtual;
  31.     if (vtbl) {
  32.         if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
  33.         SvGMAGICAL_on(sv);
  34.         if (vtbl->svt_set)
  35.         SvSMAGICAL_on(sv);
  36.         if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)) || vtbl->svt_clear)
  37.         SvRMAGICAL_on(sv);
  38.     }
  39.     }
  40. }
  41.  
  42. int
  43. mg_get(sv)
  44. SV* sv;
  45. {
  46.     MAGIC* mg;
  47.     U32 savemagic = SvMAGICAL(sv) | SvREADONLY(sv);
  48.  
  49.     assert(SvGMAGICAL(sv));
  50.     SvMAGICAL_off(sv);
  51.     SvREADONLY_off(sv);
  52.     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  53.  
  54.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  55.     MGVTBL* vtbl = mg->mg_virtual;
  56.     if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
  57.         (*vtbl->svt_get)(sv, mg);
  58.         if (mg->mg_flags & MGf_GSKIP)
  59.         savemagic = 0;
  60.     }
  61.     }
  62.  
  63.     if (savemagic)
  64.     SvFLAGS(sv) |= savemagic;
  65.     else
  66.     mg_magical(sv);
  67.     if (SvGMAGICAL(sv))
  68.     SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  69.  
  70.     return 0;
  71. }
  72.  
  73. int
  74. mg_set(sv)
  75. SV* sv;
  76. {
  77.     MAGIC* mg;
  78.     MAGIC* nextmg;
  79.     U32 savemagic = SvMAGICAL(sv);
  80.  
  81.     SvMAGICAL_off(sv);
  82.  
  83.     for (mg = SvMAGIC(sv); mg; mg = nextmg) {
  84.     MGVTBL* vtbl = mg->mg_virtual;
  85.     nextmg = mg->mg_moremagic;    /* it may delete itself */
  86.     if (mg->mg_flags & MGf_GSKIP) {
  87.         mg->mg_flags &= ~MGf_GSKIP;    /* setting requires another read */
  88.         savemagic = 0;
  89.     }
  90.     if (vtbl && vtbl->svt_set)
  91.         (*vtbl->svt_set)(sv, mg);
  92.     }
  93.  
  94.     if (SvMAGIC(sv)) {
  95.     if (savemagic)
  96.         SvFLAGS(sv) |= savemagic;
  97.     else
  98.         mg_magical(sv);
  99.     if (SvGMAGICAL(sv))
  100.         SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  101.     }
  102.  
  103.     return 0;
  104. }
  105.  
  106. U32
  107. mg_len(sv)
  108. SV* sv;
  109. {
  110.     MAGIC* mg;
  111.     char *junk;
  112.     STRLEN len;
  113.  
  114.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  115.     MGVTBL* vtbl = mg->mg_virtual;
  116.     if (vtbl && vtbl->svt_len) {
  117.         U32 savemagic = SvMAGICAL(sv);
  118.  
  119.         SvMAGICAL_off(sv);
  120.         SvFLAGS(sv) |= (SvFLAGS(sv)&(SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  121.  
  122.         /* omit MGf_GSKIP -- not changed here */
  123.         len = (*vtbl->svt_len)(sv, mg);
  124.  
  125.         SvFLAGS(sv) |= savemagic;
  126.         if (SvGMAGICAL(sv))
  127.         SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  128.  
  129.         return len;
  130.     }
  131.     }
  132.  
  133.     junk = SvPV(sv, len);
  134.     return len;
  135. }
  136.  
  137. int
  138. mg_clear(sv)
  139. SV* sv;
  140. {
  141.     MAGIC* mg;
  142.     U32 savemagic = SvMAGICAL(sv);
  143.  
  144.     SvMAGICAL_off(sv);
  145.     SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
  146.  
  147.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  148.     MGVTBL* vtbl = mg->mg_virtual;
  149.     /* omit GSKIP -- never set here */
  150.     
  151.     if (vtbl && vtbl->svt_clear)
  152.         (*vtbl->svt_clear)(sv, mg);
  153.     }
  154.  
  155.     SvFLAGS(sv) |= savemagic;
  156.     if (SvGMAGICAL(sv))
  157.     SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
  158.  
  159.     return 0;
  160. }
  161.  
  162. MAGIC*
  163. mg_find(sv, type)
  164. SV* sv;
  165. int type;
  166. {
  167.     MAGIC* mg;
  168.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  169.     if (mg->mg_type == type)
  170.         return mg;
  171.     }
  172.     return 0;
  173. }
  174.  
  175. int
  176. mg_copy(sv, nsv, key, klen)
  177. SV* sv;
  178. SV* nsv;
  179. char *key;
  180. STRLEN klen;
  181. {
  182.     int count = 0;
  183.     MAGIC* mg;
  184.     for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
  185.     if (isUPPER(mg->mg_type)) {
  186.         sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
  187.         count++;
  188.     }
  189.     }
  190.     return count;
  191. }
  192.  
  193. int
  194. mg_free(sv)
  195. SV* sv;
  196. {
  197.     MAGIC* mg;
  198.     MAGIC* moremagic;
  199.     for (mg = SvMAGIC(sv); mg; mg = moremagic) {
  200.     MGVTBL* vtbl = mg->mg_virtual;
  201.     moremagic = mg->mg_moremagic;
  202.     if (vtbl && vtbl->svt_free)
  203.         (*vtbl->svt_free)(sv, mg);
  204.     if (mg->mg_ptr && mg->mg_type != 'g')
  205.         Safefree(mg->mg_ptr);
  206.     if (mg->mg_flags & MGf_REFCOUNTED)
  207.         SvREFCNT_dec(mg->mg_obj);
  208.     Safefree(mg);
  209.     }
  210.     SvMAGIC(sv) = 0;
  211.     return 0;
  212. }
  213.  
  214. #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
  215. #include <signal.h>
  216. #endif
  217.  
  218. U32
  219. magic_len(sv, mg)
  220. SV *sv;
  221. MAGIC *mg;
  222. {
  223.     register I32 paren;
  224.     register char *s;
  225.     register I32 i;
  226.     char *t;
  227.  
  228.     switch (*mg->mg_ptr) {
  229.     case '1': case '2': case '3': case '4':
  230.     case '5': case '6': case '7': case '8': case '9': case '&':
  231.     if (curpm) {
  232.         paren = atoi(mg->mg_ptr);
  233.       getparen:
  234.         if (curpm->op_pmregexp &&
  235.           paren <= curpm->op_pmregexp->nparens &&
  236.           (s = curpm->op_pmregexp->startp[paren]) &&
  237.           (t = curpm->op_pmregexp->endp[paren]) ) {
  238.         i = t - s;
  239.         if (i >= 0)
  240.             return i;
  241.         }
  242.     }
  243.     return 0;
  244.     break;
  245.     case '+':
  246.     if (curpm) {
  247.         paren = curpm->op_pmregexp->lastparen;
  248.         if (!paren)
  249.         return 0;
  250.         goto getparen;
  251.     }
  252.     return 0;
  253.     break;
  254.     case '`':
  255.     if (curpm) {
  256.         if (curpm->op_pmregexp &&
  257.           (s = curpm->op_pmregexp->subbeg) ) {
  258.         i = curpm->op_pmregexp->startp[0] - s;
  259.         if (i >= 0)
  260.             return i;
  261.         }
  262.     }
  263.     return 0;
  264.     case '\'':
  265.     if (curpm) {
  266.         if (curpm->op_pmregexp &&
  267.           (s = curpm->op_pmregexp->endp[0]) ) {
  268.         return (STRLEN) (curpm->op_pmregexp->subend - s);
  269.         }
  270.     }
  271.     return 0;
  272.     case ',':
  273.     return (STRLEN)ofslen;
  274.     case '\\':
  275.     return (STRLEN)orslen;
  276.     }
  277.     magic_get(sv,mg);
  278.     if (!SvPOK(sv) && SvNIOK(sv))
  279.     sv_2pv(sv, &na);
  280.     if (SvPOK(sv))
  281.     return SvCUR(sv);
  282.     return 0;
  283. }
  284.  
  285. int
  286. magic_get(sv, mg)
  287. SV *sv;
  288. MAGIC *mg;
  289. {
  290.     register I32 paren;
  291.     register char *s;
  292.     register I32 i;
  293.     char *t;
  294.  
  295.     switch (*mg->mg_ptr) {
  296.     case '\001':        /* ^A */
  297.     sv_setsv(sv, bodytarget);
  298.     break;
  299.     case '\004':        /* ^D */
  300.     sv_setiv(sv,(I32)(debug & 32767));
  301.     break;
  302.     case '\006':        /* ^F */
  303.     sv_setiv(sv,(I32)maxsysfd);
  304.     break;
  305.     case '\010':        /* ^H */
  306.     sv_setiv(sv,(I32)hints);
  307.     break;
  308.     case '\t':            /* ^I */
  309.     if (inplace)
  310.         sv_setpv(sv, inplace);
  311.     else
  312.         sv_setsv(sv,&sv_undef);
  313.     break;
  314.     case '\020':        /* ^P */
  315.     sv_setiv(sv,(I32)perldb);
  316.     break;
  317.     case '\024':        /* ^T */
  318.     sv_setiv(sv,(I32)basetime);
  319.     break;
  320.     case '\027':        /* ^W */
  321.     sv_setiv(sv,(I32)dowarn);
  322.     break;
  323.     case '1': case '2': case '3': case '4':
  324.     case '5': case '6': case '7': case '8': case '9': case '&':
  325.     if (curpm) {
  326.         paren = atoi(GvENAME(mg->mg_obj));
  327.       getparen:
  328.         if (curpm->op_pmregexp &&
  329.           paren <= curpm->op_pmregexp->nparens &&
  330.           (s = curpm->op_pmregexp->startp[paren]) &&
  331.           (t = curpm->op_pmregexp->endp[paren]) ) {
  332.         i = t - s;
  333.         if (i >= 0) {
  334.             MAGIC *tmg;
  335.             sv_setpvn(sv,s,i);
  336.             if (tainting && (tmg = mg_find(sv,'t')))
  337.             tmg->mg_len = 0;    /* guarantee $1 untainted */
  338.             break;
  339.         }
  340.         }
  341.     }
  342.     sv_setsv(sv,&sv_undef);
  343.     break;
  344.     case '+':
  345.     if (curpm) {
  346.         paren = curpm->op_pmregexp->lastparen;
  347.         if (paren)
  348.         goto getparen;
  349.     }
  350.     sv_setsv(sv,&sv_undef);
  351.     break;
  352.     case '`':
  353.     if (curpm) {
  354.         if (curpm->op_pmregexp &&
  355.           (s = curpm->op_pmregexp->subbeg) ) {
  356.         i = curpm->op_pmregexp->startp[0] - s;
  357.         if (i >= 0) {
  358.             sv_setpvn(sv,s,i);
  359.             break;
  360.         }
  361.         }
  362.     }
  363.     sv_setsv(sv,&sv_undef);
  364.     break;
  365.     case '\'':
  366.     if (curpm) {
  367.         if (curpm->op_pmregexp &&
  368.           (s = curpm->op_pmregexp->endp[0]) ) {
  369.         sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
  370.         break;
  371.         }
  372.     }
  373.     sv_setsv(sv,&sv_undef);
  374.     break;
  375.     case '.':
  376. #ifndef lint
  377.     if (GvIO(last_in_gv)) {
  378.         sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv)));
  379.     }
  380. #endif
  381.     break;
  382.     case '?':
  383.     sv_setiv(sv,(I32)statusvalue);
  384.     break;
  385.     case '^':
  386.     s = IoTOP_NAME(GvIOp(defoutgv));
  387.     if (s)
  388.         sv_setpv(sv,s);
  389.     else {
  390.         sv_setpv(sv,GvENAME(defoutgv));
  391.         sv_catpv(sv,"_TOP");
  392.     }
  393.     break;
  394.     case '~':
  395.     s = IoFMT_NAME(GvIOp(defoutgv));
  396.     if (!s)
  397.         s = GvENAME(defoutgv);
  398.     sv_setpv(sv,s);
  399.     break;
  400. #ifndef lint
  401.     case '=':
  402.     sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv)));
  403.     break;
  404.     case '-':
  405.     sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv)));
  406.     break;
  407.     case '%':
  408.     sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv)));
  409.     break;
  410. #endif
  411.     case ':':
  412.     break;
  413.     case '/':
  414.     break;
  415.     case '[':
  416.     sv_setiv(sv,(I32)curcop->cop_arybase);
  417.     break;
  418.     case '|':
  419.     sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 );
  420.     break;
  421.     case ',':
  422.     sv_setpvn(sv,ofs,ofslen);
  423.     break;
  424.     case '\\':
  425.     sv_setpvn(sv,ors,orslen);
  426.     break;
  427.     case '#':
  428.     sv_setpv(sv,ofmt);
  429.     break;
  430.     case '!':
  431.     sv_setnv(sv,(double)errno);
  432.     sv_setpv(sv, errno ? Strerror(errno) : "");
  433.     SvNOK_on(sv);    /* what a wonderful hack! */
  434.     break;
  435.     case '<':
  436.     sv_setiv(sv,(I32)uid);
  437.     break;
  438.     case '>':
  439.     sv_setiv(sv,(I32)euid);
  440.     break;
  441.     case '(':
  442.     s = buf;
  443.     (void)sprintf(s,"%d",(int)gid);
  444.     goto add_groups;
  445.     case ')':
  446.     s = buf;
  447.     (void)sprintf(s,"%d",(int)egid);
  448.       add_groups:
  449.     while (*s) s++;
  450. #ifdef HAS_GETGROUPS
  451. #ifndef NGROUPS
  452. #define NGROUPS 32
  453. #endif
  454.     {
  455.         Groups_t gary[NGROUPS];
  456.  
  457.         i = getgroups(NGROUPS,gary);
  458.         while (--i >= 0) {
  459.         (void)sprintf(s," %ld", (long)gary[i]);
  460.         while (*s) s++;
  461.         }
  462.     }
  463. #endif
  464.     sv_setpv(sv,buf);
  465.     break;
  466.     case '*':
  467.     break;
  468.     case '0':
  469.     break;
  470.     }
  471.     return 0;
  472. }
  473.  
  474. int
  475. magic_getuvar(sv, mg)
  476. SV *sv;
  477. MAGIC *mg;
  478. {
  479.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  480.  
  481.     if (uf && uf->uf_val)
  482.     (*uf->uf_val)(uf->uf_index, sv);
  483.     return 0;
  484. }
  485.  
  486. int
  487. magic_setenv(sv,mg)
  488. SV* sv;
  489. MAGIC* mg;
  490. {
  491.     register char *s;
  492.     STRLEN len;
  493.     I32 i;
  494.     s = SvPV(sv,len);
  495.     my_setenv(mg->mg_ptr,s);
  496. #ifdef DYNAMIC_ENV_FETCH
  497.      /* We just undefd an environment var.  Is a replacement */
  498.      /* waiting in the wings? */
  499.     if (!len) {
  500.     SV **envsvp;
  501.     if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE))
  502.         s = SvPV(*envsvp,len);
  503.     }
  504. #endif
  505.                 /* And you'll never guess what the dog had */
  506.                 /*   in its mouth... */
  507.     if (tainting) {
  508.     if (s && strEQ(mg->mg_ptr,"PATH")) {
  509.         char *strend = s + len;
  510.  
  511.         while (s < strend) {
  512.         s = cpytill(tokenbuf,s,strend,':',&i);
  513.         s++;
  514.         if (*tokenbuf != '/'
  515.           || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
  516.             MgTAINTEDDIR_on(mg);
  517.         }
  518.     }
  519.     }
  520.     return 0;
  521. }
  522.  
  523. int
  524. magic_clearenv(sv,mg)
  525. SV* sv;
  526. MAGIC* mg;
  527. {
  528.     my_setenv(mg->mg_ptr,Nullch);
  529.     return 0;
  530. }
  531.  
  532. int
  533. magic_setsig(sv,mg)
  534. SV* sv;
  535. MAGIC* mg;
  536. {
  537.     register char *s;
  538.     I32 i;
  539.     SV** svp;
  540.  
  541.     s = mg->mg_ptr;
  542.     if (*s == '_') {
  543.     if (strEQ(s,"__DIE__"))
  544.         svp = &diehook;
  545.     else if (strEQ(s,"__WARN__"))
  546.         svp = &warnhook;
  547.     else if (strEQ(s,"__PARSE__"))
  548.         svp = &parsehook;
  549.     else
  550.         croak("No such hook: %s", s);
  551.     i = 0;
  552.     }
  553.     else {
  554.     i = whichsig(s);    /* ...no, a brick */
  555.     if (!i) {
  556.         if (dowarn || strEQ(s,"ALARM"))
  557.         warn("No such signal: SIG%s", s);
  558.         return 0;
  559.     }
  560.     }
  561.     if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
  562.     if (i)
  563.         (void)signal(i,sighandler);
  564.     else
  565.         *svp = SvREFCNT_inc(sv);
  566.     return 0;
  567.     }
  568.     s = SvPV_force(sv,na);
  569.     if (strEQ(s,"IGNORE")) {
  570.     if (i)
  571.         (void)signal(i,SIG_IGN);
  572.     else
  573.         *svp = 0;
  574.     }
  575.     else if (strEQ(s,"DEFAULT") || !*s) {
  576.     if (i)
  577.         (void)signal(i,SIG_DFL);
  578.     else
  579.         *svp = 0;
  580.     }
  581.     else {
  582.     if (!strchr(s,':') && !strchr(s,'\'')) {
  583.         sprintf(tokenbuf, "main::%s",s);
  584.         sv_setpv(sv,tokenbuf);
  585.     }
  586.     if (i)
  587.         (void)signal(i,sighandler);
  588.     else
  589.         *svp = SvREFCNT_inc(sv);
  590.     }
  591.     return 0;
  592. }
  593.  
  594. int
  595. magic_setisa(sv,mg)
  596. SV* sv;
  597. MAGIC* mg;
  598. {
  599.     sub_generation++;
  600.     return 0;
  601. }
  602.  
  603. #ifdef OVERLOAD
  604.  
  605. int
  606. magic_setamagic(sv,mg)
  607. SV* sv;
  608. MAGIC* mg;
  609. {
  610.     /* HV_badAMAGIC_on(Sv_STASH(sv)); */
  611.     amagic_generation++;
  612.  
  613.     return 0;
  614. }
  615. #endif /* OVERLOAD */
  616.  
  617. static int
  618. magic_methpack(sv,mg,meth)
  619. SV* sv;
  620. MAGIC* mg;
  621. char *meth;
  622. {
  623.     dSP;
  624.  
  625.     ENTER;
  626.     SAVETMPS;
  627.     PUSHMARK(sp);
  628.     EXTEND(sp, 2);
  629.     PUSHs(mg->mg_obj);
  630.     if (mg->mg_ptr)
  631.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  632.     else if (mg->mg_type == 'p')
  633.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  634.     PUTBACK;
  635.  
  636.     if (perl_call_method(meth, G_SCALAR))
  637.     sv_setsv(sv, *stack_sp--);
  638.  
  639.     FREETMPS;
  640.     LEAVE;
  641.     return 0;
  642. }
  643.  
  644. int
  645. magic_getpack(sv,mg)
  646. SV* sv;
  647. MAGIC* mg;
  648. {
  649.     magic_methpack(sv,mg,"FETCH");
  650.     if (mg->mg_ptr)
  651.     mg->mg_flags |= MGf_GSKIP;
  652.     return 0;
  653. }
  654.  
  655. int
  656. magic_setpack(sv,mg)
  657. SV* sv;
  658. MAGIC* mg;
  659. {
  660.     dSP;
  661.  
  662.     PUSHMARK(sp);
  663.     EXTEND(sp, 3);
  664.     PUSHs(mg->mg_obj);
  665.     if (mg->mg_ptr)
  666.     PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len)));
  667.     else if (mg->mg_type == 'p')
  668.     PUSHs(sv_2mortal(newSViv(mg->mg_len)));
  669.     PUSHs(sv);
  670.     PUTBACK;
  671.  
  672.     perl_call_method("STORE", G_SCALAR|G_DISCARD);
  673.  
  674.     return 0;
  675. }
  676.  
  677. int
  678. magic_clearpack(sv,mg)
  679. SV* sv;
  680. MAGIC* mg;
  681. {
  682.     return magic_methpack(sv,mg,"DELETE");
  683. }
  684.  
  685. int magic_wipepack(sv,mg)
  686. SV* sv;
  687. MAGIC* mg;
  688. {
  689.     dSP;
  690.  
  691.     PUSHMARK(sp);
  692.     XPUSHs(mg->mg_obj);
  693.     PUTBACK;
  694.  
  695.     perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
  696.  
  697.     return 0;
  698. }
  699.  
  700. int
  701. magic_nextpack(sv,mg,key)
  702. SV* sv;
  703. MAGIC* mg;
  704. SV* key;
  705. {
  706.     dSP;
  707.     char *meth = SvOK(key) ? "NEXTKEY" : "FIRSTKEY";
  708.  
  709.     ENTER;
  710.     SAVETMPS;
  711.     PUSHMARK(sp);
  712.     EXTEND(sp, 2);
  713.     PUSHs(mg->mg_obj);
  714.     if (SvOK(key))
  715.     PUSHs(key);
  716.     PUTBACK;
  717.  
  718.     if (perl_call_method(meth, G_SCALAR))
  719.     sv_setsv(key, *stack_sp--);
  720.  
  721.     FREETMPS;
  722.     LEAVE;
  723.     return 0;
  724. }
  725.  
  726. int
  727. magic_existspack(sv,mg)
  728. SV* sv;
  729. MAGIC* mg;
  730. {
  731.     return magic_methpack(sv,mg,"EXISTS");
  732.  
  733. int
  734. magic_setdbline(sv,mg)
  735. SV* sv;
  736. MAGIC* mg;
  737. {
  738.     OP *o;
  739.     I32 i;
  740.     GV* gv;
  741.     SV** svp;
  742.  
  743.     gv = DBline;
  744.     i = SvTRUE(sv);
  745.     svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
  746.     if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp)))
  747.     o->op_private = i;
  748.     else
  749.     warn("Can't break at that line\n");
  750.     return 0;
  751. }
  752.  
  753. int
  754. magic_getarylen(sv,mg)
  755. SV* sv;
  756. MAGIC* mg;
  757. {
  758.     sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + curcop->cop_arybase);
  759.     return 0;
  760. }
  761.  
  762. int
  763. magic_setarylen(sv,mg)
  764. SV* sv;
  765. MAGIC* mg;
  766. {
  767.     av_fill((AV*)mg->mg_obj, SvIV(sv) - curcop->cop_arybase);
  768.     return 0;
  769. }
  770.  
  771. int
  772. magic_getpos(sv,mg)
  773. SV* sv;
  774. MAGIC* mg;
  775. {
  776.     SV* lsv = LvTARG(sv);
  777.     
  778.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) {
  779.     mg = mg_find(lsv, 'g');
  780.     if (mg && mg->mg_len >= 0) {
  781.         sv_setiv(sv, mg->mg_len + curcop->cop_arybase);
  782.         return 0;
  783.     }
  784.     }
  785.     (void)SvOK_off(sv);
  786.     return 0;
  787. }
  788.  
  789. int
  790. magic_setpos(sv,mg)
  791. SV* sv;
  792. MAGIC* mg;
  793. {
  794.     SV* lsv = LvTARG(sv);
  795.     SSize_t pos;
  796.     STRLEN len;
  797.  
  798.     mg = 0;
  799.     
  800.     if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv))
  801.     mg = mg_find(lsv, 'g');
  802.     if (!mg) {
  803.     if (!SvOK(sv))
  804.         return 0;
  805.     sv_magic(lsv, (SV*)0, 'g', Nullch, 0);
  806.     mg = mg_find(lsv, 'g');
  807.     }
  808.     else if (!SvOK(sv)) {
  809.     mg->mg_len = -1;
  810.     return 0;
  811.     }
  812.     len = SvPOK(lsv) ? SvCUR(lsv) : sv_len(lsv);
  813.  
  814.     pos = SvIV(sv) - curcop->cop_arybase;
  815.     if (pos < 0) {
  816.     pos += len;
  817.     if (pos < 0)
  818.         pos = 0;
  819.     }
  820.     else if (pos > len)
  821.     pos = len;
  822.     mg->mg_len = pos;
  823.  
  824.     return 0;
  825. }
  826.  
  827. int
  828. magic_getglob(sv,mg)
  829. SV* sv;
  830. MAGIC* mg;
  831. {
  832.     gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
  833.     return 0;
  834. }
  835.  
  836. int
  837. magic_setglob(sv,mg)
  838. SV* sv;
  839. MAGIC* mg;
  840. {
  841.     register char *s;
  842.     GV* gv;
  843.  
  844.     if (!SvOK(sv))
  845.     return 0;
  846.     s = SvPV(sv, na);
  847.     if (*s == '*' && s[1])
  848.     s++;
  849.     gv = gv_fetchpv(s,TRUE, SVt_PVGV);
  850.     if (sv == (SV*)gv)
  851.     return 0;
  852.     if (GvGP(sv))
  853.     gp_free(sv);
  854.     GvGP(sv) = gp_ref(GvGP(gv));
  855.     if (!GvAV(gv))
  856.     gv_AVadd(gv);
  857.     if (!GvHV(gv))
  858.     gv_HVadd(gv);
  859.     if (!GvIOp(gv))
  860.     GvIOp(gv) = newIO();
  861.     return 0;
  862. }
  863.  
  864. int
  865. magic_setsubstr(sv,mg)
  866. SV* sv;
  867. MAGIC* mg;
  868. {
  869.     STRLEN len;
  870.     char *tmps = SvPV(sv,len);
  871.     sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps, len);
  872.     return 0;
  873. }
  874.  
  875. int
  876. magic_gettaint(sv,mg)
  877. SV* sv;
  878. MAGIC* mg;
  879. {
  880.     if (mg->mg_len & 1)
  881.     tainted = TRUE;
  882.     else if (mg->mg_len & 2 && mg->mg_obj == sv)    /* kludge */
  883.     tainted = TRUE;
  884.     return 0;
  885. }
  886.  
  887. int
  888. magic_settaint(sv,mg)
  889. SV* sv;
  890. MAGIC* mg;
  891. {
  892.     if (localizing) {
  893.     if (localizing == 1)
  894.         mg->mg_len <<= 1;
  895.     else
  896.         mg->mg_len >>= 1;
  897.     }
  898.     else if (tainted)
  899.     mg->mg_len |= 1;
  900.     else
  901.     mg->mg_len &= ~1;
  902.     return 0;
  903. }
  904.  
  905. int
  906. magic_setvec(sv,mg)
  907. SV* sv;
  908. MAGIC* mg;
  909. {
  910.     do_vecset(sv);    /* XXX slurp this routine */
  911.     return 0;
  912. }
  913.  
  914. int
  915. magic_setmglob(sv,mg)
  916. SV* sv;
  917. MAGIC* mg;
  918. {
  919.     mg->mg_len = -1;
  920.     return 0;
  921. }
  922.  
  923. int
  924. magic_setbm(sv,mg)
  925. SV* sv;
  926. MAGIC* mg;
  927. {
  928.     sv_unmagic(sv, 'B');
  929.     SvVALID_off(sv);
  930.     return 0;
  931. }
  932.  
  933. int
  934. magic_setuvar(sv,mg)
  935. SV* sv;
  936. MAGIC* mg;
  937. {
  938.     struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
  939.  
  940.     if (uf && uf->uf_set)
  941.     (*uf->uf_set)(uf->uf_index, sv);
  942.     return 0;
  943. }
  944.  
  945. int
  946. magic_set(sv,mg)
  947. SV* sv;
  948. MAGIC* mg;
  949. {
  950.     register char *s;
  951.     I32 i;
  952.     STRLEN len;
  953.     switch (*mg->mg_ptr) {
  954.     case '\001':    /* ^A */
  955.     sv_setsv(bodytarget, sv);
  956.     break;
  957.     case '\004':    /* ^D */
  958.     debug = (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) | 0x80000000;
  959.     DEBUG_x(dump_all());
  960.     break;
  961.     case '\006':    /* ^F */
  962.     maxsysfd = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  963.     break;
  964.     case '\010':    /* ^H */
  965.     hints = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  966.     break;
  967.     case '\t':    /* ^I */
  968.     if (inplace)
  969.         Safefree(inplace);
  970.     if (SvOK(sv))
  971.         inplace = savepv(SvPV(sv,na));
  972.     else
  973.         inplace = Nullch;
  974.     break;
  975.     case '\020':    /* ^P */
  976.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  977.     if (i != perldb) {
  978.         if (perldb)
  979.         oldlastpm = curpm;
  980.         else
  981.         curpm = oldlastpm;
  982.     }
  983.     perldb = i;
  984.     break;
  985.     case '\024':    /* ^T */
  986.     basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  987.     break;
  988.     case '\027':    /* ^W */
  989.     dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  990.     break;
  991.     case '.':
  992.     if (localizing) {
  993.         if (localizing == 1)
  994.         save_sptr((SV**)&last_in_gv);
  995.     }
  996.     else if (SvOK(sv))
  997.         IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv);
  998.     break;
  999.     case '^':
  1000.     Safefree(IoTOP_NAME(GvIOp(defoutgv)));
  1001.     IoTOP_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  1002.     IoTOP_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  1003.     break;
  1004.     case '~':
  1005.     Safefree(IoFMT_NAME(GvIOp(defoutgv)));
  1006.     IoFMT_NAME(GvIOp(defoutgv)) = s = savepv(SvPV(sv,na));
  1007.     IoFMT_GV(GvIOp(defoutgv)) = gv_fetchpv(s,TRUE, SVt_PVIO);
  1008.     break;
  1009.     case '=':
  1010.     IoPAGE_LEN(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1011.     break;
  1012.     case '-':
  1013.     IoLINES_LEFT(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1014.     if (IoLINES_LEFT(GvIOp(defoutgv)) < 0L)
  1015.         IoLINES_LEFT(GvIOp(defoutgv)) = 0L;
  1016.     break;
  1017.     case '%':
  1018.     IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1019.     break;
  1020.     case '|':
  1021.     IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH;
  1022.     if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) {
  1023.         IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH;
  1024.     }
  1025.     break;
  1026.     case '*':
  1027.     i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1028.     multiline = (i != 0);
  1029.     break;
  1030.     case '/':
  1031.     if (SvOK(sv)) {
  1032.         nrs = rs = SvPV_force(sv,rslen);
  1033.         nrslen = rslen;
  1034.         if (rspara = !rslen) {
  1035.         nrs = rs = "\n\n";
  1036.         nrslen = rslen = 2;
  1037.         }
  1038.         nrschar = rschar = rs[rslen - 1];
  1039.     }
  1040.     else {
  1041.         nrschar = rschar = 0777;    /* fake a non-existent char */
  1042.         nrslen = rslen = 1;
  1043.     }
  1044.     break;
  1045.     case '\\':
  1046.     if (ors)
  1047.         Safefree(ors);
  1048.     ors = savepv(SvPV(sv,orslen));
  1049.     break;
  1050.     case ',':
  1051.     if (ofs)
  1052.         Safefree(ofs);
  1053.     ofs = savepv(SvPV(sv, ofslen));
  1054.     break;
  1055.     case '#':
  1056.     if (ofmt)
  1057.         Safefree(ofmt);
  1058.     ofmt = savepv(SvPV(sv,na));
  1059.     break;
  1060.     case '[':
  1061.     compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1062.     break;
  1063.     case '?':
  1064.     statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
  1065.     break;
  1066.     case '!':
  1067.     SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SS$_ABORT);        /* will anyone ever use this? */
  1068.     break;
  1069.     case '<':
  1070.     uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1071.     if (delaymagic) {
  1072.         delaymagic |= DM_RUID;
  1073.         break;                /* don't do magic till later */
  1074.     }
  1075. #ifdef HAS_SETRUID
  1076.     (void)setruid((Uid_t)uid);
  1077. #else
  1078. #ifdef HAS_SETREUID
  1079.     (void)setreuid((Uid_t)uid, (Uid_t)-1);
  1080. #else
  1081. #ifdef HAS_SETRESUID
  1082.       (void)setresuid((Uid_t)uid, (Uid_t)-1, (Uid_t)-1);
  1083. #else
  1084.     if (uid == euid)        /* special case $< = $> */
  1085.         (void)setuid(uid);
  1086.     else {
  1087.         uid = (I32)getuid();
  1088.         croak("setruid() not implemented");
  1089.     }
  1090. #endif
  1091. #endif
  1092. #endif
  1093.     uid = (I32)getuid();
  1094.     tainting |= (euid != uid || egid != gid);
  1095.     break;
  1096.     case '>':
  1097.     euid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1098.     if (delaymagic) {
  1099.         delaymagic |= DM_EUID;
  1100.         break;                /* don't do magic till later */
  1101.     }
  1102. #ifdef HAS_SETEUID
  1103.     (void)seteuid((Uid_t)euid);
  1104. #else
  1105. #ifdef HAS_SETREUID
  1106.     (void)setreuid((Uid_t)-1, (Uid_t)euid);
  1107. #else
  1108. #ifdef HAS_SETRESUID
  1109.     (void)setresuid((Uid_t)-1, (Uid_t)euid, (Uid_t)-1);
  1110. #else
  1111.     if (euid == uid)        /* special case $> = $< */
  1112.         setuid(euid);
  1113.     else {
  1114.         euid = (I32)geteuid();
  1115.         croak("seteuid() not implemented");
  1116.     }
  1117. #endif
  1118. #endif
  1119. #endif
  1120.     euid = (I32)geteuid();
  1121.     tainting |= (euid != uid || egid != gid);
  1122.     break;
  1123.     case '(':
  1124.     gid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1125.     if (delaymagic) {
  1126.         delaymagic |= DM_RGID;
  1127.         break;                /* don't do magic till later */
  1128.     }
  1129. #ifdef HAS_SETRGID
  1130.     (void)setrgid((Gid_t)gid);
  1131. #else
  1132. #ifdef HAS_SETREGID
  1133.     (void)setregid((Gid_t)gid, (Gid_t)-1);
  1134. #else
  1135. #ifdef HAS_SETRESGID
  1136.       (void)setresgid((Gid_t)gid, (Gid_t)-1, (Gid_t) 1);
  1137. #else
  1138.     if (gid == egid)            /* special case $( = $) */
  1139.         (void)setgid(gid);
  1140.     else {
  1141.         gid = (I32)getgid();
  1142.         croak("setrgid() not implemented");
  1143.     }
  1144. #endif
  1145. #endif
  1146. #endif
  1147.     gid = (I32)getgid();
  1148.     tainting |= (euid != uid || egid != gid);
  1149.     break;
  1150.     case ')':
  1151.     egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
  1152.     if (delaymagic) {
  1153.         delaymagic |= DM_EGID;
  1154.         break;                /* don't do magic till later */
  1155.     }
  1156. #ifdef HAS_SETEGID
  1157.     (void)setegid((Gid_t)egid);
  1158. #else
  1159. #ifdef HAS_SETREGID
  1160.     (void)setregid((Gid_t)-1, (Gid_t)egid);
  1161. #else
  1162. #ifdef HAS_SETRESGID
  1163.     (void)setresgid((Gid_t)-1, (Gid_t)egid, (Gid_t)-1);
  1164. #else
  1165.     if (egid == gid)            /* special case $) = $( */
  1166.         (void)setgid(egid);
  1167.     else {
  1168.         egid = (I32)getegid();
  1169.         croak("setegid() not implemented");
  1170.     }
  1171. #endif
  1172. #endif
  1173. #endif
  1174.     egid = (I32)getegid();
  1175.     tainting |= (euid != uid || egid != gid);
  1176.     break;
  1177.     case ':':
  1178.     chopset = SvPV_force(sv,na);
  1179.     break;
  1180.     case '0':
  1181.     if (!origalen) {
  1182.         s = origargv[0];
  1183.         s += strlen(s);
  1184.         /* See if all the arguments are contiguous in memory */
  1185.         for (i = 1; i < origargc; i++) {
  1186.         if (origargv[i] == s + 1)
  1187.             s += strlen(++s);    /* this one is ok too */
  1188.         }
  1189.         if (origenviron[0] == s + 1) {    /* can grab env area too? */
  1190.         my_setenv("NoNeSuCh", Nullch);
  1191.                         /* force copy of environment */
  1192.         for (i = 0; origenviron[i]; i++)
  1193.             if (origenviron[i] == s + 1)
  1194.             s += strlen(++s);
  1195.         }
  1196.         origalen = s - origargv[0];
  1197.     }
  1198.     s = SvPV_force(sv,len);
  1199.     i = len;
  1200.     if (i >= origalen) {
  1201.         i = origalen;
  1202.         SvCUR_set(sv, i);
  1203.         *SvEND(sv) = '\0';
  1204.         Copy(s, origargv[0], i, char);
  1205.     }
  1206.     else {
  1207.         Copy(s, origargv[0], i, char);
  1208.         s = origargv[0]+i;
  1209.         *s++ = '\0';
  1210.         while (++i < origalen)
  1211.         *s++ = ' ';
  1212.         s = origargv[0]+i;
  1213.         for (i = 1; i < origargc; i++)
  1214.         origargv[i] = Nullch;
  1215.     }
  1216.     break;
  1217.     }
  1218.     return 0;
  1219. }
  1220.  
  1221. I32
  1222. whichsig(sig)
  1223. char *sig;
  1224. {
  1225.     register char **sigv;
  1226.  
  1227.     for (sigv = sig_name+1; *sigv; sigv++)
  1228.     if (strEQ(sig,*sigv))
  1229.         return sigv - sig_name;
  1230. #ifdef SIGCLD
  1231.     if (strEQ(sig,"CHLD"))
  1232.     return SIGCLD;
  1233. #endif
  1234. #ifdef SIGCHLD
  1235.     if (strEQ(sig,"CLD"))
  1236.     return SIGCHLD;
  1237. #endif
  1238.     return 0;
  1239. }
  1240.  
  1241. Signal_t
  1242. sighandler(sig)
  1243. int sig;
  1244. {
  1245.     dSP;
  1246.     GV *gv;
  1247.     HV *st;
  1248.     SV *sv;
  1249.     CV *cv;
  1250.     AV *oldstack;
  1251.  
  1252. #ifdef OS2        /* or anybody else who requires SIG_ACK */
  1253.     signal(sig, SIG_ACK);
  1254. #endif
  1255.  
  1256.     cv = sv_2cv(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
  1257.               TRUE),
  1258.         &st, &gv, TRUE);
  1259.     if (!cv || !CvROOT(cv) &&
  1260.     *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
  1261.     
  1262.     if (sig_name[sig][1] == 'H')
  1263.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE),
  1264.             &st, &gv, TRUE);
  1265.     else
  1266.         cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE),
  1267.             &st, &gv, TRUE);
  1268.     /* gag */
  1269.     }
  1270.     if (!cv || !CvROOT(cv)) {
  1271.     if (dowarn)
  1272.         warn("SIG%s handler \"%s\" not defined.\n",
  1273.         sig_name[sig], GvENAME(gv) );
  1274.     return;
  1275.     }
  1276.  
  1277.     oldstack = stack;
  1278.     if (stack != signalstack)
  1279.     AvFILL(signalstack) = 0;
  1280.     SWITCHSTACK(stack, signalstack);
  1281.  
  1282.     sv = sv_newmortal();
  1283.     sv_setpv(sv,sig_name[sig]);
  1284.     PUSHMARK(sp);
  1285.     PUSHs(sv);
  1286.     PUTBACK;
  1287.  
  1288.     perl_call_sv((SV*)cv, G_DISCARD);
  1289.  
  1290.     SWITCHSTACK(signalstack, oldstack);
  1291.  
  1292.     return;
  1293. }
  1294.