1 /* $RCSfile: eval.c,v $$Revision: 4.0.1.1 $$Date: 91/04/11 17:43:48 $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 4.0.1.1 91/04/11 17:43:48 lwall
10 * patch1: fixed failed fork to return undef as documented
11 * patch1: reduced maximum branch distance in eval.c
13 * Revision 4.0 91/03/20 01:16:48 lwall
21 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
36 static void (*ihand)();
37 static void (*qhand)();
39 static int (*ihand)();
40 static int (*qhand)();
47 static struct lstring *lstr;
48 static int old_rschar;
51 double sin(), cos(), atan2(), pow();
72 int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
73 unsigned long tmplong;
80 bool assigning = FALSE;
81 double exp(), log(), sqrt(), modf();
82 char *crypt(), *getenv();
83 extern void grow_dlevel();
87 optype = arg->arg_type;
88 maxarg = arg->arg_len;
90 str = arg->arg_ptr.arg_str;
91 if (sp + maxarg > stack->ary_max)
92 astore(stack, sp + maxarg, Nullstr);
93 st = stack->ary_array;
98 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
100 debname[dlevel] = opname[optype][0];
101 debdelim[dlevel] = ':';
102 if (++dlevel >= dlmax)
107 for (anum = 1; anum <= maxarg; anum++) {
108 argflags = arg[anum].arg_flags;
109 argtype = arg[anum].arg_type;
110 argptr = arg[anum].arg_ptr;
114 st[++sp] = &str_undef;
123 deb("%d.EXPR =>\n",anum);
126 sp = eval(argptr.arg_arg,
127 (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp);
128 if (sp + (maxarg - anum) > stack->ary_max)
129 astore(stack, sp + (maxarg - anum), Nullstr);
130 st = stack->ary_array; /* possibly reallocated */
136 deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
139 sp = cmd_exec(argptr.arg_cmd, gimme, sp);
140 if (sp + (maxarg - anum) > stack->ary_max)
141 astore(stack, sp + (maxarg - anum), Nullstr);
142 st = stack->ary_array; /* possibly reallocated */
147 case O_ITEM2: argtype = 2; break;
148 case O_ITEM3: argtype = 3; break;
149 default: argtype = anum; break;
151 str = afetch(stab_array(argptr.arg_stab),
152 arg[argtype].arg_len - arybase, TRUE);
155 (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
156 arg[argtype].arg_len);
163 case O_ITEM2: argtype = 2; break;
164 case O_ITEM3: argtype = 3; break;
165 default: argtype = anum; break;
167 st[++sp] = afetch(stab_array(argptr.arg_stab),
168 arg[argtype].arg_len - arybase, FALSE);
171 (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
172 arg[argtype].arg_len);
178 stab = argptr.arg_stab;
179 st[++sp] = (STR*)stab;
180 if (!stab_xarray(stab))
182 if (!stab_xhash(stab))
185 stab_io(stab) = stio_new();
188 (void)sprintf(buf,"STAR *%s",stab_name(argptr.arg_stab));
194 str = st[++sp] = (STR*)argptr.arg_stab;
197 (void)sprintf(buf,"LSTAR *%s",stab_name(argptr.arg_stab));
203 st[++sp] = STAB_STR(argptr.arg_stab);
206 (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab));
215 deb("%d.LEXPR =>\n",anum);
218 if (argflags & AF_ARYOK) {
219 sp = eval(argptr.arg_arg, G_ARRAY, sp);
220 if (sp + (maxarg - anum) > stack->ary_max)
221 astore(stack, sp + (maxarg - anum), Nullstr);
222 st = stack->ary_array; /* possibly reallocated */
225 sp = eval(argptr.arg_arg, G_SCALAR, sp);
226 st = stack->ary_array; /* possibly reallocated */
234 (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab));
239 str = STAB_STR(argptr.arg_stab);
241 fatal("panic: A_LVAL");
244 if (argflags & AF_PRE) {
245 if (argflags & AF_UP)
251 str = arg->arg_ptr.arg_str;
253 else if (argflags & AF_POST) {
254 st[sp] = str_mortal(str);
255 if (argflags & AF_UP)
260 str = arg->arg_ptr.arg_str;
267 stab = argptr.arg_stab;
268 str = stab_array(argptr.arg_stab)->ary_magic;
269 if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
270 str_numset(str,(double)(stab_array(stab)->ary_fill+arybase));
275 fatal("panic: A_LEXPR");
278 stab = argptr.arg_stab;
279 st[++sp] = stab_array(stab)->ary_magic;
280 str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase));
286 st[++sp] = argptr.arg_str;
292 (void) interp(str,argptr.arg_str,sp);
293 st = stack->ary_array;
300 tmps = str_get(interp(str,argptr.arg_str,sp));
301 st = stack->ary_array;
303 taintproper("Insecure dependency in ``");
305 fp = mypopen(tmps,"r");
308 if (gimme == G_SCALAR) {
309 while (str_gets(str,fp,str->str_cur) != Nullch)
314 if (++sp > stack->ary_max) {
315 astore(stack, sp, Nullstr);
316 st = stack->ary_array;
318 str = st[sp] = Str_new(56,80);
319 if (str_gets(str,fp,0) == Nullch) {
323 if (str->str_len - str->str_cur > 20) {
324 str->str_len = str->str_cur+1;
325 Renew(str->str_ptr, str->str_len, char);
330 statusvalue = mypclose(fp);
335 if (gimme == G_SCALAR)
343 if (curcsv->wantarray == G_ARRAY)
353 last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
358 argflags |= AF_POST; /* enable newline chopping */
359 last_in_stab = argptr.arg_stab;
374 last_in_stab = argptr.arg_stab;
378 if (anum > 1) /* assign to scalar */
379 gimme = G_SCALAR; /* force context to scalar */
380 if (gimme == G_ARRAY)
384 if (stab_io(last_in_stab)) {
385 fp = stab_io(last_in_stab)->ifp;
387 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
388 if (stab_io(last_in_stab)->flags & IOF_START) {
389 stab_io(last_in_stab)->flags &= ~IOF_START;
390 stab_io(last_in_stab)->lines = 0;
391 if (alen(stab_array(last_in_stab)) < 0) {
392 tmpstr = str_make("-",1); /* assume stdin */
393 (void)apush(stab_array(last_in_stab), tmpstr);
396 fp = nextargv(last_in_stab);
397 if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
398 (void)do_close(last_in_stab,FALSE); /* now it does*/
399 stab_io(last_in_stab)->flags |= IOF_START;
402 else if (argtype == A_GLOB) {
403 (void) interp(str,stab_val(last_in_stab),sp);
404 st = stack->ary_array;
405 tmpstr = Str_new(55,0);
407 str_set(tmpstr, "perlglob ");
408 str_scat(tmpstr,str);
409 str_cat(tmpstr," |");
412 str_nset(tmpstr,cshname,cshlen);
413 str_cat(tmpstr," -cf 'set nonomatch; glob ");
414 str_scat(tmpstr,str);
415 str_cat(tmpstr,"'|");
417 str_set(tmpstr, "echo ");
418 str_scat(tmpstr,str);
420 "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
423 (void)do_open(last_in_stab,tmpstr->str_ptr,
425 fp = stab_io(last_in_stab)->ifp;
431 warn("Read on closed filehandle <%s>",stab_name(last_in_stab));
432 when = str->str_len; /* remember if already alloced */
434 Str_Grow(str,80); /* try short-buffering it */
438 else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) {
440 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
441 fp = nextargv(last_in_stab);
444 (void)do_close(last_in_stab,FALSE);
445 stab_io(last_in_stab)->flags |= IOF_START;
447 else if (argflags & AF_POST) {
448 (void)do_close(last_in_stab,FALSE);
453 if (gimme == G_ARRAY) {
461 stab_io(last_in_stab)->lines++;
464 str->str_tainted = 1; /* Anything from the outside world...*/
466 if (argflags & AF_POST) {
467 if (str->str_cur > 0)
469 if (str->str_ptr[str->str_cur] == rschar)
470 str->str_ptr[str->str_cur] = '\0';
473 for (tmps = str->str_ptr; *tmps; tmps++)
474 if (!isalpha(*tmps) && !isdigit(*tmps) &&
475 index("$&*(){}[]'\";\\|?<>~`",*tmps))
477 if (*tmps && stat(str->str_ptr,&statbuf) < 0)
478 goto keepgoing; /* unmatched wildcard? */
480 if (gimme == G_ARRAY) {
481 if (str->str_len - str->str_cur > 20) {
482 str->str_len = str->str_cur+1;
483 Renew(str->str_ptr, str->str_len, char);
486 if (++sp > stack->ary_max) {
487 astore(stack, sp, Nullstr);
488 st = stack->ary_array;
490 str = Str_new(58,80);
493 else if (!when && str->str_len - str->str_cur > 80) {
494 /* try to reclaim a bit of scalar space on 1st alloc */
495 if (str->str_cur < 60)
498 str->str_len = str->str_cur+40; /* allow some slop */
499 Renew(str->str_ptr, str->str_len, char);
511 deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));
519 if (optype < O_CHOWN)
526 if (gimme == G_ARRAY)
534 if (gimme == G_ARRAY)
537 STR_SSET(str,st[arglast[anum]-arglast[0]]);
541 if (gimme == G_ARRAY)
544 STR_SSET(str,st[arglast[anum]-arglast[0]]);
553 if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {
554 sp = do_repeatary(arglast);
557 STR_SSET(str,st[arglast[1] - arglast[0]]);
558 anum = (int)str_gnum(st[arglast[2] - arglast[0]]);
560 tmpstr = Str_new(50, 0);
562 str_nset(tmpstr,tmps,str->str_cur);
563 tmps = str_get(tmpstr); /* force to be string */
564 STR_GROW(str, (anum * str->str_cur) + 1);
565 repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
566 str->str_cur *= anum;
567 str->str_ptr[str->str_cur] = '\0';
572 str_sset(str,&str_no);
576 sp = do_match(str,arg,
578 if (gimme == G_ARRAY)
583 sp = do_match(str,arg,
585 str_sset(str, str_true(str) ? &str_no : &str_yes);
589 sp = do_subst(str,arg,arglast[0]);
592 sp = do_subst(str,arg,arglast[0]);
593 str = arg->arg_ptr.arg_str;
594 str_set(str, str_true(str) ? No : Yes);
597 if (arg[1].arg_flags & AF_ARYOK) {
598 if (arg->arg_len == 1) {
599 arg->arg_type = O_LOCAL;
603 arg->arg_type = O_AASSIGN;
608 arg->arg_type = O_SASSIGN;
613 arglast[2] = arglast[1]; /* push a null array */
622 STR_SSET(str, st[2]);
627 str = arg->arg_ptr.arg_str;
628 for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
633 if (arg[1].arg_type & A_DONT) {
634 sp = do_defined(str,arg,
638 else if (str->str_pok || str->str_nok)
642 if (arg[1].arg_type & A_DONT) {
643 sp = do_undef(str,arg,
647 else if (str != stab_val(defstab)) {
649 if (str->str_state == SS_INCR)
651 Safefree(str->str_ptr);
652 str->str_ptr = Nullch;
655 str->str_pok = str->str_nok = 0;
660 sp = do_study(str,arg,
664 value = str_gnum(st[1]);
665 value = pow(value,str_gnum(st[2]));
668 value = str_gnum(st[1]);
669 value *= str_gnum(st[2]);
672 if ((value = str_gnum(st[2])) == 0.0)
673 fatal("Illegal division by zero");
675 /* insure that 20./5. == 4. */
680 if ((double)(int)x == x &&
681 (double)(int)value == value &&
682 (k = (int)x/(int)value)*(int)value == (int)x) {
689 value = str_gnum(st[1]) / value;
693 tmplong = (long) str_gnum(st[2]);
695 fatal("Illegal modulus zero");
696 when = (long)str_gnum(st[1]);
699 value = (double)(when % tmplong);
701 value = (double)(tmplong - ((-when - 1) % tmplong)) - 1;
705 value = str_gnum(st[1]);
706 value += str_gnum(st[2]);
709 value = str_gnum(st[1]);
710 value -= str_gnum(st[2]);
713 value = str_gnum(st[1]);
714 anum = (int)str_gnum(st[2]);
716 value = (double)(U_L(value) << anum);
720 value = str_gnum(st[1]);
721 anum = (int)str_gnum(st[2]);
723 value = (double)(U_L(value) >> anum);
727 value = str_gnum(st[1]);
728 value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
731 value = str_gnum(st[1]);
732 value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
735 value = str_gnum(st[1]);
736 value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
739 value = str_gnum(st[1]);
740 value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
744 if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
745 (!st[2]->str_nok && !looks_like_number(st[2])) )
746 warn("Possible use of == on string value");
748 value = str_gnum(st[1]);
749 value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
752 value = str_gnum(st[1]);
753 value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
756 value = str_gnum(st[1]);
757 value -= str_gnum(st[2]);
760 else if (value < 0.0)
764 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
765 value = str_gnum(st[1]);
767 value = (double)(U_L(value) & U_L(str_gnum(st[2])));
772 do_vop(optype,str,st[1],st[2]);
775 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
776 value = str_gnum(st[1]);
778 value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));
783 do_vop(optype,str,st[1],st[2]);
786 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
787 value = str_gnum(st[1]);
789 value = (double)(U_L(value) | U_L(str_gnum(st[2])));
794 do_vop(optype,str,st[1],st[2]);
796 /* use register in evaluating str_true() */
798 if (str_true(st[1])) {
801 argflags = arg[anum].arg_flags;
802 if (gimme == G_ARRAY)
803 argflags |= AF_ARYOK;
804 argtype = arg[anum].arg_type & A_MASK;
805 argptr = arg[anum].arg_ptr;
813 str_sset(str, st[1]);
821 if (str_true(st[1])) {
823 str_sset(str, st[1]);
833 argflags = arg[anum].arg_flags;
834 if (gimme == G_ARRAY)
835 argflags |= AF_ARYOK;
836 argtype = arg[anum].arg_type & A_MASK;
837 argptr = arg[anum].arg_ptr;
844 anum = (str_true(st[1]) ? 2 : 3);
845 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
846 argflags = arg[anum].arg_flags;
847 if (gimme == G_ARRAY)
848 argflags |= AF_ARYOK;
849 argtype = arg[anum].arg_type & A_MASK;
850 argptr = arg[anum].arg_ptr;
856 if (gimme == G_ARRAY)
861 value = -str_gnum(st[1]);
864 value = (double) !str_true(st[1]);
867 if (!sawvec || st[1]->str_nok) {
869 value = (double) ~U_L(str_gnum(st[1]));
876 for (anum = str->str_cur; anum; anum--, tmps++)
881 stab_fullname(str,defoutstab);
883 if ((arg[1].arg_type & A_MASK) == A_WORD)
884 defoutstab = arg[1].arg_ptr.arg_stab;
886 defoutstab = stabent(str_get(st[1]),TRUE);
887 if (!stab_io(defoutstab))
888 stab_io(defoutstab) = stio_new();
889 curoutstab = defoutstab;
896 else if ((arg[1].arg_type & A_MASK) == A_WORD) {
897 if (!(stab = arg[1].arg_ptr.arg_stab))
901 stab = stabent(str_get(st[1]),TRUE);
902 if (!stab_io(stab)) {
908 fp = stab_io(stab)->ofp;
910 if (stab_io(stab)->fmt_stab)
911 form = stab_form(stab_io(stab)->fmt_stab);
913 form = stab_form(stab);
917 warn("No format for filehandle");
919 if (stab_io(stab)->ifp)
920 warn("Filehandle only opened for input");
922 warn("Write on closed filehandle");
929 format(&outrec,form,sp);
930 do_write(&outrec,stab_io(stab),sp);
931 if (stab_io(stab)->flags & IOF_FLUSH)
938 anum = arg[1].arg_type & A_MASK;
939 if (anum == A_WORD || anum == A_STAB)
940 stab = arg[1].arg_ptr.arg_stab;
942 stab = stabent(str_get(st[1]),TRUE);
943 if (st[3]->str_nok || st[3]->str_pok)
944 anum = (int)str_gnum(st[3]);
947 value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
950 fatal("No dbm or ndbm on this machine");
954 if ((arg[1].arg_type & A_MASK) == A_WORD)
955 stab = arg[1].arg_ptr.arg_stab;
957 stab = stabent(str_get(st[1]),TRUE);
958 hdbmclose(stab_hash(stab));
961 fatal("No dbm or ndbm on this machine");
964 if ((arg[1].arg_type & A_MASK) == A_WORD)
965 stab = arg[1].arg_ptr.arg_stab;
967 stab = stabent(str_get(st[1]),TRUE);
968 tmps = str_get(st[2]);
969 if (do_open(stab,tmps,st[2]->str_cur)) {
970 value = (double)forkprocess;
971 stab_io(stab)->lines = 0;
974 else if (forkprocess == 0) /* we are a new child */
980 value = (double) do_trans(str,arg);
981 str = arg->arg_ptr.arg_str;
984 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
985 str = arg->arg_ptr.arg_str;
990 else if ((arg[1].arg_type & A_MASK) == A_WORD)
991 stab = arg[1].arg_ptr.arg_stab;
993 stab = stabent(str_get(st[1]),TRUE);
994 str_set(str, do_close(stab,TRUE) ? Yes : No );
998 sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
1003 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1007 str->str_nok = str->str_pok = 0;
1008 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1009 str->str_state = SS_ARY;
1012 ary = stab_array(arg[1].arg_ptr.arg_stab);
1013 maxarg = ary->ary_fill + 1;
1014 if (gimme == G_ARRAY) { /* array wanted */
1017 if (maxarg > 0 && sp + maxarg > stack->ary_max) {
1018 astore(stack,sp + maxarg, Nullstr);
1019 st = stack->ary_array;
1022 Copy(ary->ary_array, &st[1], maxarg, STR*);
1027 value = (double)maxarg;
1031 anum = ((int)str_gnum(st[2])) - arybase;
1032 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
1035 tmpstab = arg[1].arg_ptr.arg_stab;
1036 tmps = str_get(st[2]);
1037 str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
1038 if (tmpstab == envstab)
1039 setenv(tmps,Nullch);
1044 str->str_nok = str->str_pok = 0;
1045 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1046 str->str_state = SS_HASH;
1049 if (gimme == G_ARRAY) { /* array wanted */
1050 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1055 tmpstab = arg[1].arg_ptr.arg_stab;
1056 if (!stab_hash(tmpstab)->tbl_fill)
1058 sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
1059 stab_hash(tmpstab)->tbl_max+1);
1064 tmpstab = arg[1].arg_ptr.arg_stab;
1065 tmps = str_get(st[2]);
1066 str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
1069 anum = ((int)str_gnum(st[2])) - arybase;
1070 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
1071 if (!str || str == &str_undef)
1072 fatal("Assignment to non-creatable value, subscript %d",anum);
1075 tmpstab = arg[1].arg_ptr.arg_stab;
1076 tmps = str_get(st[2]);
1077 anum = st[2]->str_cur;
1078 str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
1079 if (!str || str == &str_undef)
1080 fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
1081 if (tmpstab == envstab) /* heavy wizardry going on here */
1082 str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
1083 /* he threw the brick up into the air */
1084 else if (tmpstab == sigstab)
1085 str_magic(str, tmpstab, 'S', tmps, anum);
1087 else if (stab_hash(tmpstab)->tbl_dbm)
1088 str_magic(str, tmpstab, 'D', tmps, anum);
1090 else if (perldb && tmpstab == DBline)
1091 str_magic(str, tmpstab, 'L', tmps, anum);
1096 goto do_slice_already;
1100 goto do_slice_already;
1104 goto do_slice_already;
1108 goto do_slice_already;
1113 sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
1117 sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast);
1120 if (arglast[2] - arglast[1] != 1)
1121 str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
1123 str = Str_new(51,0); /* must copy the STR */
1124 str_sset(str,st[2]);
1125 (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
1129 str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
1130 goto staticalization;
1132 str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
1136 if (ary->ary_flags & ARF_REAL)
1137 (void)str_2mortal(str);
1140 sp = do_unpack(str,gimme,arglast);
1143 value = str_gnum(st[3]);
1144 sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
1149 value = (double)str_len(stab_val(defstab));
1151 value = (double)str_len(st[1]);
1154 do_sprintf(str, sp-arglast[0], st+1);
1157 anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
1158 tmps = str_get(st[1]); /* force conversion to string */
1159 if (argtype = (str == st[1]))
1160 str = arg->arg_ptr.arg_str;
1162 anum += st[1]->str_cur + arybase;
1163 if (anum < 0 || anum > st[1]->str_cur)
1166 optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]);
1170 anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
1173 str_nset(str, tmps, anum);
1174 if (argtype) { /* it's an lvalue! */
1175 lstr = (struct lstring*)str;
1176 str->str_magic = st[1];
1177 st[1]->str_rare = 's';
1178 lstr->lstr_offset = tmps - str_get(st[1]);
1179 lstr->lstr_len = anum;
1184 (void)do_pack(str,arglast);
1187 sp = do_grep(arg,str,gimme,arglast);
1190 do_join(str,arglast);
1193 tmps = str_get(st[1]);
1194 value = (double) (str_cmp(st[1],st[2]) < 0);
1197 tmps = str_get(st[1]);
1198 value = (double) (str_cmp(st[1],st[2]) > 0);
1201 tmps = str_get(st[1]);
1202 value = (double) (str_cmp(st[1],st[2]) <= 0);
1205 tmps = str_get(st[1]);
1206 value = (double) (str_cmp(st[1],st[2]) >= 0);
1209 tmps = str_get(st[1]);
1210 value = (double) str_eq(st[1],st[2]);
1213 tmps = str_get(st[1]);
1214 value = (double) !str_eq(st[1],st[2]);
1217 tmps = str_get(st[1]);
1218 value = (double) str_cmp(st[1],st[2]);
1221 sp = do_subr(arg,gimme,arglast);
1222 st = stack->ary_array + arglast[0]; /* maybe realloced */
1225 sp = do_subr(arg,gimme,arglast);
1226 st = stack->ary_array + arglast[0]; /* maybe realloced */
1229 sp = do_caller(arg,maxarg,gimme,arglast);
1230 st = stack->ary_array + arglast[0]; /* maybe realloced */
1233 if ((arg[1].arg_type & A_MASK) == A_WORD)
1234 stab = arg[1].arg_ptr.arg_stab;
1236 stab = stabent(str_get(st[1]),TRUE);
1237 sp = do_sort(str,stab,
1241 if (gimme == G_ARRAY)
1242 sp = do_reverse(arglast);
1244 sp = do_sreverse(str, arglast);
1247 if (arglast[2] - arglast[1] != 1) {
1248 do_join(str,arglast);
1249 tmps = str_get(str);
1253 tmps = str_get(st[2]);
1255 if (!tmps || !*tmps)
1256 tmps = "Warning: something's wrong";
1260 if (arglast[2] - arglast[1] != 1) {
1261 do_join(str,arglast);
1262 tmps = str_get(str);
1266 tmps = str_get(st[2]);
1268 if (!tmps || !*tmps)
1274 if ((arg[1].arg_type & A_MASK) == A_WORD)
1275 stab = arg[1].arg_ptr.arg_stab;
1277 stab = stabent(str_get(st[1]),TRUE);
1280 if (!stab_io(stab)) {
1282 warn("Filehandle never opened");
1285 if (!(fp = stab_io(stab)->ofp)) {
1287 if (stab_io(stab)->ifp)
1288 warn("Filehandle opened only for input");
1290 warn("Print on closed filehandle");
1295 if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
1296 value = (double)do_aprint(arg,fp,arglast);
1298 value = (double)do_print(st[2],fp);
1299 if (orslen && optype == O_PRINT)
1300 if (fwrite(ors, 1, orslen, fp) == 0)
1303 if (stab_io(stab)->flags & IOF_FLUSH)
1304 if (fflush(fp) == EOF)
1312 tmps = str_get(st[1]);
1313 if (!tmps || !*tmps) {
1314 tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
1315 tmps = str_get(tmpstr);
1317 if (!tmps || !*tmps) {
1318 tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
1319 tmps = str_get(tmpstr);
1322 taintproper("Insecure dependency in chdir");
1324 value = (double)(chdir(tmps) >= 0);
1330 anum = (int)str_gnum(st[1]);
1337 tmps = str_get(st[1]);
1338 str_reset(tmps,curcmd->c_stash);
1342 if (gimme == G_ARRAY)
1345 str = st[sp - arglast[0]]; /* unwanted list, return last item */
1351 stab = last_in_stab;
1352 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1353 stab = arg[1].arg_ptr.arg_stab;
1355 stab = stabent(str_get(st[1]),TRUE);
1356 str_set(str, do_eof(stab) ? Yes : No);
1362 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1363 stab = arg[1].arg_ptr.arg_stab;
1365 stab = stabent(str_get(st[1]),TRUE);
1368 if (!stab || do_eof(stab)) /* make sure we have fp with something */
1375 *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
1381 stab = last_in_stab;
1382 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1383 stab = arg[1].arg_ptr.arg_stab;
1385 stab = stabent(str_get(st[1]),TRUE);
1387 value = (double)do_tell(stab);
1389 (void)do_tell(stab);
1395 if ((arg[1].arg_type & A_MASK) == A_WORD)
1396 stab = arg[1].arg_ptr.arg_stab;
1398 stab = stabent(str_get(st[1]),TRUE);
1399 tmps = str_get(st[2]);
1400 anum = (int)str_gnum(st[3]);
1402 maxarg = sp - arglast[0];
1404 warn("Too many args on read");
1406 maxarg = (int)str_gnum(st[4]);
1409 if (!stab_io(stab) || !stab_io(stab)->ifp)
1412 if (optype == O_RECV) {
1413 argtype = sizeof buf;
1414 STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
1415 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg,
1418 st[2]->str_cur = anum;
1419 st[2]->str_ptr[anum] = '\0';
1420 str_nset(str,buf,argtype);
1423 str_sset(str,&str_undef);
1427 if (optype == O_RECV)
1430 STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2])); /* sneaky */
1432 if (stab_io(stab)->type == 's') {
1433 argtype = sizeof buf;
1434 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0,
1439 if (optype == O_SYSREAD) {
1440 anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum);
1443 anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp);
1446 st[2]->str_cur = anum+maxarg;
1447 st[2]->str_ptr[anum+maxarg] = '\0';
1448 value = (double)anum;
1452 if ((arg[1].arg_type & A_MASK) == A_WORD)
1453 stab = arg[1].arg_ptr.arg_stab;
1455 stab = stabent(str_get(st[1]),TRUE);
1456 tmps = str_get(st[2]);
1457 anum = (int)str_gnum(st[3]);
1459 stio = stab_io(stab);
1460 maxarg = sp - arglast[0];
1461 if (!stio || !stio->ifp) {
1464 if (optype == O_SYSWRITE)
1465 warn("Syswrite on closed filehandle");
1467 warn("Send on closed socket");
1470 else if (optype == O_SYSWRITE) {
1472 warn("Too many args on syswrite");
1474 optype = (int)str_gnum(st[4]);
1477 anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum);
1480 else if (maxarg >= 4) {
1482 warn("Too many args on send");
1483 tmps2 = str_get(st[4]);
1484 anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
1485 anum, tmps2, st[4]->str_cur);
1488 anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
1495 value = (double)anum;
1498 if ((arg[1].arg_type & A_MASK) == A_WORD)
1499 stab = arg[1].arg_ptr.arg_stab;
1501 stab = stabent(str_get(st[1]),TRUE);
1502 value = str_gnum(st[2]);
1503 str_set(str, do_seek(stab,
1504 (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
1508 tmps = "_SUB_"; /* just fake up a "last _SUB_" */
1510 if (curcsv && curcsv->wantarray == G_ARRAY) {
1511 lastretstr = Nullstr;
1512 lastspbase = arglast[1];
1513 lastsize = arglast[2] - arglast[1];
1516 lastretstr = str_mortal(st[arglast[2] - arglast[0]]);
1522 tmps = str_get(arg[1].arg_ptr.arg_str);
1524 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1525 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1528 deb("(Skipping label #%d %s)\n",loop_ptr,
1529 loop_stack[loop_ptr].loop_label);
1536 deb("(Found label #%d %s)\n",loop_ptr,
1537 loop_stack[loop_ptr].loop_label);
1542 if (tmps && strEQ(tmps, "_SUB_"))
1543 fatal("Can't return outside a subroutine");
1544 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
1546 if (!lastretstr && optype == O_LAST && lastsize) {
1548 st += lastspbase + 1;
1549 optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
1551 for (anum = lastsize; anum > 0; anum--,st++)
1552 st[optype] = str_mortal(st[0]);
1554 longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
1556 longjmp(loop_stack[loop_ptr].loop_env, optype);
1558 case O_GOTO:/* shudder */
1559 goto_targ = str_get(arg[1].arg_ptr.arg_str);
1561 goto_targ = Nullch; /* just restart from top */
1562 if (optype == O_DUMP) {
1566 longjmp(top_env, 1);
1568 tmps = str_get(st[1]);
1572 anum = (int) str_gnum(st[3]) - arybase;
1575 else if (anum > st[1]->str_cur)
1576 anum = st[1]->str_cur;
1579 if (!(tmps2 = fbminstr((unsigned char*)tmps + anum,
1580 (unsigned char*)tmps + st[1]->str_cur, st[2])))
1582 if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
1584 value = (double)(-1 + arybase);
1586 value = (double)(tmps2 - tmps + arybase);
1589 tmps = str_get(st[1]);
1590 tmps2 = str_get(st[2]);
1592 anum = st[1]->str_cur;
1594 anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur;
1597 else if (anum > st[1]->str_cur)
1598 anum = st[1]->str_cur;
1601 if (!(tmps2 = rninstr(tmps, tmps + anum,
1602 tmps2, tmps2 + st[2]->str_cur)))
1604 if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
1606 value = (double)(-1 + arybase);
1608 value = (double)(tmps2 - tmps + arybase);
1612 value = (double) time(Null(long*));
1616 sp = do_tms(str,gimme,arglast);
1622 when = (long)str_gnum(st[1]);
1623 sp = do_time(str,localtime(&when),
1630 when = (long)str_gnum(st[1]);
1631 sp = do_time(str,gmtime(&when),
1635 sp = do_truncate(str,arg,
1640 sp = do_stat(str,arg,
1645 tmps = str_get(st[1]);
1647 str_set(str,fcrypt(tmps,str_get(st[2])));
1649 str_set(str,crypt(tmps,str_get(st[2])));
1653 "The crypt() function is unimplemented due to excessive paranoia.");
1657 value = str_gnum(st[1]);
1658 value = atan2(value,str_gnum(st[2]));
1662 value = str_gnum(stab_val(defstab));
1664 value = str_gnum(st[1]);
1669 value = str_gnum(stab_val(defstab));
1671 value = str_gnum(st[1]);
1678 value = str_gnum(st[1]);
1682 value = rand() * value / 2147483648.0;
1685 value = rand() * value / 65536.0;
1688 value = rand() * value / 32768.0;
1690 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1701 anum = (int)str_gnum(st[1]);
1706 value = str_gnum(stab_val(defstab));
1708 value = str_gnum(st[1]);
1713 value = str_gnum(stab_val(defstab));
1715 value = str_gnum(st[1]);
1717 fatal("Can't take log of %g\n", value);
1722 value = str_gnum(stab_val(defstab));
1724 value = str_gnum(st[1]);
1726 fatal("Can't take sqrt of %g\n", value);
1727 value = sqrt(value);
1731 value = str_gnum(stab_val(defstab));
1733 value = str_gnum(st[1]);
1735 (void)modf(value,&value);
1737 (void)modf(-value,&value);
1743 tmps = str_get(stab_val(defstab));
1745 tmps = str_get(st[1]);
1747 value = (double) (*tmps & 255);
1750 value = (double) (anum & 255);
1756 tmps = str_get(stab_val(defstab));
1758 tmps = str_get(st[1]);
1761 anum = alarm((unsigned int)atoi(tmps));
1764 value = (double)anum;
1767 fatal("Unsupported function alarm");
1774 tmps = str_get(st[1]);
1776 if (!tmps || !*tmps)
1777 sleep((32767<<16)+32767);
1779 sleep((unsigned int)atoi(tmps));
1781 value = (double)when;
1783 value = ((double)when) - value;
1787 sp = do_range(gimme,arglast);
1790 if (gimme == G_ARRAY) { /* it's a range */
1791 /* can we optimize to constant array? */
1792 if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
1793 (arg[2].arg_type & A_MASK) == A_SINGLE) {
1794 st[2] = arg[2].arg_ptr.arg_str;
1795 sp = do_range(gimme,arglast);
1796 st = stack->ary_array;
1797 maxarg = sp - arglast[0];
1798 str_free(arg[1].arg_ptr.arg_str);
1799 arg[1].arg_ptr.arg_str = Nullstr;
1800 str_free(arg[2].arg_ptr.arg_str);
1801 arg[2].arg_ptr.arg_str = Nullstr;
1802 arg->arg_type = O_ARRAY;
1803 arg[1].arg_type = A_STAB|A_DONT;
1805 stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
1806 ary = stab_array(stab);
1807 afill(ary,maxarg - 1);
1810 while (maxarg-- > 0)
1811 ary->ary_array[maxarg] = str_smake(st[maxarg]);
1815 arg->arg_type = optype = O_RANGE;
1816 maxarg = arg->arg_len = 2;
1818 arg[anum].arg_flags &= ~AF_ARYOK;
1819 argflags = arg[anum].arg_flags;
1820 argtype = arg[anum].arg_type & A_MASK;
1821 arg[anum].arg_type = argtype;
1822 argptr = arg[anum].arg_ptr;
1828 arg->arg_type = O_FLIP;
1831 if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
1832 last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
1835 str_numset(str,0.0);
1837 arg->arg_type = optype = O_FLOP;
1838 arg[2].arg_type &= ~A_DONT;
1839 arg[1].arg_type |= A_DONT;
1840 argflags = arg[2].arg_flags;
1841 argtype = arg[2].arg_type & A_MASK;
1842 argptr = arg[2].arg_ptr;
1851 if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
1852 last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
1855 arg->arg_type = O_FLIP;
1856 arg[1].arg_type &= ~A_DONT;
1857 arg[2].arg_type |= A_DONT;
1867 if (tmpstab = stabent("$",allstabs))
1868 str_numset(STAB_STR(tmpstab),(double)getpid());
1869 hclear(pidstatus); /* no kids, so don't wait for 'em */
1871 value = (double)anum;
1874 fatal("Unsupported function fork");
1880 anum = wait(&argflags);
1882 pidgone(anum,argflags);
1883 value = (double)anum;
1885 statusvalue = (unsigned short)argflags;
1888 fatal("Unsupported function wait");
1894 anum = (int)str_gnum(st[1]);
1895 optype = (int)str_gnum(st[2]);
1896 anum = wait4pid(anum, &argflags,optype);
1897 value = (double)anum;
1899 statusvalue = (unsigned short)argflags;
1902 fatal("Unsupported function wait");
1908 if (arglast[2] - arglast[1] == 1) {
1910 tainted |= st[2]->str_tainted;
1911 taintproper("Insecure dependency in system");
1914 while ((anum = vfork()) == -1) {
1915 if (errno != EAGAIN) {
1923 ihand = signal(SIGINT, SIG_IGN);
1924 qhand = signal(SIGQUIT, SIG_IGN);
1925 argtype = wait4pid(anum, &argflags, 0);
1929 (void)signal(SIGINT, ihand);
1930 (void)signal(SIGQUIT, qhand);
1931 statusvalue = (unsigned short)argflags;
1935 value = (double)((unsigned int)argflags & 0xffff);
1937 do_execfree(); /* free any memory child malloced on vfork */
1940 if ((arg[1].arg_type & A_MASK) == A_STAB)
1941 value = (double)do_aexec(st[1],arglast);
1942 else if (arglast[2] - arglast[1] != 1)
1943 value = (double)do_aexec(Nullstr,arglast);
1945 value = (double)do_exec(str_get(str_mortal(st[2])));
1949 if ((arg[1].arg_type & A_MASK) == A_STAB)
1950 value = (double)do_aspawn(st[1],arglast);
1951 else if (arglast[2] - arglast[1] != 1)
1952 value = (double)do_aspawn(Nullstr,arglast);
1954 value = (double)do_spawn(str_get(str_mortal(st[2])));
1959 if ((arg[1].arg_type & A_MASK) == A_STAB)
1960 value = (double)do_aexec(st[1],arglast);
1961 else if (arglast[2] - arglast[1] != 1)
1962 value = (double)do_aexec(Nullstr,arglast);
1964 value = (double)do_exec(str_get(str_mortal(st[2])));
1969 tmps = str_get(stab_val(defstab));
1971 tmps = str_get(st[1]);
1972 value = (double)scanhex(tmps, 99, &argtype);
1977 tmps = str_get(stab_val(defstab));
1979 tmps = str_get(st[1]);
1980 while (*tmps && isascii(*tmps) && (isspace(*tmps) || *tmps == '0'))
1983 value = (double)scanhex(++tmps, 99, &argtype);
1985 value = (double)scanoct(tmps, 99, &argtype);
1988 /* These common exits are hidden here in the middle of the switches for the
1989 /* benefit of those machines with limited branch addressing. Sigh. */
1996 anum = sp - arglast[0];
1999 deb("%s RETURNS ()\n",opname[optype]);
2002 deb("%s RETURNS (\"%s\")\n",opname[optype],str_get(st[1]));
2005 tmps = str_get(st[1]);
2006 deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\")\n",opname[optype],
2007 anum,tmps,anum==2?"":"...,",str_get(st[anum]));
2032 str_numset(str,value);
2039 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2042 return arglast[0] + 1;
2043 #ifdef SMALLSWITCHES
2050 value = (double)apply(optype,arglast);
2053 fatal("Unsupported function chown");
2058 value = (double)apply(optype,arglast);
2061 fatal("Unsupported function kill");
2067 value = (double)apply(optype,arglast);
2076 anum = umask((int)str_gnum(st[1]));
2077 value = (double)anum;
2079 taintproper("Insecure dependency in umask");
2083 fatal("Unsupported function umask");
2086 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2090 if ((anum = do_ipcget(optype, arglast)) == -1)
2092 value = (double)anum;
2097 anum = do_ipcctl(optype, arglast);
2101 value = (double)anum;
2104 str_set(str,"0 but true");
2108 value = (double)(do_msgsnd(arglast) >= 0);
2111 value = (double)(do_msgrcv(arglast) >= 0);
2114 value = (double)(do_semop(arglast) >= 0);
2118 value = (double)(do_shmio(optype, arglast) >= 0);
2120 #else /* not SYSVIPC */
2132 fatal("System V IPC is not implemented on this machine");
2133 #endif /* not SYSVIPC */
2135 tmps = str_get(st[1]);
2136 tmps2 = str_get(st[2]);
2138 taintproper("Insecure dependency in rename");
2141 value = (double)(rename(tmps,tmps2) >= 0);
2143 if (same_dirent(tmps2, tmps)) /* can always rename to same name */
2146 if (euid || stat(tmps2,&statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
2147 (void)UNLINK(tmps2);
2148 if (!(anum = link(tmps,tmps2)))
2149 anum = UNLINK(tmps);
2151 value = (double)(anum >= 0);
2156 tmps = str_get(st[1]);
2157 tmps2 = str_get(st[2]);
2159 taintproper("Insecure dependency in link");
2161 value = (double)(link(tmps,tmps2) >= 0);
2164 fatal("Unsupported function link");
2168 tmps = str_get(st[1]);
2169 anum = (int)str_gnum(st[2]);
2171 taintproper("Insecure dependency in mkdir");
2174 value = (double)(mkdir(tmps,anum) >= 0);
2177 (void)strcpy(buf,"mkdir ");
2179 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
2181 for (tmps2 = buf+6; *tmps; ) {
2185 (void)strcpy(tmps2," 2>&1");
2186 rsfp = mypopen(buf,"r");
2189 tmps2 = fgets(buf,sizeof buf,rsfp);
2190 (void)mypclose(rsfp);
2191 if (tmps2 != Nullch) {
2192 for (errno = 1; errno < sys_nerr; errno++) {
2193 if (instr(buf,sys_errlist[errno])) /* you don't see this */
2198 #define EACCES EPERM
2200 if (instr(buf,"cannot make"))
2202 else if (instr(buf,"existing file"))
2204 else if (instr(buf,"ile exists"))
2206 else if (instr(buf,"non-exist"))
2208 else if (instr(buf,"does not exist"))
2210 else if (instr(buf,"not empty"))
2212 else if (instr(buf,"cannot access"))
2218 else { /* some mkdirs return no failure indication */
2219 tmps = str_get(st[1]);
2220 anum = (stat(tmps,&statbuf) >= 0);
2221 if (optype == O_RMDIR)
2226 errno = EACCES; /* a guess */
2227 value = (double)anum;
2236 tmps = str_get(stab_val(defstab));
2238 tmps = str_get(st[1]);
2240 taintproper("Insecure dependency in rmdir");
2243 value = (double)(rmdir(tmps) >= 0);
2246 (void)strcpy(buf,"rmdir ");
2247 goto one_liner; /* see above in HAS_MKDIR */
2251 value = (double)getppid();
2254 fatal("Unsupported function getppid");
2262 anum = (int)str_gnum(st[1]);
2263 value = (double)getpgrp(anum);
2266 fatal("The getpgrp() function is unimplemented on this machine");
2271 argtype = (int)str_gnum(st[1]);
2272 anum = (int)str_gnum(st[2]);
2274 taintproper("Insecure dependency in setpgrp");
2276 value = (double)(setpgrp(argtype,anum) >= 0);
2279 fatal("The setpgrp() function is unimplemented on this machine");
2283 #ifdef HAS_GETPRIORITY
2284 argtype = (int)str_gnum(st[1]);
2285 anum = (int)str_gnum(st[2]);
2286 value = (double)getpriority(argtype,anum);
2289 fatal("The getpriority() function is unimplemented on this machine");
2293 #ifdef HAS_SETPRIORITY
2294 argtype = (int)str_gnum(st[1]);
2295 anum = (int)str_gnum(st[2]);
2296 optype = (int)str_gnum(st[3]);
2298 taintproper("Insecure dependency in setpriority");
2300 value = (double)(setpriority(argtype,anum,optype) >= 0);
2303 fatal("The setpriority() function is unimplemented on this machine");
2309 tmps = str_get(stab_val(defstab));
2311 tmps = str_get(st[1]);
2313 taintproper("Insecure dependency in chroot");
2315 value = (double)(chroot(tmps) >= 0);
2318 fatal("Unsupported function chroot");
2324 stab = last_in_stab;
2325 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2326 stab = arg[1].arg_ptr.arg_stab;
2328 stab = stabent(str_get(st[1]),TRUE);
2329 argtype = U_I(str_gnum(st[2]));
2331 taintproper("Insecure dependency in ioctl");
2333 anum = do_ctl(optype,stab,argtype,st[3]);
2337 value = (double)anum;
2340 str_set(str,"0 but true");
2346 stab = last_in_stab;
2347 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2348 stab = arg[1].arg_ptr.arg_stab;
2350 stab = stabent(str_get(st[1]),TRUE);
2351 if (stab && stab_io(stab))
2352 fp = stab_io(stab)->ifp;
2356 argtype = (int)str_gnum(st[2]);
2357 value = (double)(flock(fileno(fp),argtype) >= 0);
2363 fatal("The flock() function is unimplemented on this machine");
2367 ary = stab_array(arg[1].arg_ptr.arg_stab);
2368 if (arglast[2] - arglast[1] != 1)
2369 do_unshift(ary,arglast);
2371 STR *tmpstr = Str_new(52,0); /* must copy the STR */
2372 str_sset(tmpstr,st[2]);
2374 (void)astore(ary,0,tmpstr);
2376 value = (double)(ary->ary_fill + 1);
2383 tmpstr = stab_val(defstab);
2386 (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
2388 tainted |= tmpstr->str_tainted;
2389 taintproper("Insecure dependency in eval");
2391 sp = do_eval(tmpstr, optype, curcmd->c_stash,
2419 if (mystat(arg,st[1]) < 0)
2421 if (cando(anum,argtype,&statcache))
2426 if (mystat(arg,st[1]) < 0)
2431 if (mystat(arg,st[1]) < 0)
2433 if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
2437 if (mystat(arg,st[1]) < 0)
2439 if (!statcache.st_size)
2443 if (mystat(arg,st[1]) < 0)
2445 value = (double)statcache.st_size;
2449 if (mystat(arg,st[1]) < 0)
2451 value = (double)(basetime - statcache.st_mtime) / 86400.0;
2454 if (mystat(arg,st[1]) < 0)
2456 value = (double)(basetime - statcache.st_atime) / 86400.0;
2459 if (mystat(arg,st[1]) < 0)
2461 value = (double)(basetime - statcache.st_ctime) / 86400.0;
2465 if (mystat(arg,st[1]) < 0)
2467 if (S_ISSOCK(statcache.st_mode))
2471 if (mystat(arg,st[1]) < 0)
2473 if (S_ISCHR(statcache.st_mode))
2477 if (mystat(arg,st[1]) < 0)
2479 if (S_ISBLK(statcache.st_mode))
2483 if (mystat(arg,st[1]) < 0)
2485 if (S_ISREG(statcache.st_mode))
2489 if (mystat(arg,st[1]) < 0)
2491 if (S_ISDIR(statcache.st_mode))
2495 if (mystat(arg,st[1]) < 0)
2497 if (S_ISFIFO(statcache.st_mode))
2501 if (mylstat(arg,st[1]) < 0)
2503 if (S_ISLNK(statcache.st_mode))
2508 tmps = str_get(st[1]);
2509 tmps2 = str_get(st[2]);
2511 taintproper("Insecure dependency in symlink");
2513 value = (double)(symlink(tmps,tmps2) >= 0);
2516 fatal("Unsupported function symlink");
2521 tmps = str_get(stab_val(defstab));
2523 tmps = str_get(st[1]);
2524 anum = readlink(tmps,buf,sizeof buf);
2527 str_nset(str,buf,anum);
2530 goto say_undef; /* just pretend it's a normal file */
2553 if (mystat(arg,st[1]) < 0)
2555 if (statcache.st_mode & anum)
2559 if (arg[1].arg_type & A_DONT) {
2560 stab = arg[1].arg_ptr.arg_stab;
2564 stab = stabent(tmps = str_get(st[1]),FALSE);
2565 if (stab && stab_io(stab) && stab_io(stab)->ifp)
2566 anum = fileno(stab_io(stab)->ifp);
2567 else if (isdigit(*tmps))
2576 str = do_fttext(arg,st[1]);
2580 if ((arg[1].arg_type & A_MASK) == A_WORD)
2581 stab = arg[1].arg_ptr.arg_stab;
2583 stab = stabent(str_get(st[1]),TRUE);
2585 value = (double)do_socket(stab,arglast);
2587 (void)do_socket(stab,arglast);
2591 if ((arg[1].arg_type & A_MASK) == A_WORD)
2592 stab = arg[1].arg_ptr.arg_stab;
2594 stab = stabent(str_get(st[1]),TRUE);
2596 value = (double)do_bind(stab,arglast);
2598 (void)do_bind(stab,arglast);
2602 if ((arg[1].arg_type & A_MASK) == A_WORD)
2603 stab = arg[1].arg_ptr.arg_stab;
2605 stab = stabent(str_get(st[1]),TRUE);
2607 value = (double)do_connect(stab,arglast);
2609 (void)do_connect(stab,arglast);
2613 if ((arg[1].arg_type & A_MASK) == A_WORD)
2614 stab = arg[1].arg_ptr.arg_stab;
2616 stab = stabent(str_get(st[1]),TRUE);
2618 value = (double)do_listen(stab,arglast);
2620 (void)do_listen(stab,arglast);
2624 if ((arg[1].arg_type & A_MASK) == A_WORD)
2625 stab = arg[1].arg_ptr.arg_stab;
2627 stab = stabent(str_get(st[1]),TRUE);
2628 if ((arg[2].arg_type & A_MASK) == A_WORD)
2629 stab2 = arg[2].arg_ptr.arg_stab;
2631 stab2 = stabent(str_get(st[2]),TRUE);
2632 do_accept(str,stab,stab2);
2640 sp = do_ghent(optype,
2648 sp = do_gnent(optype,
2656 sp = do_gpent(optype,
2664 sp = do_gsent(optype,
2668 value = (double) sethostent((int)str_gnum(st[1]));
2671 value = (double) setnetent((int)str_gnum(st[1]));
2674 value = (double) setprotoent((int)str_gnum(st[1]));
2677 value = (double) setservent((int)str_gnum(st[1]));
2680 value = (double) endhostent();
2683 value = (double) endnetent();
2686 value = (double) endprotoent();
2689 value = (double) endservent();
2692 if ((arg[1].arg_type & A_MASK) == A_WORD)
2693 stab = arg[1].arg_ptr.arg_stab;
2695 stab = stabent(str_get(st[1]),TRUE);
2696 if ((arg[2].arg_type & A_MASK) == A_WORD)
2697 stab2 = arg[2].arg_ptr.arg_stab;
2699 stab2 = stabent(str_get(st[2]),TRUE);
2701 value = (double)do_spair(stab,stab2,arglast);
2703 (void)do_spair(stab,stab2,arglast);
2707 if ((arg[1].arg_type & A_MASK) == A_WORD)
2708 stab = arg[1].arg_ptr.arg_stab;
2710 stab = stabent(str_get(st[1]),TRUE);
2712 value = (double)do_shutdown(stab,arglast);
2714 (void)do_shutdown(stab,arglast);
2719 if ((arg[1].arg_type & A_MASK) == A_WORD)
2720 stab = arg[1].arg_ptr.arg_stab;
2722 stab = stabent(str_get(st[1]),TRUE);
2723 sp = do_sopt(optype,stab,arglast);
2727 if ((arg[1].arg_type & A_MASK) == A_WORD)
2728 stab = arg[1].arg_ptr.arg_stab;
2730 stab = stabent(str_get(st[1]),TRUE);
2733 sp = do_getsockname(optype,stab,arglast);
2736 #else /* HAS_SOCKET not defined */
2769 fatal("Unsupported socket function");
2770 #endif /* HAS_SOCKET */
2773 sp = do_select(gimme,arglast);
2776 fatal("select not implemented");
2781 if ((arg[1].arg_type & A_MASK) == A_WORD)
2782 stab = arg[1].arg_ptr.arg_stab;
2784 stab = stabent(str_get(st[1]),TRUE);
2785 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2792 if ((arg[1].arg_type & A_MASK) == A_WORD)
2793 stab = arg[1].arg_ptr.arg_stab;
2795 stab = stabent(str_get(st[1]),TRUE);
2796 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2799 str_set(str, (setmode(fileno(fp), O_BINARY) != -1) ? Yes : No);
2806 sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
2812 sp = do_gpwent(optype,
2816 value = (double) setpwent();
2819 value = (double) endpwent();
2824 fatal("Unsupported password function");
2831 sp = do_ggrent(optype,
2835 value = (double) setgrent();
2838 value = (double) endgrent();
2843 fatal("Unsupported group function");
2848 if (!(tmps = getlogin()))
2852 fatal("Unsupported function getlogin");
2863 if ((arg[1].arg_type & A_MASK) == A_WORD)
2864 stab = arg[1].arg_ptr.arg_stab;
2866 stab = stabent(str_get(st[1]),TRUE);
2869 sp = do_dirop(optype,stab,gimme,arglast);
2872 value = (double)do_syscall(arglast);
2876 if ((arg[1].arg_type & A_MASK) == A_WORD)
2877 stab = arg[1].arg_ptr.arg_stab;
2879 stab = stabent(str_get(st[1]),TRUE);
2880 if ((arg[2].arg_type & A_MASK) == A_WORD)
2881 stab2 = arg[2].arg_ptr.arg_stab;
2883 stab2 = stabent(str_get(st[2]),TRUE);
2884 do_pipe(str,stab,stab2);
2887 fatal("Unsupported function pipe");
2898 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2901 return arglast[0] + 1;