1 /* $RCSfile: hash.c,v $$Revision: 4.1 $$Date: 92/08/07 18:21:48 $
3 * Copyright (c) 1993, Larry Wall
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.
19 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
20 MGVTBL* vtbl = mg->mg_virtual;
21 if (vtbl && vtbl->svt_get)
22 (*vtbl->svt_get)(sv, mg);
32 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
33 MGVTBL* vtbl = mg->mg_virtual;
34 if (vtbl && vtbl->svt_set)
35 (*vtbl->svt_set)(sv, mg);
45 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
46 MGVTBL* vtbl = mg->mg_virtual;
47 if (vtbl && vtbl->svt_len)
48 return (*vtbl->svt_len)(sv, mg);
50 if (!SvPOK(sv) && SvNIOK(sv))
62 for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
63 MGVTBL* vtbl = mg->mg_virtual;
64 if (vtbl && vtbl->svt_clear)
65 (*vtbl->svt_clear)(sv, mg);
76 MAGIC** mgp = &SvMAGIC(sv);
77 for (mg = *mgp; mg; mg = *mgp) {
78 if (mg->mg_type == type) {
79 MGVTBL* vtbl = mg->mg_virtual;
80 *mgp = mg->mg_moremagic;
81 if (vtbl && vtbl->svt_free)
82 (*vtbl->svt_free)(sv, mg);
88 mgp = &mg->mg_moremagic;
99 for (mg = SvMAGIC(sv); mg; mg = moremagic) {
100 MGVTBL* vtbl = mg->mg_virtual;
101 moremagic = mg->mg_moremagic;
102 if (vtbl && vtbl->svt_free)
103 (*vtbl->svt_free)(sv, mg);
105 Safefree(mg->mg_ptr);
112 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
117 #define handlertype void
119 #define handlertype int
122 static handlertype sighandler();
133 switch (*mg->mg_ptr) {
134 case '\004': /* ^D */
135 sv_setiv(sv,(I32)(debug & 32767));
137 case '\006': /* ^F */
138 sv_setiv(sv,(I32)maxsysfd);
142 sv_setpv(sv, inplace);
144 sv_setsv(sv,&sv_undef);
146 case '\020': /* ^P */
147 sv_setiv(sv,(I32)perldb);
149 case '\024': /* ^T */
150 sv_setiv(sv,(I32)basetime);
152 case '\027': /* ^W */
153 sv_setiv(sv,(I32)dowarn);
155 case '1': case '2': case '3': case '4':
156 case '5': case '6': case '7': case '8': case '9': case '&':
158 paren = atoi(GvENAME(mg->mg_obj));
160 if (curpm->op_pmregexp &&
161 paren <= curpm->op_pmregexp->nparens &&
162 (s = curpm->op_pmregexp->startp[paren]) ) {
163 i = curpm->op_pmregexp->endp[paren] - s;
167 sv_setsv(sv,&sv_undef);
170 sv_setsv(sv,&sv_undef);
175 paren = curpm->op_pmregexp->lastparen;
181 if (curpm->op_pmregexp &&
182 (s = curpm->op_pmregexp->subbeg) ) {
183 i = curpm->op_pmregexp->startp[0] - s;
195 if (curpm->op_pmregexp &&
196 (s = curpm->op_pmregexp->endp[0]) ) {
197 sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
205 if (last_in_gv && GvIO(last_in_gv)) {
206 sv_setiv(sv,(I32)GvIO(last_in_gv)->lines);
211 sv_setiv(sv,(I32)statusvalue);
214 s = GvIO(defoutgv)->top_name;
218 sv_setpv(sv,GvENAME(defoutgv));
223 s = GvIO(defoutgv)->fmt_name;
225 s = GvENAME(defoutgv);
230 sv_setiv(sv,(I32)GvIO(defoutgv)->page_len);
233 sv_setiv(sv,(I32)GvIO(defoutgv)->lines_left);
236 sv_setiv(sv,(I32)GvIO(defoutgv)->page);
244 sv_setiv(sv,(I32)arybase);
248 GvIO(defoutgv) = newIO();
249 sv_setiv(sv, (GvIO(defoutgv)->flags & IOf_FLUSH) != 0 );
252 sv_setpvn(sv,ofs,ofslen);
255 sv_setpvn(sv,ors,orslen);
261 sv_setnv(sv,(double)errno);
262 sv_setpv(sv, errno ? strerror(errno) : "");
263 SvNOK_on(sv); /* what a wonderful hack! */
266 sv_setiv(sv,(I32)uid);
269 sv_setiv(sv,(I32)euid);
273 (void)sprintf(s,"%d",(int)gid);
277 (void)sprintf(s,"%d",(int)egid);
285 GROUPSTYPE gary[NGROUPS];
287 i = getgroups(NGROUPS,gary);
289 (void)sprintf(s," %ld", (long)gary[i]);
304 magic_getuvar(sv, mg)
308 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
310 if (uf && uf->uf_val)
311 (*uf->uf_val)(uf->uf_index, sv);
323 my_setenv(mg->mg_ptr,s);
324 /* And you'll never guess what the dog had */
325 /* in its mouth... */
327 if (s && strEQ(mg->mg_ptr,"PATH")) {
328 char *strend = SvEND(sv);
331 s = cpytill(tokenbuf,s,strend,':',&i);
334 || (stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
350 i = whichsig(mg->mg_ptr); /* ...no, a brick */
351 if (!i && (dowarn || strEQ(mg->mg_ptr,"ALARM")))
352 warn("No such signal: SIG%s", mg->mg_ptr);
353 if (strEQ(s,"IGNORE"))
355 (void)signal(i,SIG_IGN);
359 else if (strEQ(s,"DEFAULT") || !*s)
360 (void)signal(i,SIG_DFL);
362 (void)signal(i,sighandler);
363 if (!index(s,'\'')) {
364 sprintf(tokenbuf, "main'%s",s);
365 sv_setpv(sv,tokenbuf);
376 HV* hv = (HV*)mg->mg_obj;
377 hv_dbmstore(hv,mg->mg_ptr,mg->mg_len,sv); /* XXX slurp? */
382 magic_setdbline(sv,mg)
393 svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE);
394 if (svp && SvMAGICAL(*svp) && (o = (OP*)SvMAGIC(*svp)->mg_ptr)) {
396 cmd->cop_flags &= ~COPf_OPTIMIZE;
397 cmd->cop_flags |= i? COPo_D1 : COPo_D0;
401 warn("Can't break at that line\n");
406 magic_getarylen(sv,mg)
410 sv_setiv(sv, AvFILL((AV*)mg->mg_obj) + arybase);
415 magic_setarylen(sv,mg)
419 av_fill((AV*)mg->mg_obj, (SvIOK(sv) ? SvIV(sv) : sv_2iv(sv)) - arybase);
428 gv_efullname(sv,((GV*)sv));/* a gv value, be nice */
442 s = SvPOK(sv) ? SvPV(sv) : sv_2pv(sv);
443 if (*s == '*' && s[1])
445 gv = gv_fetchpv(s,TRUE);
450 GvGP(sv) = gp_ref(GvGP(gv));
461 magic_setsubstr(sv,mg)
465 char *tmps = SvPV(sv);
468 sv_insert(LvTARG(sv),LvTARGOFF(sv),LvTARGLEN(sv), tmps,SvCUR(sv));
477 do_vecset(sv); /* XXX slurp this routine */
496 struct ufuncs *uf = (struct ufuncs *)mg->mg_ptr;
498 if (uf && uf->uf_set)
499 (*uf->uf_set)(uf->uf_index, sv);
510 switch (*mg->mg_ptr) {
511 case '\004': /* ^D */
512 debug = (SvIOK(sv) ? SvIV(sv) : sv_2iv(sv)) | 32768;
515 case '\006': /* ^F */
516 maxsysfd = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
522 inplace = savestr(SvPV(sv));
526 case '\020': /* ^P */
527 i = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
536 case '\024': /* ^T */
537 basetime = (time_t)(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
539 case '\027': /* ^W */
540 dowarn = (bool)(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
544 save_sptr((SV**)&last_in_gv);
547 Safefree(GvIO(defoutgv)->top_name);
548 GvIO(defoutgv)->top_name = s = savestr(SvPV(sv));
549 GvIO(defoutgv)->top_gv = gv_fetchpv(s,TRUE);
552 Safefree(GvIO(defoutgv)->fmt_name);
553 GvIO(defoutgv)->fmt_name = s = savestr(SvPV(sv));
554 GvIO(defoutgv)->fmt_gv = gv_fetchpv(s,TRUE);
557 GvIO(defoutgv)->page_len = (long)(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
560 GvIO(defoutgv)->lines_left = (long)(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
561 if (GvIO(defoutgv)->lines_left < 0L)
562 GvIO(defoutgv)->lines_left = 0L;
565 GvIO(defoutgv)->page = (long)(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
569 GvIO(defoutgv) = newIO();
570 GvIO(defoutgv)->flags &= ~IOf_FLUSH;
571 if ((SvIOK(sv) ? SvIV(sv) : sv_2iv(sv)) != 0) {
572 GvIO(defoutgv)->flags |= IOf_FLUSH;
576 i = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
577 multiline = (i != 0);
583 if (rspara = !rslen) {
587 rschar = rs[rslen - 1];
590 rschar = 0777; /* fake a non-existent char */
597 ors = savestr(SvPV(sv));
603 ofs = savestr(SvPV(sv));
609 ofmt = savestr(SvPV(sv));
612 arybase = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
615 statusvalue = U_S(SvIOK(sv) ? SvIV(sv) : sv_2iv(sv));
618 errno = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv); /* will anyone ever use this? */
621 uid = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
623 delaymagic |= DM_RUID;
624 break; /* don't do magic till later */
627 (void)setruid((UIDTYPE)uid);
630 (void)setreuid((UIDTYPE)uid, (UIDTYPE)-1);
632 if (uid == euid) /* special case $< = $> */
635 fatal("setruid() not implemented");
638 uid = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
641 euid = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
643 delaymagic |= DM_EUID;
644 break; /* don't do magic till later */
647 (void)seteuid((UIDTYPE)euid);
650 (void)setreuid((UIDTYPE)-1, (UIDTYPE)euid);
652 if (euid == uid) /* special case $> = $< */
655 fatal("seteuid() not implemented");
658 euid = (I32)geteuid();
661 gid = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
663 delaymagic |= DM_RGID;
664 break; /* don't do magic till later */
667 (void)setrgid((GIDTYPE)gid);
670 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
672 if (gid == egid) /* special case $( = $) */
675 fatal("setrgid() not implemented");
681 egid = SvIOK(sv) ? SvIV(sv) : sv_2iv(sv);
683 delaymagic |= DM_EGID;
684 break; /* don't do magic till later */
687 (void)setegid((GIDTYPE)egid);
690 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
692 if (egid == gid) /* special case $) = $( */
695 fatal("setegid() not implemented");
698 egid = (I32)getegid();
707 /* See if all the arguments are contiguous in memory */
708 for (i = 1; i < origargc; i++) {
709 if (origargv[i] == s + 1)
710 s += strlen(++s); /* this one is ok too */
712 if (origenviron[0] == s + 1) { /* can grab env area too? */
713 my_setenv("NoNeSuCh", Nullch);
714 /* force copy of environment */
715 for (i = 0; origenviron[i]; i++)
716 if (origenviron[i] == s + 1)
719 origalen = s - origargv[0];
727 Copy(s, origargv[0], i, char);
730 Copy(s, origargv[0], i, char);
733 while (++i < origalen)
745 register char **sigv;
747 for (sigv = sig_name+1; *sigv; sigv++)
748 if (strEQ(sig,*sigv))
749 return sigv - sig_name;
751 if (strEQ(sig,"CHLD"))
755 if (strEQ(sig,"CLD"))
773 I32 gimme = G_SCALAR;
775 #ifdef OS2 /* or anybody else who requires SIG_ACK */
776 signal(sig, SIG_ACK);
780 SvPVnx(*hv_fetch(GvHVn(siggv),sig_name[sig],strlen(sig_name[sig]),
783 if (!cv && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
784 if (sig_name[sig][1] == 'H')
785 gv = gv_fetchpv(SvPVnx(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE)),
788 gv = gv_fetchpv(SvPVnx(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE)),
790 cv = GvCV(gv); /* gag */
794 warn("SIG%s handler \"%s\" not defined.\n",
795 sig_name[sig], GvENAME(gv) );
800 SWITCHSTACK(stack, signalstack);
802 sv = sv_mortalcopy(&sv_undef);
803 sv_setpv(sv,sig_name[sig]);
811 PUSHBLOCK(cx, CXt_SUB, sp);
813 cx->blk_sub.savearray = GvAV(defgv);
814 cx->blk_sub.argarray = av_fake(items, sp);
815 GvAV(defgv) = cx->blk_sub.argarray;
817 if (CvDEPTH(cv) >= 2) {
818 if (CvDEPTH(cv) == 100 && dowarn)
819 warn("Deep recursion on subroutine \"%s\"",GvENAME(gv));
823 run(); /* Does the LEAVE for us. */
825 SWITCHSTACK(signalstack, oldstack);
832 if (sv->sv_magic && !sv->sv_rare) {
833 GV *gv = sv->sv_magic->sv_u.sv_gv;
835 switch (*SvPV(gv->sv_magic)) {
836 case '1': case '2': case '3': case '4':
837 case '5': case '6': case '7': case '8': case '9': case '&':
839 paren = atoi(GvENAME(gv));
841 if (curpm->op_pmregexp &&
842 paren <= curpm->op_pmregexp->nparens &&
843 (s = curpm->op_pmregexp->startp[paren]) ) {
844 i = curpm->op_pmregexp->endp[paren] - s;
856 paren = curpm->op_pmregexp->lastparen;
862 if (curpm->op_pmregexp &&
863 (s = curpm->op_pmregexp->subbeg) ) {
864 i = curpm->op_pmregexp->startp[0] - s;
876 if (curpm->op_pmregexp &&
877 (s = curpm->op_pmregexp->endp[0]) ) {
878 return (STRLEN) (curpm->op_pmregexp->subend - s);
885 return (STRLEN)ofslen;
887 return (STRLEN)orslen;