1 /* $RCSfile: eval.c,v $$Revision: 4.0.1.4 $$Date: 92/06/08 13:20:20 $
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.4 92/06/08 13:20:20 lwall
10 * patch20: added explicit time_t support
11 * patch20: fixed confusion between a *var's real name and its effective name
12 * patch20: added Atari ST portability
13 * patch20: new warning for use of x with non-numeric right operand
14 * patch20: modulus with highest bit in left operand set didn't always work
15 * patch20: dbmclose(%array) didn't work
16 * patch20: added ... as variant on ..
17 * patch20: O_PIPE conflicted with Atari
19 * Revision 4.0.1.3 91/11/05 17:15:21 lwall
20 * patch11: prepared for ctype implementations that don't define isascii()
21 * patch11: various portability fixes
22 * patch11: added sort {} LIST
23 * patch11: added eval {}
24 * patch11: sysread() in socket was substituting recv()
25 * patch11: a last statement outside any block caused occasional core dumps
26 * patch11: missing arguments caused core dump in -D8 code
27 * patch11: eval 'stuff' now optimized to eval {stuff}
29 * Revision 4.0.1.2 91/06/07 11:07:23 lwall
30 * patch4: new copyright notice
31 * patch4: length($`), length($&), length($') now optimized to avoid string copy
32 * patch4: assignment wasn't correctly de-tainting the assigned variable.
33 * patch4: default top-of-form format is now FILEHANDLE_TOP
34 * patch4: added $^P variable to control calling of perldb routines
35 * patch4: taintchecks could improperly modify parent in vfork()
36 * patch4: many, many itty-bitty portability fixes
38 * Revision 4.0.1.1 91/04/11 17:43:48 lwall
39 * patch1: fixed failed fork to return undef as documented
40 * patch1: reduced maximum branch distance in eval.c
42 * Revision 4.0 91/03/20 01:16:48 lwall
50 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
58 /* I_FCNTL *MUST* not be defined for MS-DOS and OS/2
59 but fcntl.h is required for O_BINARY */
70 static void (*ihand)();
71 static void (*qhand)();
73 static int (*ihand)();
74 static int (*qhand)();
81 static struct lstring *lstr;
82 static int old_rschar;
85 double sin(), cos(), atan2(), pow();
106 int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
107 unsigned long tmpulong;
116 bool assigning = FALSE;
117 double exp(), log(), sqrt(), modf();
118 char *crypt(), *getenv();
119 extern void grow_dlevel();
123 optype = arg->arg_type;
124 maxarg = arg->arg_len;
126 str = arg->arg_ptr.arg_str;
127 if (sp + maxarg > stack->ary_max)
128 astore(stack, sp + maxarg, Nullstr);
129 st = stack->ary_array;
134 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
136 debname[dlevel] = opname[optype][0];
137 debdelim[dlevel] = ':';
138 if (++dlevel >= dlmax)
143 for (anum = 1; anum <= maxarg; anum++) {
144 argflags = arg[anum].arg_flags;
145 argtype = arg[anum].arg_type;
146 argptr = arg[anum].arg_ptr;
150 st[++sp] = &str_undef;
159 deb("%d.EXPR =>\n",anum);
162 sp = eval(argptr.arg_arg,
163 (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp);
164 if (sp + (maxarg - anum) > stack->ary_max)
165 astore(stack, sp + (maxarg - anum), Nullstr);
166 st = stack->ary_array; /* possibly reallocated */
172 deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
175 sp = cmd_exec(argptr.arg_cmd, gimme, sp);
176 if (sp + (maxarg - anum) > stack->ary_max)
177 astore(stack, sp + (maxarg - anum), Nullstr);
178 st = stack->ary_array; /* possibly reallocated */
183 case O_ITEM2: argtype = 2; break;
184 case O_ITEM3: argtype = 3; break;
185 default: argtype = anum; break;
187 str = afetch(stab_array(argptr.arg_stab),
188 arg[argtype].arg_len - arybase, TRUE);
191 (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
192 arg[argtype].arg_len);
199 case O_ITEM2: argtype = 2; break;
200 case O_ITEM3: argtype = 3; break;
201 default: argtype = anum; break;
203 st[++sp] = afetch(stab_array(argptr.arg_stab),
204 arg[argtype].arg_len - arybase, FALSE);
207 (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
208 arg[argtype].arg_len);
214 stab = argptr.arg_stab;
215 st[++sp] = (STR*)stab;
216 if (!stab_xarray(stab))
218 if (!stab_xhash(stab))
221 stab_io(stab) = stio_new();
224 (void)sprintf(buf,"STAR *%s -> *%s",
225 stab_name(argptr.arg_stab), stab_ename(argptr.arg_stab));
231 str = st[++sp] = (STR*)argptr.arg_stab;
234 (void)sprintf(buf,"LSTAR *%s -> *%s",
235 stab_name(argptr.arg_stab), stab_ename(argptr.arg_stab));
241 st[++sp] = STAB_STR(argptr.arg_stab);
244 (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab));
250 str_numset(str, (double)STAB_LEN(argptr.arg_stab));
254 (void)sprintf(buf,"LENSTAB $%s",stab_name(argptr.arg_stab));
263 deb("%d.LEXPR =>\n",anum);
266 if (argflags & AF_ARYOK) {
267 sp = eval(argptr.arg_arg, G_ARRAY, sp);
268 if (sp + (maxarg - anum) > stack->ary_max)
269 astore(stack, sp + (maxarg - anum), Nullstr);
270 st = stack->ary_array; /* possibly reallocated */
273 sp = eval(argptr.arg_arg, G_SCALAR, sp);
274 st = stack->ary_array; /* possibly reallocated */
282 (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab));
287 str = STAB_STR(argptr.arg_stab);
289 fatal("panic: A_LVAL");
292 if (argflags & AF_PRE) {
293 if (argflags & AF_UP)
299 str = arg->arg_ptr.arg_str;
301 else if (argflags & AF_POST) {
302 st[sp] = str_mortal(str);
303 if (argflags & AF_UP)
308 str = arg->arg_ptr.arg_str;
315 stab = argptr.arg_stab;
316 str = stab_array(argptr.arg_stab)->ary_magic;
317 if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
318 str_numset(str,(double)(stab_array(stab)->ary_fill+arybase));
323 fatal("panic: A_LEXPR");
326 stab = argptr.arg_stab;
327 st[++sp] = stab_array(stab)->ary_magic;
328 str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase));
334 st[++sp] = argptr.arg_str;
340 (void) interp(str,argptr.arg_str,sp);
341 st = stack->ary_array;
348 tmps = str_get(interp(str,argptr.arg_str,sp));
349 st = stack->ary_array;
351 taintproper("Insecure dependency in ``");
353 fp = mypopen(tmps,"r");
356 if (gimme == G_SCALAR) {
357 while (str_gets(str,fp,str->str_cur) != Nullch)
363 if (++sp > stack->ary_max) {
364 astore(stack, sp, Nullstr);
365 st = stack->ary_array;
367 str = st[sp] = Str_new(56,80);
368 if (str_gets(str,fp,0) == Nullch) {
372 if (str->str_len - str->str_cur > 20) {
373 str->str_len = str->str_cur+1;
374 Renew(str->str_ptr, str->str_len, char);
379 statusvalue = mypclose(fp);
384 if (gimme == G_SCALAR)
392 if (curcsv->wantarray == G_ARRAY)
402 last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
407 argflags |= AF_POST; /* enable newline chopping */
408 last_in_stab = argptr.arg_stab;
423 last_in_stab = argptr.arg_stab;
427 if (anum > 1) /* assign to scalar */
428 gimme = G_SCALAR; /* force context to scalar */
429 if (gimme == G_ARRAY)
433 if (stab_io(last_in_stab)) {
434 fp = stab_io(last_in_stab)->ifp;
436 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
437 if (stab_io(last_in_stab)->flags & IOF_START) {
438 stab_io(last_in_stab)->flags &= ~IOF_START;
439 stab_io(last_in_stab)->lines = 0;
440 if (alen(stab_array(last_in_stab)) < 0) {
441 tmpstr = str_make("-",1); /* assume stdin */
442 (void)apush(stab_array(last_in_stab), tmpstr);
445 fp = nextargv(last_in_stab);
446 if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
447 (void)do_close(last_in_stab,FALSE); /* now it does*/
448 stab_io(last_in_stab)->flags |= IOF_START;
451 else if (argtype == A_GLOB) {
452 (void) interp(str,stab_val(last_in_stab),sp);
453 st = stack->ary_array;
454 tmpstr = Str_new(55,0);
456 str_set(tmpstr, "perlglob ");
457 str_scat(tmpstr,str);
458 str_cat(tmpstr," |");
461 str_nset(tmpstr,cshname,cshlen);
462 str_cat(tmpstr," -cf 'set nonomatch; glob ");
463 str_scat(tmpstr,str);
464 str_cat(tmpstr,"'|");
466 str_set(tmpstr, "echo ");
467 str_scat(tmpstr,str);
469 "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
472 (void)do_open(last_in_stab,tmpstr->str_ptr,
474 fp = stab_io(last_in_stab)->ifp;
480 warn("Read on closed filehandle <%s>",stab_ename(last_in_stab));
481 tmplen = str->str_len; /* remember if already alloced */
483 Str_Grow(str,80); /* try short-buffering it */
487 else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) {
489 if (stab_io(last_in_stab)->flags & IOF_ARGV) {
490 fp = nextargv(last_in_stab);
493 (void)do_close(last_in_stab,FALSE);
494 stab_io(last_in_stab)->flags |= IOF_START;
496 else if (argflags & AF_POST) {
497 (void)do_close(last_in_stab,FALSE);
502 if (gimme == G_ARRAY) {
510 stab_io(last_in_stab)->lines++;
513 str->str_tainted = 1; /* Anything from the outside world...*/
515 if (argflags & AF_POST) {
516 if (str->str_cur > 0)
518 if (str->str_ptr[str->str_cur] == rschar)
519 str->str_ptr[str->str_cur] = '\0';
522 for (tmps = str->str_ptr; *tmps; tmps++)
523 if (!isALPHA(*tmps) && !isDIGIT(*tmps) &&
524 index("$&*(){}[]'\";\\|?<>~`",*tmps))
526 if (*tmps && stat(str->str_ptr,&statbuf) < 0)
527 goto keepgoing; /* unmatched wildcard? */
529 if (gimme == G_ARRAY) {
530 if (str->str_len - str->str_cur > 20) {
531 str->str_len = str->str_cur+1;
532 Renew(str->str_ptr, str->str_len, char);
535 if (++sp > stack->ary_max) {
536 astore(stack, sp, Nullstr);
537 st = stack->ary_array;
539 str = Str_new(58,80);
542 else if (!tmplen && str->str_len - str->str_cur > 80) {
543 /* try to reclaim a bit of scalar space on 1st alloc */
544 if (str->str_cur < 60)
547 str->str_len = str->str_cur+40; /* allow some slop */
548 Renew(str->str_ptr, str->str_len, char);
560 deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));
568 if (optype < O_CHOWN)
575 if (gimme == G_ARRAY)
583 if (gimme == G_ARRAY)
586 STR_SSET(str,st[arglast[anum]-arglast[0]]);
590 if (gimme == G_ARRAY)
593 STR_SSET(str,st[arglast[anum]-arglast[0]]);
602 if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {
603 sp = do_repeatary(arglast);
607 anum = (int)str_gnum(st[2]);
609 tmpstr = Str_new(50, 0);
611 str_nset(tmpstr,tmps,str->str_cur);
612 tmps = str_get(tmpstr); /* force to be string */
613 STR_GROW(str, (anum * str->str_cur) + 1);
614 repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
615 str->str_cur *= anum;
616 str->str_ptr[str->str_cur] = '\0';
621 if (dowarn && st[2]->str_pok && !looks_like_number(st[2]))
622 warn("Right operand of x is not numeric");
623 str_sset(str,&str_no);
628 sp = do_match(str,arg,
630 if (gimme == G_ARRAY)
635 sp = do_match(str,arg,
637 str_sset(str, str_true(str) ? &str_no : &str_yes);
641 sp = do_subst(str,arg,arglast[0]);
644 sp = do_subst(str,arg,arglast[0]);
645 str = arg->arg_ptr.arg_str;
646 str_set(str, str_true(str) ? No : Yes);
649 if (arg[1].arg_flags & AF_ARYOK) {
650 if (arg->arg_len == 1) {
651 arg->arg_type = O_LOCAL;
655 arg->arg_type = O_AASSIGN;
660 arg->arg_type = O_SASSIGN;
665 arglast[2] = arglast[1]; /* push a null array */
675 if (tainted && !st[2]->str_tainted)
678 STR_SSET(str, st[2]);
683 str = arg->arg_ptr.arg_str;
684 for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
689 if (arg[1].arg_type & A_DONT) {
690 sp = do_defined(str,arg,
694 else if (str->str_pok || str->str_nok)
698 if (arg[1].arg_type & A_DONT) {
699 sp = do_undef(str,arg,
703 else if (str != stab_val(defstab)) {
705 if (str->str_state == SS_INCR)
707 Safefree(str->str_ptr);
708 str->str_ptr = Nullch;
711 str->str_pok = str->str_nok = 0;
716 sp = do_study(str,arg,
720 value = str_gnum(st[1]);
721 value = pow(value,str_gnum(st[2]));
724 value = str_gnum(st[1]);
725 value *= str_gnum(st[2]);
728 if ((value = str_gnum(st[2])) == 0.0)
729 fatal("Illegal division by zero");
731 /* insure that 20./5. == 4. */
736 if ((double)(int)x == x &&
737 (double)(int)value == value &&
738 (k = (int)x/(int)value)*(int)value == (int)x) {
745 value = str_gnum(st[1]) / value;
749 tmpulong = (unsigned long) str_gnum(st[2]);
751 fatal("Illegal modulus zero");
753 value = str_gnum(st[1]);
755 value = (double)(((unsigned long)value) % tmpulong);
757 tmplong = (long)value;
758 value = (double)(tmpulong - ((-tmplong - 1) % tmpulong)) - 1;
763 value = str_gnum(st[1]);
764 value += str_gnum(st[2]);
767 value = str_gnum(st[1]);
768 value -= str_gnum(st[2]);
771 value = str_gnum(st[1]);
772 anum = (int)str_gnum(st[2]);
774 value = (double)(U_L(value) << anum);
778 value = str_gnum(st[1]);
779 anum = (int)str_gnum(st[2]);
781 value = (double)(U_L(value) >> anum);
785 value = str_gnum(st[1]);
786 value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
789 value = str_gnum(st[1]);
790 value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
793 value = str_gnum(st[1]);
794 value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
797 value = str_gnum(st[1]);
798 value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
802 if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
803 (!st[2]->str_nok && !looks_like_number(st[2])) )
804 warn("Possible use of == on string value");
806 value = str_gnum(st[1]);
807 value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
810 value = str_gnum(st[1]);
811 value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
814 value = str_gnum(st[1]);
815 value -= str_gnum(st[2]);
818 else if (value < 0.0)
822 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
823 value = str_gnum(st[1]);
825 value = (double)(U_L(value) & U_L(str_gnum(st[2])));
830 do_vop(optype,str,st[1],st[2]);
833 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
834 value = str_gnum(st[1]);
836 value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));
841 do_vop(optype,str,st[1],st[2]);
844 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
845 value = str_gnum(st[1]);
847 value = (double)(U_L(value) | U_L(str_gnum(st[2])));
852 do_vop(optype,str,st[1],st[2]);
854 /* use register in evaluating str_true() */
856 if (str_true(st[1])) {
859 argflags = arg[anum].arg_flags;
860 if (gimme == G_ARRAY)
861 argflags |= AF_ARYOK;
862 argtype = arg[anum].arg_type & A_MASK;
863 argptr = arg[anum].arg_ptr;
871 str_sset(str, st[1]);
879 if (str_true(st[1])) {
881 str_sset(str, st[1]);
891 argflags = arg[anum].arg_flags;
892 if (gimme == G_ARRAY)
893 argflags |= AF_ARYOK;
894 argtype = arg[anum].arg_type & A_MASK;
895 argptr = arg[anum].arg_ptr;
902 anum = (str_true(st[1]) ? 2 : 3);
903 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
904 argflags = arg[anum].arg_flags;
905 if (gimme == G_ARRAY)
906 argflags |= AF_ARYOK;
907 argtype = arg[anum].arg_type & A_MASK;
908 argptr = arg[anum].arg_ptr;
914 if (gimme == G_ARRAY)
919 value = -str_gnum(st[1]);
923 { char xxx = str_true(st[1]); value = (double) !xxx; }
925 value = (double) !str_true(st[1]);
929 if (!sawvec || st[1]->str_nok) {
931 value = (double) ~U_L(str_gnum(st[1]));
938 for (anum = str->str_cur; anum; anum--, tmps++)
943 stab_efullname(str,defoutstab);
945 if ((arg[1].arg_type & A_MASK) == A_WORD)
946 defoutstab = arg[1].arg_ptr.arg_stab;
948 defoutstab = stabent(str_get(st[1]),TRUE);
949 if (!stab_io(defoutstab))
950 stab_io(defoutstab) = stio_new();
951 curoutstab = defoutstab;
958 else if ((arg[1].arg_type & A_MASK) == A_WORD) {
959 if (!(stab = arg[1].arg_ptr.arg_stab))
963 stab = stabent(str_get(st[1]),TRUE);
964 if (!stab_io(stab)) {
970 fp = stab_io(stab)->ofp;
972 if (stab_io(stab)->fmt_stab)
973 form = stab_form(stab_io(stab)->fmt_stab);
975 form = stab_form(stab);
979 warn("No format for filehandle");
981 if (stab_io(stab)->ifp)
982 warn("Filehandle only opened for input");
984 warn("Write on closed filehandle");
991 format(&outrec,form,sp);
992 do_write(&outrec,stab,sp);
993 if (stab_io(stab)->flags & IOF_FLUSH)
1000 anum = arg[1].arg_type & A_MASK;
1001 if (anum == A_WORD || anum == A_STAB)
1002 stab = arg[1].arg_ptr.arg_stab;
1004 stab = stabent(str_get(st[1]),TRUE);
1005 if (st[3]->str_nok || st[3]->str_pok)
1006 anum = (int)str_gnum(st[3]);
1009 value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
1012 fatal("No dbm or ndbm on this machine");
1016 anum = arg[1].arg_type & A_MASK;
1017 if (anum == A_WORD || anum == A_STAB)
1018 stab = arg[1].arg_ptr.arg_stab;
1020 stab = stabent(str_get(st[1]),TRUE);
1021 hdbmclose(stab_hash(stab));
1024 fatal("No dbm or ndbm on this machine");
1027 if ((arg[1].arg_type & A_MASK) == A_WORD)
1028 stab = arg[1].arg_ptr.arg_stab;
1030 stab = stabent(str_get(st[1]),TRUE);
1031 tmps = str_get(st[2]);
1032 if (do_open(stab,tmps,st[2]->str_cur)) {
1033 value = (double)forkprocess;
1034 stab_io(stab)->lines = 0;
1037 else if (forkprocess == 0) /* we are a new child */
1043 value = (double) do_trans(str,arg);
1044 str = arg->arg_ptr.arg_str;
1047 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
1048 str = arg->arg_ptr.arg_str;
1053 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1054 stab = arg[1].arg_ptr.arg_stab;
1056 stab = stabent(str_get(st[1]),TRUE);
1057 str_set(str, do_close(stab,TRUE) ? Yes : No );
1061 sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
1066 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1070 str->str_nok = str->str_pok = 0;
1071 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1072 str->str_state = SS_ARY;
1075 ary = stab_array(arg[1].arg_ptr.arg_stab);
1076 maxarg = ary->ary_fill + 1;
1077 if (gimme == G_ARRAY) { /* array wanted */
1080 if (maxarg > 0 && sp + maxarg > stack->ary_max) {
1081 astore(stack,sp + maxarg, Nullstr);
1082 st = stack->ary_array;
1085 Copy(ary->ary_array, &st[1], maxarg, STR*);
1090 value = (double)maxarg;
1094 anum = ((int)str_gnum(st[2])) - arybase;
1095 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
1098 tmpstab = arg[1].arg_ptr.arg_stab;
1099 tmps = str_get(st[2]);
1100 str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
1101 if (tmpstab == envstab)
1102 my_setenv(tmps,Nullch);
1107 str->str_nok = str->str_pok = 0;
1108 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
1109 str->str_state = SS_HASH;
1112 if (gimme == G_ARRAY) { /* array wanted */
1113 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
1118 tmpstab = arg[1].arg_ptr.arg_stab;
1119 if (!stab_hash(tmpstab)->tbl_fill)
1121 sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
1122 stab_hash(tmpstab)->tbl_max+1);
1127 tmpstab = arg[1].arg_ptr.arg_stab;
1128 tmps = str_get(st[2]);
1129 str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
1132 anum = ((int)str_gnum(st[2])) - arybase;
1133 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
1134 if (!str || str == &str_undef)
1135 fatal("Assignment to non-creatable value, subscript %d",anum);
1138 tmpstab = arg[1].arg_ptr.arg_stab;
1139 tmps = str_get(st[2]);
1140 anum = st[2]->str_cur;
1141 str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
1142 if (!str || str == &str_undef)
1143 fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
1144 if (tmpstab == envstab) /* heavy wizardry going on here */
1145 str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
1146 /* he threw the brick up into the air */
1147 else if (tmpstab == sigstab)
1148 str_magic(str, tmpstab, 'S', tmps, anum);
1150 else if (stab_hash(tmpstab)->tbl_dbm)
1151 str_magic(str, tmpstab, 'D', tmps, anum);
1153 else if (tmpstab == DBline)
1154 str_magic(str, tmpstab, 'L', tmps, anum);
1159 goto do_slice_already;
1163 goto do_slice_already;
1167 goto do_slice_already;
1171 goto do_slice_already;
1176 sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
1180 sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast);
1183 if (arglast[2] - arglast[1] != 1)
1184 str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
1186 str = Str_new(51,0); /* must copy the STR */
1187 str_sset(str,st[2]);
1188 (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
1192 str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
1193 goto staticalization;
1195 str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
1199 if (ary->ary_flags & ARF_REAL)
1200 (void)str_2mortal(str);
1203 sp = do_unpack(str,gimme,arglast);
1206 value = str_gnum(st[3]);
1207 sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
1212 value = (double)str_len(stab_val(defstab));
1214 value = (double)str_len(st[1]);
1217 do_sprintf(str, sp-arglast[0], st+1);
1220 anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
1221 tmps = str_get(st[1]); /* force conversion to string */
1223 if (argtype = (str == st[1]))
1224 str = arg->arg_ptr.arg_str;
1226 anum += st[1]->str_cur + arybase;
1227 if (anum < 0 || anum > st[1]->str_cur)
1230 optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]);
1234 anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
1237 str_nset(str, tmps, anum);
1238 if (argtype) { /* it's an lvalue! */
1239 lstr = (struct lstring*)str;
1240 str->str_magic = st[1];
1241 st[1]->str_rare = 's';
1242 lstr->lstr_offset = tmps - str_get(st[1]);
1243 lstr->lstr_len = anum;
1249 (void)do_pack(str,arglast);
1252 sp = do_grep(arg,str,gimme,arglast);
1255 do_join(str,arglast);
1258 tmps = str_get(st[1]);
1259 value = (double) (str_cmp(st[1],st[2]) < 0);
1262 tmps = str_get(st[1]);
1263 value = (double) (str_cmp(st[1],st[2]) > 0);
1266 tmps = str_get(st[1]);
1267 value = (double) (str_cmp(st[1],st[2]) <= 0);
1270 tmps = str_get(st[1]);
1271 value = (double) (str_cmp(st[1],st[2]) >= 0);
1274 tmps = str_get(st[1]);
1275 value = (double) str_eq(st[1],st[2]);
1278 tmps = str_get(st[1]);
1279 value = (double) !str_eq(st[1],st[2]);
1282 tmps = str_get(st[1]);
1283 value = (double) str_cmp(st[1],st[2]);
1286 sp = do_subr(arg,gimme,arglast);
1287 st = stack->ary_array + arglast[0]; /* maybe realloced */
1290 sp = do_subr(arg,gimme,arglast);
1291 st = stack->ary_array + arglast[0]; /* maybe realloced */
1294 sp = do_caller(arg,maxarg,gimme,arglast);
1295 st = stack->ary_array + arglast[0]; /* maybe realloced */
1298 sp = do_sort(str,arg,
1302 if (gimme == G_ARRAY)
1303 sp = do_reverse(arglast);
1305 sp = do_sreverse(str, arglast);
1308 if (arglast[2] - arglast[1] != 1) {
1309 do_join(str,arglast);
1310 tmps = str_get(str);
1314 tmps = str_get(st[2]);
1316 if (!tmps || !*tmps)
1317 tmps = "Warning: something's wrong";
1321 if (arglast[2] - arglast[1] != 1) {
1322 do_join(str,arglast);
1323 tmps = str_get(str);
1327 tmps = str_get(st[2]);
1329 if (!tmps || !*tmps)
1335 if ((arg[1].arg_type & A_MASK) == A_WORD)
1336 stab = arg[1].arg_ptr.arg_stab;
1338 stab = stabent(str_get(st[1]),TRUE);
1341 if (!stab_io(stab)) {
1343 warn("Filehandle never opened");
1346 if (!(fp = stab_io(stab)->ofp)) {
1348 if (stab_io(stab)->ifp)
1349 warn("Filehandle opened only for input");
1351 warn("Print on closed filehandle");
1356 if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
1357 value = (double)do_aprint(arg,fp,arglast);
1359 value = (double)do_print(st[2],fp);
1360 if (orslen && optype == O_PRINT)
1361 if (fwrite(ors, 1, orslen, fp) == 0)
1364 if (stab_io(stab)->flags & IOF_FLUSH)
1365 if (fflush(fp) == EOF)
1373 tmps = str_get(st[1]);
1374 if (!tmps || !*tmps) {
1375 tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
1376 tmps = str_get(tmpstr);
1378 if (!tmps || !*tmps) {
1379 tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
1380 tmps = str_get(tmpstr);
1383 taintproper("Insecure dependency in chdir");
1385 value = (double)(chdir(tmps) >= 0);
1391 anum = (int)str_gnum(st[1]);
1398 tmps = str_get(st[1]);
1399 str_reset(tmps,curcmd->c_stash);
1403 if (gimme == G_ARRAY)
1406 str = st[sp - arglast[0]]; /* unwanted list, return last item */
1412 stab = last_in_stab;
1413 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1414 stab = arg[1].arg_ptr.arg_stab;
1416 stab = stabent(str_get(st[1]),TRUE);
1417 str_set(str, do_eof(stab) ? Yes : No);
1423 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1424 stab = arg[1].arg_ptr.arg_stab;
1426 stab = stabent(str_get(st[1]),TRUE);
1429 if (!stab || do_eof(stab)) /* make sure we have fp with something */
1436 *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
1442 stab = last_in_stab;
1443 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1444 stab = arg[1].arg_ptr.arg_stab;
1446 stab = stabent(str_get(st[1]),TRUE);
1448 value = (double)do_tell(stab);
1450 (void)do_tell(stab);
1456 if ((arg[1].arg_type & A_MASK) == A_WORD)
1457 stab = arg[1].arg_ptr.arg_stab;
1459 stab = stabent(str_get(st[1]),TRUE);
1460 tmps = str_get(st[2]);
1461 anum = (int)str_gnum(st[3]);
1463 maxarg = sp - arglast[0];
1465 warn("Too many args on read");
1467 maxarg = (int)str_gnum(st[4]);
1470 if (!stab_io(stab) || !stab_io(stab)->ifp)
1473 if (optype == O_RECV) {
1474 argtype = sizeof buf;
1475 STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
1476 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg,
1479 st[2]->str_cur = anum;
1480 st[2]->str_ptr[anum] = '\0';
1481 str_nset(str,buf,argtype);
1484 str_sset(str,&str_undef);
1488 if (optype == O_RECV)
1491 STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2])); /* sneaky */
1492 if (optype == O_SYSREAD) {
1493 anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum);
1497 if (stab_io(stab)->type == 's') {
1498 argtype = sizeof buf;
1499 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0,
1504 anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp);
1507 st[2]->str_cur = anum+maxarg;
1508 st[2]->str_ptr[anum+maxarg] = '\0';
1509 value = (double)anum;
1513 if ((arg[1].arg_type & A_MASK) == A_WORD)
1514 stab = arg[1].arg_ptr.arg_stab;
1516 stab = stabent(str_get(st[1]),TRUE);
1517 tmps = str_get(st[2]);
1518 anum = (int)str_gnum(st[3]);
1520 stio = stab_io(stab);
1521 maxarg = sp - arglast[0];
1522 if (!stio || !stio->ifp) {
1525 if (optype == O_SYSWRITE)
1526 warn("Syswrite on closed filehandle");
1528 warn("Send on closed socket");
1531 else if (optype == O_SYSWRITE) {
1533 warn("Too many args on syswrite");
1535 optype = (int)str_gnum(st[4]);
1538 anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum);
1541 else if (maxarg >= 4) {
1543 warn("Too many args on send");
1544 tmps2 = str_get(st[4]);
1545 anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
1546 anum, tmps2, st[4]->str_cur);
1549 anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
1556 value = (double)anum;
1559 if ((arg[1].arg_type & A_MASK) == A_WORD)
1560 stab = arg[1].arg_ptr.arg_stab;
1562 stab = stabent(str_get(st[1]),TRUE);
1563 value = str_gnum(st[2]);
1564 str_set(str, do_seek(stab,
1565 (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
1569 tmps = "_SUB_"; /* just fake up a "last _SUB_" */
1571 if (curcsv && curcsv->wantarray == G_ARRAY) {
1572 lastretstr = Nullstr;
1573 lastspbase = arglast[1];
1574 lastsize = arglast[2] - arglast[1];
1577 lastretstr = str_mortal(st[arglast[2] - arglast[0]]);
1584 tmps = str_get(arg[1].arg_ptr.arg_str);
1586 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1587 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1590 deb("(Skipping label #%d %s)\n",loop_ptr,
1591 loop_stack[loop_ptr].loop_label);
1598 deb("(Found label #%d %s)\n",loop_ptr,
1599 loop_stack[loop_ptr].loop_label);
1604 if (tmps && strEQ(tmps, "_SUB_"))
1605 fatal("Can't return outside a subroutine");
1606 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
1608 if (!lastretstr && optype == O_LAST && lastsize) {
1610 st += lastspbase + 1;
1611 optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
1613 for (anum = lastsize; anum > 0; anum--,st++)
1614 st[optype] = str_mortal(st[0]);
1616 longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
1618 longjmp(loop_stack[loop_ptr].loop_env, optype);
1620 case O_GOTO:/* shudder */
1621 goto_targ = str_get(arg[1].arg_ptr.arg_str);
1623 goto_targ = Nullch; /* just restart from top */
1624 if (optype == O_DUMP) {
1628 longjmp(top_env, 1);
1630 tmps = str_get(st[1]);
1634 anum = (int) str_gnum(st[3]) - arybase;
1637 else if (anum > st[1]->str_cur)
1638 anum = st[1]->str_cur;
1641 if (!(tmps2 = fbminstr((unsigned char*)tmps + anum,
1642 (unsigned char*)tmps + st[1]->str_cur, st[2])))
1644 if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
1646 value = (double)(-1 + arybase);
1648 value = (double)(tmps2 - tmps + arybase);
1651 tmps = str_get(st[1]);
1652 tmps2 = str_get(st[2]);
1654 anum = st[1]->str_cur;
1656 anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur;
1659 else if (anum > st[1]->str_cur)
1660 anum = st[1]->str_cur;
1663 if (!(tmps2 = rninstr(tmps, tmps + anum,
1664 tmps2, tmps2 + st[2]->str_cur)))
1666 if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
1668 value = (double)(-1 + arybase);
1670 value = (double)(tmps2 - tmps + arybase);
1674 value = (double) time(Null(long*));
1678 sp = do_tms(str,gimme,arglast);
1684 when = (time_t)str_gnum(st[1]);
1685 sp = do_time(str,localtime(&when),
1692 when = (time_t)str_gnum(st[1]);
1693 sp = do_time(str,gmtime(&when),
1697 sp = do_truncate(str,arg,
1702 sp = do_stat(str,arg,
1707 tmps = str_get(st[1]);
1709 str_set(str,fcrypt(tmps,str_get(st[2])));
1711 str_set(str,crypt(tmps,str_get(st[2])));
1715 "The crypt() function is unimplemented due to excessive paranoia.");
1719 value = str_gnum(st[1]);
1720 value = atan2(value,str_gnum(st[2]));
1724 value = str_gnum(stab_val(defstab));
1726 value = str_gnum(st[1]);
1731 value = str_gnum(stab_val(defstab));
1733 value = str_gnum(st[1]);
1740 value = str_gnum(st[1]);
1744 value = rand() * value / 2147483648.0;
1747 value = rand() * value / 65536.0;
1750 value = rand() * value / 32768.0;
1752 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1763 anum = (int)str_gnum(st[1]);
1768 value = str_gnum(stab_val(defstab));
1770 value = str_gnum(st[1]);
1775 value = str_gnum(stab_val(defstab));
1777 value = str_gnum(st[1]);
1779 fatal("Can't take log of %g\n", value);
1784 value = str_gnum(stab_val(defstab));
1786 value = str_gnum(st[1]);
1788 fatal("Can't take sqrt of %g\n", value);
1789 value = sqrt(value);
1793 value = str_gnum(stab_val(defstab));
1795 value = str_gnum(st[1]);
1797 (void)modf(value,&value);
1799 (void)modf(-value,&value);
1805 tmps = str_get(stab_val(defstab));
1807 tmps = str_get(st[1]);
1809 value = (double) (*tmps & 255);
1812 value = (double) (anum & 255);
1818 tmps = str_get(stab_val(defstab));
1820 tmps = str_get(st[1]);
1823 anum = alarm((unsigned int)atoi(tmps));
1826 value = (double)anum;
1829 fatal("Unsupported function alarm");
1836 tmps = str_get(st[1]);
1838 if (!tmps || !*tmps)
1839 sleep((32767<<16)+32767);
1841 sleep((unsigned int)atoi(tmps));
1843 value = (double)when;
1845 value = ((double)when) - value;
1849 sp = do_range(gimme,arglast);
1852 if (gimme == G_ARRAY) { /* it's a range */
1853 /* can we optimize to constant array? */
1854 if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
1855 (arg[2].arg_type & A_MASK) == A_SINGLE) {
1856 st[2] = arg[2].arg_ptr.arg_str;
1857 sp = do_range(gimme,arglast);
1858 st = stack->ary_array;
1859 maxarg = sp - arglast[0];
1860 str_free(arg[1].arg_ptr.arg_str);
1861 arg[1].arg_ptr.arg_str = Nullstr;
1862 str_free(arg[2].arg_ptr.arg_str);
1863 arg[2].arg_ptr.arg_str = Nullstr;
1864 arg->arg_type = O_ARRAY;
1865 arg[1].arg_type = A_STAB|A_DONT;
1867 stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
1868 ary = stab_array(stab);
1869 afill(ary,maxarg - 1);
1872 while (maxarg-- > 0)
1873 ary->ary_array[maxarg] = str_smake(st[maxarg]);
1877 arg->arg_type = optype = O_RANGE;
1878 maxarg = arg->arg_len = 2;
1880 arg[anum].arg_flags &= ~AF_ARYOK;
1881 argflags = arg[anum].arg_flags;
1882 argtype = arg[anum].arg_type & A_MASK;
1883 arg[anum].arg_type = argtype;
1884 argptr = arg[anum].arg_ptr;
1890 arg->arg_type = O_FLIP;
1893 if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
1894 last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
1897 arg[2].arg_type &= ~A_DONT;
1898 arg[1].arg_type |= A_DONT;
1899 arg->arg_type = optype = O_FLOP;
1900 if (arg->arg_flags & AF_COMMON) {
1901 str_numset(str,0.0);
1903 argflags = arg[2].arg_flags;
1904 argtype = arg[2].arg_type & A_MASK;
1905 argptr = arg[2].arg_ptr;
1911 str_numset(str,1.0);
1919 if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
1920 last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
1923 arg->arg_type = O_FLIP;
1924 arg[1].arg_type &= ~A_DONT;
1925 arg[2].arg_type |= A_DONT;
1936 if (tmpstab = stabent("$",allstabs))
1937 str_numset(STAB_STR(tmpstab),(double)getpid());
1938 hclear(pidstatus, FALSE); /* no kids, so don't wait for 'em */
1940 value = (double)anum;
1943 fatal("Unsupported function fork");
1949 anum = wait(&argflags);
1951 pidgone(anum,argflags);
1952 value = (double)anum;
1954 statusvalue = (unsigned short)argflags;
1957 fatal("Unsupported function wait");
1963 anum = (int)str_gnum(st[1]);
1964 optype = (int)str_gnum(st[2]);
1965 anum = wait4pid(anum, &argflags,optype);
1966 value = (double)anum;
1968 statusvalue = (unsigned short)argflags;
1971 fatal("Unsupported function wait");
1977 if (arglast[2] - arglast[1] == 1) {
1979 tainted |= st[2]->str_tainted;
1980 taintproper("Insecure dependency in system");
1983 while ((anum = vfork()) == -1) {
1984 if (errno != EAGAIN) {
1992 ihand = signal(SIGINT, SIG_IGN);
1993 qhand = signal(SIGQUIT, SIG_IGN);
1994 argtype = wait4pid(anum, &argflags, 0);
1998 (void)signal(SIGINT, ihand);
1999 (void)signal(SIGQUIT, qhand);
2000 statusvalue = (unsigned short)argflags;
2004 value = (double)((unsigned int)argflags & 0xffff);
2006 do_execfree(); /* free any memory child malloced on vfork */
2009 if ((arg[1].arg_type & A_MASK) == A_STAB)
2010 value = (double)do_aexec(st[1],arglast);
2011 else if (arglast[2] - arglast[1] != 1)
2012 value = (double)do_aexec(Nullstr,arglast);
2014 value = (double)do_exec(str_get(str_mortal(st[2])));
2018 if ((arg[1].arg_type & A_MASK) == A_STAB)
2019 value = (double)do_aspawn(st[1],arglast);
2020 else if (arglast[2] - arglast[1] != 1)
2021 value = (double)do_aspawn(Nullstr,arglast);
2023 value = (double)do_spawn(str_get(str_mortal(st[2])));
2028 if ((arg[1].arg_type & A_MASK) == A_STAB)
2029 value = (double)do_aexec(st[1],arglast);
2030 else if (arglast[2] - arglast[1] != 1)
2031 value = (double)do_aexec(Nullstr,arglast);
2035 tainted |= st[2]->str_tainted;
2036 taintproper("Insecure dependency in exec");
2038 value = (double)do_exec(str_get(str_mortal(st[2])));
2043 tmps = str_get(stab_val(defstab));
2045 tmps = str_get(st[1]);
2046 value = (double)scanhex(tmps, 99, &argtype);
2051 tmps = str_get(stab_val(defstab));
2053 tmps = str_get(st[1]);
2054 while (*tmps && (isSPACE(*tmps) || *tmps == '0'))
2057 value = (double)scanhex(++tmps, 99, &argtype);
2059 value = (double)scanoct(tmps, 99, &argtype);
2062 /* These common exits are hidden here in the middle of the switches for the
2063 benefit of those machines with limited branch addressing. Sigh. */
2070 anum = sp - arglast[0];
2073 deb("%s RETURNS ()\n",opname[optype]);
2076 deb("%s RETURNS (\"%s\")\n",opname[optype],
2077 st[1] ? str_get(st[1]) : "");
2080 tmps = st[1] ? str_get(st[1]) : "";
2081 deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\")\n",opname[optype],
2082 anum,tmps,anum==2?"":"...,",
2083 st[anum] ? str_get(st[anum]) : "");
2108 str_numset(str,value);
2115 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2118 return arglast[0] + 1;
2119 #ifdef SMALLSWITCHES
2126 value = (double)apply(optype,arglast);
2129 fatal("Unsupported function chown");
2134 value = (double)apply(optype,arglast);
2137 fatal("Unsupported function kill");
2143 value = (double)apply(optype,arglast);
2152 anum = umask((int)str_gnum(st[1]));
2153 value = (double)anum;
2155 taintproper("Insecure dependency in umask");
2159 fatal("Unsupported function umask");
2162 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
2166 if ((anum = do_ipcget(optype, arglast)) == -1)
2168 value = (double)anum;
2173 anum = do_ipcctl(optype, arglast);
2177 value = (double)anum;
2180 str_set(str,"0 but true");
2184 value = (double)(do_msgsnd(arglast) >= 0);
2187 value = (double)(do_msgrcv(arglast) >= 0);
2190 value = (double)(do_semop(arglast) >= 0);
2194 value = (double)(do_shmio(optype, arglast) >= 0);
2196 #else /* not SYSVIPC */
2208 fatal("System V IPC is not implemented on this machine");
2209 #endif /* not SYSVIPC */
2211 tmps = str_get(st[1]);
2212 tmps2 = str_get(st[2]);
2214 taintproper("Insecure dependency in rename");
2217 value = (double)(rename(tmps,tmps2) >= 0);
2219 if (same_dirent(tmps2, tmps)) /* can always rename to same name */
2222 if (euid || stat(tmps2,&statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
2223 (void)UNLINK(tmps2);
2224 if (!(anum = link(tmps,tmps2)))
2225 anum = UNLINK(tmps);
2227 value = (double)(anum >= 0);
2232 tmps = str_get(st[1]);
2233 tmps2 = str_get(st[2]);
2235 taintproper("Insecure dependency in link");
2237 value = (double)(link(tmps,tmps2) >= 0);
2240 fatal("Unsupported function link");
2244 tmps = str_get(st[1]);
2245 anum = (int)str_gnum(st[2]);
2247 taintproper("Insecure dependency in mkdir");
2250 value = (double)(mkdir(tmps,anum) >= 0);
2253 (void)strcpy(buf,"mkdir ");
2255 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
2257 for (tmps2 = buf+6; *tmps; ) {
2261 (void)strcpy(tmps2," 2>&1");
2262 rsfp = mypopen(buf,"r");
2265 tmps2 = fgets(buf,sizeof buf,rsfp);
2266 (void)mypclose(rsfp);
2267 if (tmps2 != Nullch) {
2268 for (errno = 1; errno < sys_nerr; errno++) {
2269 if (instr(buf,sys_errlist[errno])) /* you don't see this */
2274 #define EACCES EPERM
2276 if (instr(buf,"cannot make"))
2278 else if (instr(buf,"existing file"))
2280 else if (instr(buf,"ile exists"))
2282 else if (instr(buf,"non-exist"))
2284 else if (instr(buf,"does not exist"))
2286 else if (instr(buf,"not empty"))
2288 else if (instr(buf,"cannot access"))
2294 else { /* some mkdirs return no failure indication */
2295 tmps = str_get(st[1]);
2296 anum = (stat(tmps,&statbuf) >= 0);
2297 if (optype == O_RMDIR)
2302 errno = EACCES; /* a guess */
2303 value = (double)anum;
2312 tmps = str_get(stab_val(defstab));
2314 tmps = str_get(st[1]);
2316 taintproper("Insecure dependency in rmdir");
2319 value = (double)(rmdir(tmps) >= 0);
2322 (void)strcpy(buf,"rmdir ");
2323 goto one_liner; /* see above in HAS_MKDIR */
2327 value = (double)getppid();
2330 fatal("Unsupported function getppid");
2338 anum = (int)str_gnum(st[1]);
2339 #ifdef _POSIX_SOURCE
2341 fatal("POSIX getpgrp can't take an argument");
2342 value = (double)getpgrp();
2344 value = (double)getpgrp(anum);
2348 fatal("The getpgrp() function is unimplemented on this machine");
2353 argtype = (int)str_gnum(st[1]);
2354 anum = (int)str_gnum(st[2]);
2356 taintproper("Insecure dependency in setpgrp");
2358 value = (double)(setpgrp(argtype,anum) >= 0);
2361 fatal("The setpgrp() function is unimplemented on this machine");
2365 #ifdef HAS_GETPRIORITY
2366 argtype = (int)str_gnum(st[1]);
2367 anum = (int)str_gnum(st[2]);
2368 value = (double)getpriority(argtype,anum);
2371 fatal("The getpriority() function is unimplemented on this machine");
2375 #ifdef HAS_SETPRIORITY
2376 argtype = (int)str_gnum(st[1]);
2377 anum = (int)str_gnum(st[2]);
2378 optype = (int)str_gnum(st[3]);
2380 taintproper("Insecure dependency in setpriority");
2382 value = (double)(setpriority(argtype,anum,optype) >= 0);
2385 fatal("The setpriority() function is unimplemented on this machine");
2391 tmps = str_get(stab_val(defstab));
2393 tmps = str_get(st[1]);
2395 taintproper("Insecure dependency in chroot");
2397 value = (double)(chroot(tmps) >= 0);
2400 fatal("Unsupported function chroot");
2406 stab = last_in_stab;
2407 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2408 stab = arg[1].arg_ptr.arg_stab;
2410 stab = stabent(str_get(st[1]),TRUE);
2411 argtype = U_I(str_gnum(st[2]));
2413 taintproper("Insecure dependency in ioctl");
2415 anum = do_ctl(optype,stab,argtype,st[3]);
2419 value = (double)anum;
2422 str_set(str,"0 but true");
2428 stab = last_in_stab;
2429 else if ((arg[1].arg_type & A_MASK) == A_WORD)
2430 stab = arg[1].arg_ptr.arg_stab;
2432 stab = stabent(str_get(st[1]),TRUE);
2433 if (stab && stab_io(stab))
2434 fp = stab_io(stab)->ifp;
2438 argtype = (int)str_gnum(st[2]);
2439 value = (double)(flock(fileno(fp),argtype) >= 0);
2445 fatal("The flock() function is unimplemented on this machine");
2449 ary = stab_array(arg[1].arg_ptr.arg_stab);
2450 if (arglast[2] - arglast[1] != 1)
2451 do_unshift(ary,arglast);
2453 STR *tmpstr = Str_new(52,0); /* must copy the STR */
2454 str_sset(tmpstr,st[2]);
2456 (void)astore(ary,0,tmpstr);
2458 value = (double)(ary->ary_fill + 1);
2462 sp = do_try(arg[1].arg_ptr.arg_cmd,
2467 sp = do_eval(st[1], O_EVAL, curcmd->c_stash, TRUE,
2470 str_free(arg[1].arg_ptr.arg_str);
2471 arg[1].arg_ptr.arg_cmd = eval_root;
2472 arg[1].arg_type = (A_CMD|A_DONT);
2473 arg[0].arg_type = O_TRY;
2481 tmpstr = stab_val(defstab);
2484 (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
2486 tainted |= tmpstr->str_tainted;
2487 taintproper("Insecure dependency in eval");
2489 sp = do_eval(tmpstr, optype, curcmd->c_stash, FALSE,
2517 if (mystat(arg,st[1]) < 0)
2519 if (cando(anum,argtype,&statcache))
2524 if (mystat(arg,st[1]) < 0)
2529 if (mystat(arg,st[1]) < 0)
2531 if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
2535 if (mystat(arg,st[1]) < 0)
2537 if (!statcache.st_size)
2541 if (mystat(arg,st[1]) < 0)
2543 value = (double)statcache.st_size;
2547 if (mystat(arg,st[1]) < 0)
2549 value = (double)(basetime - statcache.st_mtime) / 86400.0;
2552 if (mystat(arg,st[1]) < 0)
2554 value = (double)(basetime - statcache.st_atime) / 86400.0;
2557 if (mystat(arg,st[1]) < 0)
2559 value = (double)(basetime - statcache.st_ctime) / 86400.0;
2563 if (mystat(arg,st[1]) < 0)
2565 if (S_ISSOCK(statcache.st_mode))
2569 if (mystat(arg,st[1]) < 0)
2571 if (S_ISCHR(statcache.st_mode))
2575 if (mystat(arg,st[1]) < 0)
2577 if (S_ISBLK(statcache.st_mode))
2581 if (mystat(arg,st[1]) < 0)
2583 if (S_ISREG(statcache.st_mode))
2587 if (mystat(arg,st[1]) < 0)
2589 if (S_ISDIR(statcache.st_mode))
2593 if (mystat(arg,st[1]) < 0)
2595 if (S_ISFIFO(statcache.st_mode))
2599 if (mylstat(arg,st[1]) < 0)
2601 if (S_ISLNK(statcache.st_mode))
2606 tmps = str_get(st[1]);
2607 tmps2 = str_get(st[2]);
2609 taintproper("Insecure dependency in symlink");
2611 value = (double)(symlink(tmps,tmps2) >= 0);
2614 fatal("Unsupported function symlink");
2619 tmps = str_get(stab_val(defstab));
2621 tmps = str_get(st[1]);
2622 anum = readlink(tmps,buf,sizeof buf);
2625 str_nset(str,buf,anum);
2628 goto say_undef; /* just pretend it's a normal file */
2651 if (mystat(arg,st[1]) < 0)
2653 if (statcache.st_mode & anum)
2657 if (arg[1].arg_type & A_DONT) {
2658 stab = arg[1].arg_ptr.arg_stab;
2662 stab = stabent(tmps = str_get(st[1]),FALSE);
2663 if (stab && stab_io(stab) && stab_io(stab)->ifp)
2664 anum = fileno(stab_io(stab)->ifp);
2665 else if (isDIGIT(*tmps))
2674 str = do_fttext(arg,st[1]);
2678 if ((arg[1].arg_type & A_MASK) == A_WORD)
2679 stab = arg[1].arg_ptr.arg_stab;
2681 stab = stabent(str_get(st[1]),TRUE);
2683 value = (double)do_socket(stab,arglast);
2685 (void)do_socket(stab,arglast);
2689 if ((arg[1].arg_type & A_MASK) == A_WORD)
2690 stab = arg[1].arg_ptr.arg_stab;
2692 stab = stabent(str_get(st[1]),TRUE);
2694 value = (double)do_bind(stab,arglast);
2696 (void)do_bind(stab,arglast);
2700 if ((arg[1].arg_type & A_MASK) == A_WORD)
2701 stab = arg[1].arg_ptr.arg_stab;
2703 stab = stabent(str_get(st[1]),TRUE);
2705 value = (double)do_connect(stab,arglast);
2707 (void)do_connect(stab,arglast);
2711 if ((arg[1].arg_type & A_MASK) == A_WORD)
2712 stab = arg[1].arg_ptr.arg_stab;
2714 stab = stabent(str_get(st[1]),TRUE);
2716 value = (double)do_listen(stab,arglast);
2718 (void)do_listen(stab,arglast);
2722 if ((arg[1].arg_type & A_MASK) == A_WORD)
2723 stab = arg[1].arg_ptr.arg_stab;
2725 stab = stabent(str_get(st[1]),TRUE);
2726 if ((arg[2].arg_type & A_MASK) == A_WORD)
2727 stab2 = arg[2].arg_ptr.arg_stab;
2729 stab2 = stabent(str_get(st[2]),TRUE);
2730 do_accept(str,stab,stab2);
2738 sp = do_ghent(optype,
2746 sp = do_gnent(optype,
2754 sp = do_gpent(optype,
2762 sp = do_gsent(optype,
2766 value = (double) sethostent((int)str_gnum(st[1]));
2769 value = (double) setnetent((int)str_gnum(st[1]));
2772 value = (double) setprotoent((int)str_gnum(st[1]));
2775 value = (double) setservent((int)str_gnum(st[1]));
2778 value = (double) endhostent();
2781 value = (double) endnetent();
2784 value = (double) endprotoent();
2787 value = (double) endservent();
2790 if ((arg[1].arg_type & A_MASK) == A_WORD)
2791 stab = arg[1].arg_ptr.arg_stab;
2793 stab = stabent(str_get(st[1]),TRUE);
2794 if ((arg[2].arg_type & A_MASK) == A_WORD)
2795 stab2 = arg[2].arg_ptr.arg_stab;
2797 stab2 = stabent(str_get(st[2]),TRUE);
2799 value = (double)do_spair(stab,stab2,arglast);
2801 (void)do_spair(stab,stab2,arglast);
2805 if ((arg[1].arg_type & A_MASK) == A_WORD)
2806 stab = arg[1].arg_ptr.arg_stab;
2808 stab = stabent(str_get(st[1]),TRUE);
2810 value = (double)do_shutdown(stab,arglast);
2812 (void)do_shutdown(stab,arglast);
2817 if ((arg[1].arg_type & A_MASK) == A_WORD)
2818 stab = arg[1].arg_ptr.arg_stab;
2820 stab = stabent(str_get(st[1]),TRUE);
2821 sp = do_sopt(optype,stab,arglast);
2825 if ((arg[1].arg_type & A_MASK) == A_WORD)
2826 stab = arg[1].arg_ptr.arg_stab;
2828 stab = stabent(str_get(st[1]),TRUE);
2831 sp = do_getsockname(optype,stab,arglast);
2834 #else /* HAS_SOCKET not defined */
2867 fatal("Unsupported socket function");
2868 #endif /* HAS_SOCKET */
2871 sp = do_select(gimme,arglast);
2874 fatal("select not implemented");
2879 if ((arg[1].arg_type & A_MASK) == A_WORD)
2880 stab = arg[1].arg_ptr.arg_stab;
2882 stab = stabent(str_get(st[1]),TRUE);
2883 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2890 if ((arg[1].arg_type & A_MASK) == A_WORD)
2891 stab = arg[1].arg_ptr.arg_stab;
2893 stab = stabent(str_get(st[1]),TRUE);
2894 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2902 fp->_flag |= _IOBIN;
2906 str_set(str, (setmode(fileno(fp), O_BINARY) != -1) ? Yes : No);
2914 sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
2920 sp = do_gpwent(optype,
2924 value = (double) setpwent();
2927 value = (double) endpwent();
2932 fatal("Unsupported password function");
2939 sp = do_ggrent(optype,
2943 value = (double) setgrent();
2946 value = (double) endgrent();
2951 fatal("Unsupported group function");
2956 if (!(tmps = getlogin()))
2960 fatal("Unsupported function getlogin");
2971 if ((arg[1].arg_type & A_MASK) == A_WORD)
2972 stab = arg[1].arg_ptr.arg_stab;
2974 stab = stabent(str_get(st[1]),TRUE);
2977 sp = do_dirop(optype,stab,gimme,arglast);
2980 value = (double)do_syscall(arglast);
2984 if ((arg[1].arg_type & A_MASK) == A_WORD)
2985 stab = arg[1].arg_ptr.arg_stab;
2987 stab = stabent(str_get(st[1]),TRUE);
2988 if ((arg[2].arg_type & A_MASK) == A_WORD)
2989 stab2 = arg[2].arg_ptr.arg_stab;
2991 stab2 = stabent(str_get(st[2]),TRUE);
2992 do_pipe(str,stab,stab2);
2995 fatal("Unsupported function pipe");
3006 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
3009 return arglast[0] + 1;