home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / Perl5 / mg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-30  |  22.8 KB  |  1,255 lines  |  [TEXT/MPS ]

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