1 /* $RCSfile: eval.c,v $$Revision: 4.0.1.3 $$Date: 91/11/05 17:15:21 $
3 * Copyright (c) 1991, 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.
9 * Revision 4.0.1.3 91/11/05 17:15:21 lwall
10 * patch11: prepared for ctype implementations that don't define isascii()
11 * patch11: various portability fixes
12 * patch11: added sort {} LIST
13 * patch11: added eval {}
14 * patch11: sysread() in socket was substituting recv()
15 * patch11: a last statement outside any block caused occasional core dumps
16 * patch11: missing arguments caused core dump in -D8 code
17 * patch11: eval 'stuff' now optimized to eval {stuff}
19 * Revision 4.0.1.2 91/06/07 11:07:23 lwall
20 * patch4: new copyright notice
21 * patch4: length($`), length($&), length($') now optimized to avoid string copy
22 * patch4: assignment wasn't correctly de-tainting the assigned variable.
23 * patch4: default top-of-form format is now FILEHANDLE_TOP
24 * patch4: added $^P variable to control calling of perldb routines
25 * patch4: taintchecks could improperly modify parent in vfork()
26 * patch4: many, many itty-bitty portability fixes
28 * Revision 4.0.1.1 91/04/11 17:43:48 lwall
29 * patch1: fixed failed fork to return undef as documented
30 * patch1: reduced maximum branch distance in eval.c
32 * Revision 4.0 91/03/20 01:16:48 lwall
40 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
55 static void (*ihand)();
56 static void (*qhand)();
58 static int (*ihand)();
59 static int (*qhand)();
66 static struct lstring *lstr;
67 static int old_rschar;
70 double sin(), cos(), atan2(), pow();
91 int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
92 unsigned long tmplong;
99 bool assigning = FALSE;
100 double exp(), log(), sqrt(), modf();
101 char *crypt(), *getenv();
102 extern void grow_dlevel();
106 optype = arg->arg_type;
107 maxarg = arg->arg_len;
109 str = arg->arg_ptr.arg_str;
110 if (sp + maxarg > stack->ary_max)
111 astore(stack, sp + maxarg, Nullstr);
112 st = stack->ary_array;
117 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
119 debname[dlevel] = opname[optype][0];
120 debdelim[dlevel] = ':';
121 if (++dlevel >= dlmax)
126 for (anum = 1; anum <= maxarg; anum++) {
127 argflags = arg[anum].arg_flags;
128 argtype = arg[anum].arg_type;
129 argptr = arg[anum].arg_ptr;
133 st[++sp] = &str_undef;
142 deb("%d.EXPR =>\n",anum);
145 sp = eval(argptr.arg_arg,
146 (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp);
147 if (sp + (maxarg - anum) > stack->ary_max)
148 astore(stack, sp + (maxarg - anum), Nullstr);
149 st = stack->ary_array; /* possibly reallocated */
155 deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
158 sp = cmd_exec(argptr.arg_cmd, gimme, sp);
159 if (sp + (maxarg - anum) > stack->ary_max)
160 astore(stack, sp + (maxarg - anum), Nullstr);
161 st = stack->ary_array; /* possibly reallocated */
166 case O_ITEM2: argtype = 2; break;
167 case O_ITEM3: argtype = 3; break;
168 default: argtype = anum; break;
170 str = afetch(stab_array(argptr.arg_stab),
171 arg[argtype].arg_len - arybase, TRUE);
174 (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
175 arg[argtype].arg_len);
182 case O_ITEM2: argtype = 2; break;
183 case O_ITEM3: argtype = 3; break;
184 default: argtype = anum; break;
186 st[++sp] = afetch(stab_array(argptr.arg_stab),
187 arg[argtype].arg_len - arybase, FALSE);
190 (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
191 arg[argtype].arg_len);
197 stab = argptr.arg_stab;
198 st[++sp] = (STR*)stab;
199 if (!stab_xarray(stab))
201 if (!stab_xhash(stab))
204 stab_io(stab) = stio_new();
207 (void)sprintf(buf,"STAR *%s",stab_name(argptr.arg_stab));
213 str = st[++sp] = (STR*)argptr.arg_stab;
216 (void)sprintf(buf,"LSTAR *%s",stab_name(argptr.arg_stab));
222 st[++sp] = STAB_STR(argptr.arg_stab);
225 (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab));
231 str_numset(str, (double)STAB_LEN(argptr.arg_stab));
235 (void)sprintf(buf,"LENSTAB $%s",stab_name(argptr.arg_stab));
244 deb("%d.LEXPR =>\n",anum);
247 if (argflags & AF_ARYOK) {
248 sp = eval(argptr.arg_arg, G_ARRAY, sp);
249 if (sp + (maxarg - anum) > stack->ary_max)
250 astore(stack, sp + (maxarg - anum), Nullstr);
251 st = stack->ary_array; /* possibly reallocated */
254 sp = eval(argptr.arg_arg, G_SCALAR, sp);
255 st = stack->ary_array; /* possibly reallocated */
263 (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab));
268 str = STAB_STR(argptr.arg_stab);
270 fatal("panic: A_LVAL");
273 if (argflags & AF_PRE) {
274 if (argflags & AF_UP)
280 str = arg->arg_ptr.arg_str;
282 else if (argflags & AF_POST) {
283 st[sp] = str_mortal(str);
284 if (argflags & AF_UP)
289 str = arg->arg_ptr.arg_str;
296 stab = argptr.arg_stab;
297 str = stab_array(argptr.arg_stab)->ary_magic;
298 if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
299 str_numset(str,(double)(stab_array(stab)->ary_fill+arybase));
304 fatal("panic: A_LEXPR");
307 stab = argptr.arg_stab;
308 st[++sp] = stab_array(stab)->ary_magic;
309 str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase));
315 st[++sp] = argptr.arg_str;
321 (void) interp(str,argptr.arg_str,sp);
322 st = stack->ary_array;
329 tmps = str_get(interp(str,argptr.arg_str,sp));
330 st = stack->ary_array;
332 taintproper("Insecure dependency in ``");
334 fp = mypopen(tmps,"r");
337 if (gimme == G_SCALAR) {
338 while (str_gets(str,fp,str->str_cur) != Nullch)
344 if (++sp > stack->ary_max) {
345 astore(stack, sp, Nullstr);
346 st = stack->ary_array;
348 str = st[sp] = Str_new(56,80);
349 if (str_gets(str,fp,0) == Nullch) {
353 if (str->str_len - str->str_cur > 20) {
354 str->str_len = str->str_cur+1;
355 Renew(str->str_ptr, str->str_len, char);
360 statusvalue = mypclose(fp);
365 if (gimme == G_SCALAR)
373 if (curcsv->wantarray == G_ARRAY)
383 last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
388 argflags |= AF_POST; /* enable newline chopping */
389 last_in_stab = argptr.arg_stab;
404 last_in_stab = argptr.arg_stab;
408 if (anum > 1) /* assign to scalar */
409 gimme = G_SCALAR; /* force context to scalar */
410 if (gimme == G_ARRAY)
414 if (stab_io(last_in_stab)) {
415 fp = stab_io(last_in_stab)->ifp;
417 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
418 if (stab_io(last_in_stab)->flags & IOF_START) {
419 stab_io(last_in_stab)->flags &= ~IOF_START;
420 stab_io(last_in_stab)->lines = 0;
421 if (alen(stab_array(last_in_stab)) < 0) {
422 tmpstr = str_make("-",1); /* assume stdin */
423 (void)apush(stab_array(last_in_stab), tmpstr);
426 fp = nextargv(last_in_stab);
427 if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
428 (void)do_close(last_in_stab,FALSE); /* now it does*/
429 stab_io(last_in_stab)->flags |= IOF_START;
432 else if (argtype == A_GLOB) {
433 (void) interp(str,stab_val(last_in_stab),sp);
434 st = stack->ary_array;
435 tmpstr = Str_new(55,0);
437 str_set(tmpstr, "perlglob ");
438 str_scat(tmpstr,str);
439 str_cat(tmpstr," |");
442 str_nset(tmpstr,cshname,cshlen);
443 str_cat(tmpstr," -cf 'set nonomatch; glob ");
444 str_scat(tmpstr,str);
445 str_cat(tmpstr,"'|");
447 str_set(tmpstr, "echo ");
448 str_scat(tmpstr,str);
450 "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
453 (void)do_open(last_in_stab,tmpstr->str_ptr,
455 fp = stab_io(last_in_stab)->ifp;
461 warn("Read on closed filehandle <%s>",stab_name(last_in_stab));
462 when = str->str_len; /* remember if already alloced */
464 Str_Grow(str,80); /* try short-buffering it */
468 else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) {
470 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
471 fp = nextargv(last_in_stab);
474 (void)do_close(last_in_stab,FALSE);
475 stab_io(last_in_stab)->flags |= IOF_START;
477 else if (argflags & AF_POST) {
478 (void)do_close(last_in_stab,FALSE);
483 if (gimme == G_ARRAY) {
491 stab_io(last_in_stab)->lines++;
494 str->str_tainted = 1; /* Anything from the outside world...*/
496 if (argflags & AF_POST) {
497 if (str->str_cur > 0)
499 if (str->str_ptr[str->str_cur] == rschar)
500 str->str_ptr[str->str_cur] = '\0';
503 for (tmps = str->str_ptr; *tmps; tmps++)
504 if (!isALPHA(*tmps) && !isDIGIT(*tmps) &&
505 index("$&*(){}[]'\";\\|?<>~`",*tmps))
507 if (*tmps && stat(str->str_ptr,&statbuf) < 0)
508 goto keepgoing; /* unmatched wildcard? */
510 if (gimme == G_ARRAY) {
511 if (str->str_len - str->str_cur > 20) {
512 str->str_len = str->str_cur+1;
513 Renew(str->str_ptr, str->str_len, char);
516 if (++sp > stack->ary_max) {
517 astore(stack, sp, Nullstr);
518 st = stack->ary_array;
520 str = Str_new(58,80);
523 else if (!when && str->str_len - str->str_cur > 80) {
524 /* try to reclaim a bit of scalar space on 1st alloc */
525 if (str->str_cur < 60)
528 str->str_len = str->str_cur+40; /* allow some slop */
529 Renew(str->str_ptr, str->str_len, char);
541 deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));
549 if (optype < O_CHOWN)
556 if (gimme == G_ARRAY)
564 if (gimme == G_ARRAY)
567 STR_SSET(str,st[arglast[anum]-arglast[0]]);
571 if (gimme == G_ARRAY)
574 STR_SSET(str,st[arglast[anum]-arglast[0]]);
583 if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {
584 sp = do_repeatary(arglast);
587 STR_SSET(str,st[arglast[1] - arglast[0]]);
588 anum = (int)str_gnum(st[arglast[2] - arglast[0]]);
590 tmpstr = Str_new(50, 0);
592 str_nset(tmpstr,tmps,str->str_cur);
593 tmps = str_get(tmpstr); /* force to be string */
594 STR_GROW(str, (anum * str->str_cur) + 1);
595 repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
596 str->str_cur *= anum;
597 str->str_ptr[str->str_cur] = '\0';
602 str_sset(str,&str_no);
606 sp = do_match(str,arg,
608 if (gimme == G_ARRAY)
613 sp = do_match(str,arg,
615 str_sset(str, str_true(str) ? &str_no : &str_yes);
619 sp = do_subst(str,arg,arglast[0]);
622 sp = do_subst(str,arg,arglast[0]);
623 str = arg->arg_ptr.arg_str;
624 str_set(str, str_true(str) ? No : Yes);
627 if (arg[1].arg_flags & AF_ARYOK) {
628 if (arg->arg_len == 1) {
629 arg->arg_type = O_LOCAL;
633 arg->arg_type = O_AASSIGN;
638 arg->arg_type = O_SASSIGN;
643 arglast[2] = arglast[1]; /* push a null array */
653 if (tainted && !st[2]->str_tainted)
656 STR_SSET(str, st[2]);
661 str = arg->arg_ptr.arg_str;
662 for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
667 if (arg[1].arg_type & A_DONT) {
668 sp = do_defined(str,arg,
672 else if (str->str_pok || str->str_nok)
676 if (arg[1].arg_type & A_DONT) {
677 sp = do_undef(str,arg,
681 else if (str != stab_val(defstab)) {
683 if (str->str_state == SS_INCR)
685 Safefree(str->str_ptr);
686 str->str_ptr = Nullch;
689 str->str_pok = str->str_nok = 0;
694 sp = do_study(str,arg,
698 value = str_gnum(st[1]);
699 value = pow(value,str_gnum(st[2]));
702 value = str_gnum(st[1]);
703 value *= str_gnum(st[2]);
706 if ((value = str_gnum(st[2])) == 0.0)
707 fatal("Illegal division by zero");
709 /* insure that 20./5. == 4. */
714 if ((double)(int)x == x &&
715 (double)(int)value == value &&
716 (k = (int)x/(int)value)*(int)value == (int)x) {
723 value = str_gnum(st[1]) / value;
727 tmplong = (long) str_gnum(st[2]);
729 fatal("Illegal modulus zero");
730 when = (long)str_gnum(st[1]);
733 value = (double)(when % tmplong);
735 value = (double)(tmplong - ((-when - 1) % tmplong)) - 1;
739 value = str_gnum(st[1]);
740 value += str_gnum(st[2]);
743 value = str_gnum(st[1]);
744 value -= str_gnum(st[2]);
747 value = str_gnum(st[1]);
748 anum = (int)str_gnum(st[2]);
750 value = (double)(U_L(value) << anum);
754 value = str_gnum(st[1]);
755 anum = (int)str_gnum(st[2]);
757 value = (double)(U_L(value) >> anum);
761 value = str_gnum(st[1]);
762 value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
765 value = str_gnum(st[1]);
766 value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
769 value = str_gnum(st[1]);
770 value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
773 value = str_gnum(st[1]);
774 value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
778 if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
779 (!st[2]->str_nok && !looks_like_number(st[2])) )
780 warn("Possible use of == on string value");
782 value = str_gnum(st[1]);
783 value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
786 value = str_gnum(st[1]);
787 value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
790 value = str_gnum(st[1]);
791 value -= str_gnum(st[2]);
794 else if (value < 0.0)
798 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
799 value = str_gnum(st[1]);
801 value = (double)(U_L(value) & U_L(str_gnum(st[2])));
806 do_vop(optype,str,st[1],st[2]);
809 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
810 value = str_gnum(st[1]);
812 value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));
817 do_vop(optype,str,st[1],st[2]);
820 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
821 value = str_gnum(st[1]);
823 value = (double)(U_L(value) | U_L(str_gnum(st[2])));
828 do_vop(optype,str,st[1],st[2]);
830 /* use register in evaluating str_true() */
832 if (str_true(st[1])) {
835 argflags = arg[anum].arg_flags;
836 if (gimme == G_ARRAY)
837 argflags |= AF_ARYOK;
838 argtype = arg[anum].arg_type & A_MASK;
839 argptr = arg[anum].arg_ptr;
847 str_sset(str, st[1]);
855 if (str_true(st[1])) {
857 str_sset(str, st[1]);
867 argflags = arg[anum].arg_flags;
868 if (gimme == G_ARRAY)
869 argflags |= AF_ARYOK;
870 argtype = arg[anum].arg_type & A_MASK;
871 argptr = arg[anum].arg_ptr;
878 anum = (str_true(st[1]) ? 2 : 3);
879 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
880 argflags = arg[anum].arg_flags;
881 if (gimme == G_ARRAY)
882 argflags |= AF_ARYOK;
883 argtype = arg[anum].arg_type & A_MASK;
884 argptr = arg[anum].arg_ptr;
890 if (gimme == G_ARRAY)
895 value = -str_gnum(st[1]);
899 { char xxx = str_true(st[1]); value = (double) !xxx; }
901 value = (double) !str_true(st[1]);
905 if (!sawvec || st[1]->str_nok) {
907 value = (double) ~U_L(str_gnum(st[1]));
914 for (anum = str->str_cur; anum; anum--, tmps++)
919 stab_fullname(str,defoutstab);
921 if ((arg[1].arg_type & A_MASK) == A_WORD)
922 defoutstab = arg[1].arg_ptr.arg_stab;
924 defoutstab = stabent(str_get(st[1]),TRUE);
925 if (!stab_io(defoutstab))
926 stab_io(defoutstab) = stio_new();
927 curoutstab = defoutstab;
934 else if ((arg[1].arg_type & A_MASK) == A_WORD) {
935 if (!(stab = arg[1].arg_ptr.arg_stab))
939 stab = stabent(str_get(st[1]),TRUE);
940 if (!stab_io(stab)) {
946 fp = stab_io(stab)->ofp;
948 if (stab_io(stab)->fmt_stab)
949 form = stab_form(stab_io(stab)->fmt_stab);
951 form = stab_form(stab);
955 warn("No format for filehandle");
957 if (stab_io(stab)->ifp)
958 warn("Filehandle only opened for input");
960 warn("Write on closed filehandle");
967 format(&outrec,form,sp);
968 do_write(&outrec,stab,sp);
969 if (stab_io(stab)->flags & IOF_FLUSH)
976 anum = arg[1].arg_type & A_MASK;
977 if (anum == A_WORD || anum == A_STAB)
978 stab = arg[1].arg_ptr.arg_stab;
980 stab = stabent(str_get(st[1]),TRUE);
981 if (st[3]->str_nok || st[3]->str_pok)
982 anum = (int)str_gnum(st[3]);
985 value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
988 fatal("No dbm or ndbm on this machine");
992 if ((arg[1].arg_type & A_MASK) == A_WORD)
993 stab = arg[1].arg_ptr.arg_stab;
995 stab = stabent(str_get(st[1]),TRUE);
996 hdbmclose(stab_hash(stab));
999 fatal("No dbm or ndbm on this machine");
1002 if ((arg[1].arg_type & A_MASK) == A_WORD)
1003 stab = arg[1].arg_ptr.arg_stab;
1005 stab = stabent(str_get(st[1]),TRUE);
1006 tmps = str_get(st[2]);
1007 if (do_open(stab,tmps,st[2]->str_cur)) {
1008 value = (double)forkprocess;
1009 stab_io(stab)->lines = 0;
1012 else if (forkprocess == 0) /* we are a new child */
1018 value = (double) do_trans(str,arg);
1019 str = arg->arg_ptr.arg_str;
1022 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
1023 str = arg->arg_ptr.arg_str;
1028 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1029 stab = arg[1].arg_ptr.arg_stab;
1031 stab = stabent(str_get(st[1]),TRUE);
1032 str_set(str, do_close(stab,TRUE) ? Yes : No );
1036 sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
1041 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1045 str->str_nok = str->str_pok = 0;
1046 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1047 str->str_state = SS_ARY;
1050 ary = stab_array(arg[1].arg_ptr.arg_stab);
1051 maxarg = ary->ary_fill + 1;
1052 if (gimme == G_ARRAY) { /* array wanted */
1055 if (maxarg > 0 && sp + maxarg > stack->ary_max) {
1056 astore(stack,sp + maxarg, Nullstr);
1057 st = stack->ary_array;
1060 Copy(ary->ary_array, &st[1], maxarg, STR*);
1065 value = (double)maxarg;
1069 anum = ((int)str_gnum(st[2])) - arybase;
1070 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
1073 tmpstab = arg[1].arg_ptr.arg_stab;
1074 tmps = str_get(st[2]);
1075 str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
1076 if (tmpstab == envstab)
1077 setenv(tmps,Nullch);
1082 str->str_nok = str->str_pok = 0;
1083 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1084 str->str_state = SS_HASH;
1087 if (gimme == G_ARRAY) { /* array wanted */
1088 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1093 tmpstab = arg[1].arg_ptr.arg_stab;
1094 if (!stab_hash(tmpstab)->tbl_fill)
1096 sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
1097 stab_hash(tmpstab)->tbl_max+1);
1102 tmpstab = arg[1].arg_ptr.arg_stab;
1103 tmps = str_get(st[2]);
1104 str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
1107 anum = ((int)str_gnum(st[2])) - arybase;
1108 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
1109 if (!str || str == &str_undef)
1110 fatal("Assignment to non-creatable value, subscript %d",anum);
1113 tmpstab = arg[1].arg_ptr.arg_stab;
1114 tmps = str_get(st[2]);
1115 anum = st[2]->str_cur;
1116 str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
1117 if (!str || str == &str_undef)
1118 fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
1119 if (tmpstab == envstab) /* heavy wizardry going on here */
1120 str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
1121 /* he threw the brick up into the air */
1122 else if (tmpstab == sigstab)
1123 str_magic(str, tmpstab, 'S', tmps, anum);
1125 else if (stab_hash(tmpstab)->tbl_dbm)
1126 str_magic(str, tmpstab, 'D', tmps, anum);
1128 else if (tmpstab == DBline)
1129 str_magic(str, tmpstab, 'L', tmps, anum);
1134 goto do_slice_already;
1138 goto do_slice_already;
1142 goto do_slice_already;
1146 goto do_slice_already;
1151 sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
1155 sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast);
1158 if (arglast[2] - arglast[1] != 1)
1159 str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
1161 str = Str_new(51,0); /* must copy the STR */
1162 str_sset(str,st[2]);
1163 (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
1167 str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
1168 goto staticalization;
1170 str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
1174 if (ary->ary_flags & ARF_REAL)
1175 (void)str_2mortal(str);
1178 sp = do_unpack(str,gimme,arglast);
1181 value = str_gnum(st[3]);
1182 sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
1187 value = (double)str_len(stab_val(defstab));
1189 value = (double)str_len(st[1]);
1192 do_sprintf(str, sp-arglast[0], st+1);
1195 anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
1196 tmps = str_get(st[1]); /* force conversion to string */
1198 if (argtype = (str == st[1]))
1199 str = arg->arg_ptr.arg_str;
1201 anum += st[1]->str_cur + arybase;
1202 if (anum < 0 || anum > st[1]->str_cur)
1205 optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]);
1209 anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
1212 str_nset(str, tmps, anum);
1213 if (argtype) { /* it's an lvalue! */
1214 lstr = (struct lstring*)str;
1215 str->str_magic = st[1];
1216 st[1]->str_rare = 's';
1217 lstr->lstr_offset = tmps - str_get(st[1]);
1218 lstr->lstr_len = anum;
1224 (void)do_pack(str,arglast);
1227 sp = do_grep(arg,str,gimme,arglast);
1230 do_join(str,arglast);
1233 tmps = str_get(st[1]);
1234 value = (double) (str_cmp(st[1],st[2]) < 0);
1237 tmps = str_get(st[1]);
1238 value = (double) (str_cmp(st[1],st[2]) > 0);
1241 tmps = str_get(st[1]);
1242 value = (double) (str_cmp(st[1],st[2]) <= 0);
1245 tmps = str_get(st[1]);
1246 value = (double) (str_cmp(st[1],st[2]) >= 0);
1249 tmps = str_get(st[1]);
1250 value = (double) str_eq(st[1],st[2]);
1253 tmps = str_get(st[1]);
1254 value = (double) !str_eq(st[1],st[2]);
1257 tmps = str_get(st[1]);
1258 value = (double) str_cmp(st[1],st[2]);
1261 sp = do_subr(arg,gimme,arglast);
1262 st = stack->ary_array + arglast[0]; /* maybe realloced */
1265 sp = do_subr(arg,gimme,arglast);
1266 st = stack->ary_array + arglast[0]; /* maybe realloced */
1269 sp = do_caller(arg,maxarg,gimme,arglast);
1270 st = stack->ary_array + arglast[0]; /* maybe realloced */
1273 sp = do_sort(str,arg,
1277 if (gimme == G_ARRAY)
1278 sp = do_reverse(arglast);
1280 sp = do_sreverse(str, arglast);
1283 if (arglast[2] - arglast[1] != 1) {
1284 do_join(str,arglast);
1285 tmps = str_get(str);
1289 tmps = str_get(st[2]);
1291 if (!tmps || !*tmps)
1292 tmps = "Warning: something's wrong";
1296 if (arglast[2] - arglast[1] != 1) {
1297 do_join(str,arglast);
1298 tmps = str_get(str);
1302 tmps = str_get(st[2]);
1304 if (!tmps || !*tmps)
1310 if ((arg[1].arg_type & A_MASK) == A_WORD)
1311 stab = arg[1].arg_ptr.arg_stab;
1313 stab = stabent(str_get(st[1]),TRUE);
1316 if (!stab_io(stab)) {
1318 warn("Filehandle never opened");
1321 if (!(fp = stab_io(stab)->ofp)) {
1323 if (stab_io(stab)->ifp)
1324 warn("Filehandle opened only for input");
1326 warn("Print on closed filehandle");
1331 if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
1332 value = (double)do_aprint(arg,fp,arglast);
1334 value = (double)do_print(st[2],fp);
1335 if (orslen && optype == O_PRINT)
1336 if (fwrite(ors, 1, orslen, fp) == 0)
1339 if (stab_io(stab)->flags & IOF_FLUSH)
1340 if (fflush(fp) == EOF)
1348 tmps = str_get(st[1]);
1349 if (!tmps || !*tmps) {
1350 tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
1351 tmps = str_get(tmpstr);
1353 if (!tmps || !*tmps) {
1354 tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
1355 tmps = str_get(tmpstr);
1358 taintproper("Insecure dependency in chdir");
1360 value = (double)(chdir(tmps) >= 0);
1366 anum = (int)str_gnum(st[1]);
1373 tmps = str_get(st[1]);
1374 str_reset(tmps,curcmd->c_stash);
1378 if (gimme == G_ARRAY)
1381 str = st[sp - arglast[0]]; /* unwanted list, return last item */
1387 stab = last_in_stab;
1388 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1389 stab = arg[1].arg_ptr.arg_stab;
1391 stab = stabent(str_get(st[1]),TRUE);
1392 str_set(str, do_eof(stab) ? Yes : No);
1398 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1399 stab = arg[1].arg_ptr.arg_stab;
1401 stab = stabent(str_get(st[1]),TRUE);
1404 if (!stab || do_eof(stab)) /* make sure we have fp with something */
1411 *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
1417 stab = last_in_stab;
1418 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1419 stab = arg[1].arg_ptr.arg_stab;
1421 stab = stabent(str_get(st[1]),TRUE);
1423 value = (double)do_tell(stab);
1425 (void)do_tell(stab);
1431 if ((arg[1].arg_type & A_MASK) == A_WORD)
1432 stab = arg[1].arg_ptr.arg_stab;
1434 stab = stabent(str_get(st[1]),TRUE);
1435 tmps = str_get(st[2]);
1436 anum = (int)str_gnum(st[3]);
1438 maxarg = sp - arglast[0];
1440 warn("Too many args on read");
1442 maxarg = (int)str_gnum(st[4]);
1445 if (!stab_io(stab) || !stab_io(stab)->ifp)
1448 if (optype == O_RECV) {
1449 argtype = sizeof buf;
1450 STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
1451 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg,
1454 st[2]->str_cur = anum;
1455 st[2]->str_ptr[anum] = '\0';
1456 str_nset(str,buf,argtype);
1459 str_sset(str,&str_undef);
1463 if (optype == O_RECV)
1466 STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2])); /* sneaky */
1467 if (optype == O_SYSREAD) {
1468 anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum);
1472 if (stab_io(stab)->type == 's') {
1473 argtype = sizeof buf;
1474 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0,
1479 anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp);
1482 st[2]->str_cur = anum+maxarg;
1483 st[2]->str_ptr[anum+maxarg] = '\0';
1484 value = (double)anum;
1488 if ((arg[1].arg_type & A_MASK) == A_WORD)
1489 stab = arg[1].arg_ptr.arg_stab;
1491 stab = stabent(str_get(st[1]),TRUE);
1492 tmps = str_get(st[2]);
1493 anum = (int)str_gnum(st[3]);
1495 stio = stab_io(stab);
1496 maxarg = sp - arglast[0];
1497 if (!stio || !stio->ifp) {
1500 if (optype == O_SYSWRITE)
1501 warn("Syswrite on closed filehandle");
1503 warn("Send on closed socket");
1506 else if (optype == O_SYSWRITE) {
1508 warn("Too many args on syswrite");
1510 optype = (int)str_gnum(st[4]);
1513 anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum);
1516 else if (maxarg >= 4) {
1518 warn("Too many args on send");
1519 tmps2 = str_get(st[4]);
1520 anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
1521 anum, tmps2, st[4]->str_cur);
1524 anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
1531 value = (double)anum;
1534 if ((arg[1].arg_type & A_MASK) == A_WORD)
1535 stab = arg[1].arg_ptr.arg_stab;
1537 stab = stabent(str_get(st[1]),TRUE);
1538 value = str_gnum(st[2]);
1539 str_set(str, do_seek(stab,
1540 (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
1544 tmps = "_SUB_"; /* just fake up a "last _SUB_" */
1546 if (curcsv && curcsv->wantarray == G_ARRAY) {
1547 lastretstr = Nullstr;
1548 lastspbase = arglast[1];
1549 lastsize = arglast[2] - arglast[1];
1552 lastretstr = str_mortal(st[arglast[2] - arglast[0]]);
1559 tmps = str_get(arg[1].arg_ptr.arg_str);
1561 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1562 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1565 deb("(Skipping label #%d %s)\n",loop_ptr,
1566 loop_stack[loop_ptr].loop_label);
1573 deb("(Found label #%d %s)\n",loop_ptr,
1574 loop_stack[loop_ptr].loop_label);
1579 if (tmps && strEQ(tmps, "_SUB_"))
1580 fatal("Can't return outside a subroutine");
1581 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
1583 if (!lastretstr && optype == O_LAST && lastsize) {
1585 st += lastspbase + 1;
1586 optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
1588 for (anum = lastsize; anum > 0; anum--,st++)
1589 st[optype] = str_mortal(st[0]);
1591 longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
1593 longjmp(loop_stack[loop_ptr].loop_env, optype);
1595 case O_GOTO:/* shudder */
1596 goto_targ = str_get(arg[1].arg_ptr.arg_str);
1598 goto_targ = Nullch; /* just restart from top */
1599 if (optype == O_DUMP) {
1603 longjmp(top_env, 1);
1605 tmps = str_get(st[1]);
1609 anum = (int) str_gnum(st[3]) - arybase;
1612 else if (anum > st[1]->str_cur)
1613 anum = st[1]->str_cur;
1616 if (!(tmps2 = fbminstr((unsigned char*)tmps + anum,
1617 (unsigned char*)tmps + st[1]->str_cur, st[2])))
1619 if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
1621 value = (double)(-1 + arybase);
1623 value = (double)(tmps2 - tmps + arybase);
1626 tmps = str_get(st[1]);
1627 tmps2 = str_get(st[2]);
1629 anum = st[1]->str_cur;
1631 anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur;
1634 else if (anum > st[1]->str_cur)
1635 anum = st[1]->str_cur;
1638 if (!(tmps2 = rninstr(tmps, tmps + anum,
1639 tmps2, tmps2 + st[2]->str_cur)))
1641 if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
1643 value = (double)(-1 + arybase);
1645 value = (double)(tmps2 - tmps + arybase);
1649 value = (double) time(Null(long*));
1653 sp = do_tms(str,gimme,arglast);
1659 when = (long)str_gnum(st[1]);
1660 sp = do_time(str,localtime(&when),
1667 when = (long)str_gnum(st[1]);
1668 sp = do_time(str,gmtime(&when),
1672 sp = do_truncate(str,arg,
1677 sp = do_stat(str,arg,
1682 tmps = str_get(st[1]);
1684 str_set(str,fcrypt(tmps,str_get(st[2])));
1686 str_set(str,crypt(tmps,str_get(st[2])));
1690 "The crypt() function is unimplemented due to excessive paranoia.");
1694 value = str_gnum(st[1]);
1695 value = atan2(value,str_gnum(st[2]));
1699 value = str_gnum(stab_val(defstab));
1701 value = str_gnum(st[1]);
1706 value = str_gnum(stab_val(defstab));
1708 value = str_gnum(st[1]);
1715 value = str_gnum(st[1]);
1719 value = rand() * value / 2147483648.0;
1722 value = rand() * value / 65536.0;
1725 value = rand() * value / 32768.0;
1727 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1738 anum = (int)str_gnum(st[1]);
1743 value = str_gnum(stab_val(defstab));
1745 value = str_gnum(st[1]);
1750 value = str_gnum(stab_val(defstab));
1752 value = str_gnum(st[1]);
1754 fatal("Can't take log of %g\n", value);
1759 value = str_gnum(stab_val(defstab));
1761 value = str_gnum(st[1]);
1763 fatal("Can't take sqrt of %g\n", value);
1764 value = sqrt(value);
1768 value = str_gnum(stab_val(defstab));
1770 value = str_gnum(st[1]);
1772 (void)modf(value,&value);
1774 (void)modf(-value,&value);
1780 tmps = str_get(stab_val(defstab));
1782 tmps = str_get(st[1]);
1784 value = (double) (*tmps & 255);
1787 value = (double) (anum & 255);
1793 tmps = str_get(stab_val(defstab));
1795 tmps = str_get(st[1]);
1798 anum = alarm((unsigned int)atoi(tmps));
1801 value = (double)anum;
1804 fatal("Unsupported function alarm");
1811 tmps = str_get(st[1]);
1813 if (!tmps || !*tmps)
1814 sleep((32767<<16)+32767);
1816 sleep((unsigned int)atoi(tmps));
1818 value = (double)when;
1820 value = ((double)when) - value;
1824 sp = do_range(gimme,arglast);
1827 if (gimme == G_ARRAY) { /* it's a range */
1828 /* can we optimize to constant array? */
1829 if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
1830 (arg[2].arg_type & A_MASK) == A_SINGLE) {
1831 st[2] = arg[2].arg_ptr.arg_str;
1832 sp = do_range(gimme,arglast);
1833 st = stack->ary_array;
1834 maxarg = sp - arglast[0];
1835 str_free(arg[1].arg_ptr.arg_str);
1836 arg[1].arg_ptr.arg_str = Nullstr;
1837 str_free(arg[2].arg_ptr.arg_str);
1838 arg[2].arg_ptr.arg_str = Nullstr;
1839 arg->arg_type = O_ARRAY;
1840 arg[1].arg_type = A_STAB|A_DONT;
1842 stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
1843 ary = stab_array(stab);
1844 afill(ary,maxarg - 1);
1847 while (maxarg-- > 0)
1848 ary->ary_array[maxarg] = str_smake(st[maxarg]);
1852 arg->arg_type = optype = O_RANGE;
1853 maxarg = arg->arg_len = 2;
1855 arg[anum].arg_flags &= ~AF_ARYOK;
1856 argflags = arg[anum].arg_flags;
1857 argtype = arg[anum].arg_type & A_MASK;
1858 arg[anum].arg_type = argtype;
1859 argptr = arg[anum].arg_ptr;
1865 arg->arg_type = O_FLIP;
1868 if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
1869 last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
1872 str_numset(str,0.0);
1874 arg->arg_type = optype = O_FLOP;
1875 arg[2].arg_type &= ~A_DONT;
1876 arg[1].arg_type |= A_DONT;
1877 argflags = arg[2].arg_flags;
1878 argtype = arg[2].arg_type & A_MASK;
1879 argptr = arg[2].arg_ptr;
1888 if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
1889 last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
1892 arg->arg_type = O_FLIP;
1893 arg[1].arg_type &= ~A_DONT;
1894 arg[2].arg_type |= A_DONT;
1905 if (tmpstab = stabent("$",allstabs))
1906 str_numset(STAB_STR(tmpstab),(double)getpid());
1907 hclear(pidstatus, FALSE); /* no kids, so don't wait for 'em */
1909 value = (double)anum;
1912 fatal("Unsupported function fork");
1918 anum = wait(&argflags);
1920 pidgone(anum,argflags);
1921 value = (double)anum;
1923 statusvalue = (unsigned short)argflags;
1926 fatal("Unsupported function wait");
1932 anum = (int)str_gnum(st[1]);
1933 optype = (int)str_gnum(st[2]);
1934 anum = wait4pid(anum, &argflags,optype);
1935 value = (double)anum;
1937 statusvalue = (unsigned short)argflags;
1940 fatal("Unsupported function wait");
1946 if (arglast[2] - arglast[1] == 1) {
1948 tainted |= st[2]->str_tainted;
1949 taintproper("Insecure dependency in system");
1952 while ((anum = vfork()) == -1) {
1953 if (errno != EAGAIN) {
1961 ihand = signal(SIGINT, SIG_IGN);
1962 qhand = signal(SIGQUIT, SIG_IGN);
1963 argtype = wait4pid(anum, &argflags, 0);
1967 (void)signal(SIGINT, ihand);
1968 (void)signal(SIGQUIT, qhand);
1969 statusvalue = (unsigned short)argflags;
1973 value = (double)((unsigned int)argflags & 0xffff);
1975 do_execfree(); /* free any memory child malloced on vfork */
1978 if ((arg[1].arg_type & A_MASK) == A_STAB)
1979 value = (double)do_aexec(st[1],arglast);
1980 else if (arglast[2] - arglast[1] != 1)
1981 value = (double)do_aexec(Nullstr,arglast);
1983 value = (double)do_exec(str_get(str_mortal(st[2])));
1987 if ((arg[1].arg_type & A_MASK) == A_STAB)
1988 value = (double)do_aspawn(st[1],arglast);
1989 else if (arglast[2] - arglast[1] != 1)
1990 value = (double)do_aspawn(Nullstr,arglast);
1992 value = (double)do_spawn(str_get(str_mortal(st[2])));
1997 if ((arg[1].arg_type & A_MASK) == A_STAB)
1998 value = (double)do_aexec(st[1],arglast);
1999 else if (arglast[2] - arglast[1] != 1)
2000 value = (double)do_aexec(Nullstr,arglast);
2004 tainted |= st[2]->str_tainted;
2005 taintproper("Insecure dependency in exec");
2007 value = (double)do_exec(str_get(str_mortal(st[2])));
2012 tmps = str_get(stab_val(defstab));
2014 tmps = str_get(st[1]);
2015 value = (double)scanhex(tmps, 99, &argtype);
2020 tmps = str_get(stab_val(defstab));
2022 tmps = str_get(st[1]);
2023 while (*tmps && (isSPACE(*tmps) || *tmps == '0'))
2026 value = (double)scanhex(++tmps, 99, &argtype);
2028 value = (double)scanoct(tmps, 99, &argtype);
2031 /* These common exits are hidden here in the middle of the switches for the
2032 benefit of those machines with limited branch addressing. Sigh. */
2039 anum = sp - arglast[0];
2042 deb("%s RETURNS ()\n",opname[optype]);
2045 deb("%s RETURNS (\"%s\")\n",opname[optype],
2046 st[1] ? str_get(st[1]) : "");
2049 tmps = st[1] ? str_get(st[1]) : "";
2050 deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\")\n",opname[optype],
2051 anum,tmps,anum==2?"":"...,",
2052 st[anum] ? str_get(st[anum]) : "");
2077 str_numset(str,value);
2084 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2087 return arglast[0] + 1;
2088 #ifdef SMALLSWITCHES
2095 value = (double)apply(optype,arglast);
2098 fatal("Unsupported function chown");
2103 value = (double)apply(optype,arglast);
2106 fatal("Unsupported function kill");
2112 value = (double)apply(optype,arglast);
2121 anum = umask((int)str_gnum(st[1]));
2122 value = (double)anum;
2124 taintproper("Insecure dependency in umask");
2128 fatal("Unsupported function umask");
2131 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2135 if ((anum = do_ipcget(optype, arglast)) == -1)
2137 value = (double)anum;
2142 anum = do_ipcctl(optype, arglast);
2146 value = (double)anum;
2149 str_set(str,"0 but true");
2153 value = (double)(do_msgsnd(arglast) >= 0);
2156 value = (double)(do_msgrcv(arglast) >= 0);
2159 value = (double)(do_semop(arglast) >= 0);
2163 value = (double)(do_shmio(optype, arglast) >= 0);
2165 #else /* not SYSVIPC */
2177 fatal("System V IPC is not implemented on this machine");
2178 #endif /* not SYSVIPC */
2180 tmps = str_get(st[1]);
2181 tmps2 = str_get(st[2]);
2183 taintproper("Insecure dependency in rename");
2186 value = (double)(rename(tmps,tmps2) >= 0);
2188 if (same_dirent(tmps2, tmps)) /* can always rename to same name */
2191 if (euid || stat(tmps2,&statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
2192 (void)UNLINK(tmps2);
2193 if (!(anum = link(tmps,tmps2)))
2194 anum = UNLINK(tmps);
2196 value = (double)(anum >= 0);
2201 tmps = str_get(st[1]);
2202 tmps2 = str_get(st[2]);
2204 taintproper("Insecure dependency in link");
2206 value = (double)(link(tmps,tmps2) >= 0);
2209 fatal("Unsupported function link");
2213 tmps = str_get(st[1]);
2214 anum = (int)str_gnum(st[2]);
2216 taintproper("Insecure dependency in mkdir");
2219 value = (double)(mkdir(tmps,anum) >= 0);
2222 (void)strcpy(buf,"mkdir ");
2224 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
2226 for (tmps2 = buf+6; *tmps; ) {
2230 (void)strcpy(tmps2," 2>&1");
2231 rsfp = mypopen(buf,"r");
2234 tmps2 = fgets(buf,sizeof buf,rsfp);
2235 (void)mypclose(rsfp);
2236 if (tmps2 != Nullch) {
2237 for (errno = 1; errno < sys_nerr; errno++) {
2238 if (instr(buf,sys_errlist[errno])) /* you don't see this */
2243 #define EACCES EPERM
2245 if (instr(buf,"cannot make"))
2247 else if (instr(buf,"existing file"))
2249 else if (instr(buf,"ile exists"))
2251 else if (instr(buf,"non-exist"))
2253 else if (instr(buf,"does not exist"))
2255 else if (instr(buf,"not empty"))
2257 else if (instr(buf,"cannot access"))
2263 else { /* some mkdirs return no failure indication */
2264 tmps = str_get(st[1]);
2265 anum = (stat(tmps,&statbuf) >= 0);
2266 if (optype == O_RMDIR)
2271 errno = EACCES; /* a guess */
2272 value = (double)anum;
2281 tmps = str_get(stab_val(defstab));
2283 tmps = str_get(st[1]);
2285 taintproper("Insecure dependency in rmdir");
2288 value = (double)(rmdir(tmps) >= 0);
2291 (void)strcpy(buf,"rmdir ");
2292 goto one_liner; /* see above in HAS_MKDIR */
2296 value = (double)getppid();
2299 fatal("Unsupported function getppid");
2307 anum = (int)str_gnum(st[1]);
2308 #ifdef _POSIX_SOURCE
2310 fatal("POSIX getpgrp can't take an argument");
2311 value = (double)getpgrp();
2313 value = (double)getpgrp(anum);
2317 fatal("The getpgrp() function is unimplemented on this machine");
2322 argtype = (int)str_gnum(st[1]);
2323 anum = (int)str_gnum(st[2]);
2325 taintproper("Insecure dependency in setpgrp");
2327 value = (double)(setpgrp(argtype,anum) >= 0);
2330 fatal("The setpgrp() function is unimplemented on this machine");
2334 #ifdef HAS_GETPRIORITY
2335 argtype = (int)str_gnum(st[1]);
2336 anum = (int)str_gnum(st[2]);
2337 value = (double)getpriority(argtype,anum);
2340 fatal("The getpriority() function is unimplemented on this machine");
2344 #ifdef HAS_SETPRIORITY
2345 argtype = (int)str_gnum(st[1]);
2346 anum = (int)str_gnum(st[2]);
2347 optype = (int)str_gnum(st[3]);
2349 taintproper("Insecure dependency in setpriority");
2351 value = (double)(setpriority(argtype,anum,optype) >= 0);
2354 fatal("The setpriority() function is unimplemented on this machine");
2360 tmps = str_get(stab_val(defstab));
2362 tmps = str_get(st[1]);
2364 taintproper("Insecure dependency in chroot");
2366 value = (double)(chroot(tmps) >= 0);
2369 fatal("Unsupported function chroot");
2375 stab = last_in_stab;
2376 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2377 stab = arg[1].arg_ptr.arg_stab;
2379 stab = stabent(str_get(st[1]),TRUE);
2380 argtype = U_I(str_gnum(st[2]));
2382 taintproper("Insecure dependency in ioctl");
2384 anum = do_ctl(optype,stab,argtype,st[3]);
2388 value = (double)anum;
2391 str_set(str,"0 but true");
2397 stab = last_in_stab;
2398 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2399 stab = arg[1].arg_ptr.arg_stab;
2401 stab = stabent(str_get(st[1]),TRUE);
2402 if (stab && stab_io(stab))
2403 fp = stab_io(stab)->ifp;
2407 argtype = (int)str_gnum(st[2]);
2408 value = (double)(flock(fileno(fp),argtype) >= 0);
2414 fatal("The flock() function is unimplemented on this machine");
2418 ary = stab_array(arg[1].arg_ptr.arg_stab);
2419 if (arglast[2] - arglast[1] != 1)
2420 do_unshift(ary,arglast);
2422 STR *tmpstr = Str_new(52,0); /* must copy the STR */
2423 str_sset(tmpstr,st[2]);
2425 (void)astore(ary,0,tmpstr);
2427 value = (double)(ary->ary_fill + 1);
2431 sp = do_try(arg[1].arg_ptr.arg_cmd,
2436 sp = do_eval(st[1], O_EVAL, curcmd->c_stash, TRUE,
2439 str_free(arg[1].arg_ptr.arg_str);
2440 arg[1].arg_ptr.arg_cmd = eval_root;
2441 arg[1].arg_type = (A_CMD|A_DONT);
2442 arg[0].arg_type = O_TRY;
2450 tmpstr = stab_val(defstab);
2453 (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
2455 tainted |= tmpstr->str_tainted;
2456 taintproper("Insecure dependency in eval");
2458 sp = do_eval(tmpstr, optype, curcmd->c_stash, FALSE,
2486 if (mystat(arg,st[1]) < 0)
2488 if (cando(anum,argtype,&statcache))
2493 if (mystat(arg,st[1]) < 0)
2498 if (mystat(arg,st[1]) < 0)
2500 if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
2504 if (mystat(arg,st[1]) < 0)
2506 if (!statcache.st_size)
2510 if (mystat(arg,st[1]) < 0)
2512 value = (double)statcache.st_size;
2516 if (mystat(arg,st[1]) < 0)
2518 value = (double)(basetime - statcache.st_mtime) / 86400.0;
2521 if (mystat(arg,st[1]) < 0)
2523 value = (double)(basetime - statcache.st_atime) / 86400.0;
2526 if (mystat(arg,st[1]) < 0)
2528 value = (double)(basetime - statcache.st_ctime) / 86400.0;
2532 if (mystat(arg,st[1]) < 0)
2534 if (S_ISSOCK(statcache.st_mode))
2538 if (mystat(arg,st[1]) < 0)
2540 if (S_ISCHR(statcache.st_mode))
2544 if (mystat(arg,st[1]) < 0)
2546 if (S_ISBLK(statcache.st_mode))
2550 if (mystat(arg,st[1]) < 0)
2552 if (S_ISREG(statcache.st_mode))
2556 if (mystat(arg,st[1]) < 0)
2558 if (S_ISDIR(statcache.st_mode))
2562 if (mystat(arg,st[1]) < 0)
2564 if (S_ISFIFO(statcache.st_mode))
2568 if (mylstat(arg,st[1]) < 0)
2570 if (S_ISLNK(statcache.st_mode))
2575 tmps = str_get(st[1]);
2576 tmps2 = str_get(st[2]);
2578 taintproper("Insecure dependency in symlink");
2580 value = (double)(symlink(tmps,tmps2) >= 0);
2583 fatal("Unsupported function symlink");
2588 tmps = str_get(stab_val(defstab));
2590 tmps = str_get(st[1]);
2591 anum = readlink(tmps,buf,sizeof buf);
2594 str_nset(str,buf,anum);
2597 goto say_undef; /* just pretend it's a normal file */
2620 if (mystat(arg,st[1]) < 0)
2622 if (statcache.st_mode & anum)
2626 if (arg[1].arg_type & A_DONT) {
2627 stab = arg[1].arg_ptr.arg_stab;
2631 stab = stabent(tmps = str_get(st[1]),FALSE);
2632 if (stab && stab_io(stab) && stab_io(stab)->ifp)
2633 anum = fileno(stab_io(stab)->ifp);
2634 else if (isDIGIT(*tmps))
2643 str = do_fttext(arg,st[1]);
2647 if ((arg[1].arg_type & A_MASK) == A_WORD)
2648 stab = arg[1].arg_ptr.arg_stab;
2650 stab = stabent(str_get(st[1]),TRUE);
2652 value = (double)do_socket(stab,arglast);
2654 (void)do_socket(stab,arglast);
2658 if ((arg[1].arg_type & A_MASK) == A_WORD)
2659 stab = arg[1].arg_ptr.arg_stab;
2661 stab = stabent(str_get(st[1]),TRUE);
2663 value = (double)do_bind(stab,arglast);
2665 (void)do_bind(stab,arglast);
2669 if ((arg[1].arg_type & A_MASK) == A_WORD)
2670 stab = arg[1].arg_ptr.arg_stab;
2672 stab = stabent(str_get(st[1]),TRUE);
2674 value = (double)do_connect(stab,arglast);
2676 (void)do_connect(stab,arglast);
2680 if ((arg[1].arg_type & A_MASK) == A_WORD)
2681 stab = arg[1].arg_ptr.arg_stab;
2683 stab = stabent(str_get(st[1]),TRUE);
2685 value = (double)do_listen(stab,arglast);
2687 (void)do_listen(stab,arglast);
2691 if ((arg[1].arg_type & A_MASK) == A_WORD)
2692 stab = arg[1].arg_ptr.arg_stab;
2694 stab = stabent(str_get(st[1]),TRUE);
2695 if ((arg[2].arg_type & A_MASK) == A_WORD)
2696 stab2 = arg[2].arg_ptr.arg_stab;
2698 stab2 = stabent(str_get(st[2]),TRUE);
2699 do_accept(str,stab,stab2);
2707 sp = do_ghent(optype,
2715 sp = do_gnent(optype,
2723 sp = do_gpent(optype,
2731 sp = do_gsent(optype,
2735 value = (double) sethostent((int)str_gnum(st[1]));
2738 value = (double) setnetent((int)str_gnum(st[1]));
2741 value = (double) setprotoent((int)str_gnum(st[1]));
2744 value = (double) setservent((int)str_gnum(st[1]));
2747 value = (double) endhostent();
2750 value = (double) endnetent();
2753 value = (double) endprotoent();
2756 value = (double) endservent();
2759 if ((arg[1].arg_type & A_MASK) == A_WORD)
2760 stab = arg[1].arg_ptr.arg_stab;
2762 stab = stabent(str_get(st[1]),TRUE);
2763 if ((arg[2].arg_type & A_MASK) == A_WORD)
2764 stab2 = arg[2].arg_ptr.arg_stab;
2766 stab2 = stabent(str_get(st[2]),TRUE);
2768 value = (double)do_spair(stab,stab2,arglast);
2770 (void)do_spair(stab,stab2,arglast);
2774 if ((arg[1].arg_type & A_MASK) == A_WORD)
2775 stab = arg[1].arg_ptr.arg_stab;
2777 stab = stabent(str_get(st[1]),TRUE);
2779 value = (double)do_shutdown(stab,arglast);
2781 (void)do_shutdown(stab,arglast);
2786 if ((arg[1].arg_type & A_MASK) == A_WORD)
2787 stab = arg[1].arg_ptr.arg_stab;
2789 stab = stabent(str_get(st[1]),TRUE);
2790 sp = do_sopt(optype,stab,arglast);
2794 if ((arg[1].arg_type & A_MASK) == A_WORD)
2795 stab = arg[1].arg_ptr.arg_stab;
2797 stab = stabent(str_get(st[1]),TRUE);
2800 sp = do_getsockname(optype,stab,arglast);
2803 #else /* HAS_SOCKET not defined */
2836 fatal("Unsupported socket function");
2837 #endif /* HAS_SOCKET */
2840 sp = do_select(gimme,arglast);
2843 fatal("select not implemented");
2848 if ((arg[1].arg_type & A_MASK) == A_WORD)
2849 stab = arg[1].arg_ptr.arg_stab;
2851 stab = stabent(str_get(st[1]),TRUE);
2852 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2859 if ((arg[1].arg_type & A_MASK) == A_WORD)
2860 stab = arg[1].arg_ptr.arg_stab;
2862 stab = stabent(str_get(st[1]),TRUE);
2863 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2866 str_set(str, (setmode(fileno(fp), O_BINARY) != -1) ? Yes : No);
2873 sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
2879 sp = do_gpwent(optype,
2883 value = (double) setpwent();
2886 value = (double) endpwent();
2891 fatal("Unsupported password function");
2898 sp = do_ggrent(optype,
2902 value = (double) setgrent();
2905 value = (double) endgrent();
2910 fatal("Unsupported group function");
2915 if (!(tmps = getlogin()))
2919 fatal("Unsupported function getlogin");
2930 if ((arg[1].arg_type & A_MASK) == A_WORD)
2931 stab = arg[1].arg_ptr.arg_stab;
2933 stab = stabent(str_get(st[1]),TRUE);
2936 sp = do_dirop(optype,stab,gimme,arglast);
2939 value = (double)do_syscall(arglast);
2943 if ((arg[1].arg_type & A_MASK) == A_WORD)
2944 stab = arg[1].arg_ptr.arg_stab;
2946 stab = stabent(str_get(st[1]),TRUE);
2947 if ((arg[2].arg_type & A_MASK) == A_WORD)
2948 stab2 = arg[2].arg_ptr.arg_stab;
2950 stab2 = stabent(str_get(st[2]),TRUE);
2951 do_pipe(str,stab,stab2);
2954 fatal("Unsupported function pipe");
2965 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2968 return arglast[0] + 1;