summaryrefslogtreecommitdiff
path: root/eval.c.save
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c.save')
-rw-r--r--eval.c.save3048
1 files changed, 0 insertions, 3048 deletions
diff --git a/eval.c.save b/eval.c.save
deleted file mode 100644
index 964bc0301f..0000000000
--- a/eval.c.save
+++ /dev/null
@@ -1,3048 +0,0 @@
-/* $RCSfile: eval.c,v $$Revision: 4.1 $$Date: 92/08/07 18:20:29 $
- *
- * Copyright (c) 1991, Larry Wall
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Artistic License, as specified in the README file.
- *
- * $Log: eval.c,v $
- * Revision 4.1 92/08/07 18:20:29 lwall
- *
- * Revision 4.0.1.4 92/06/08 13:20:20 lwall
- * patch20: added explicit time_t support
- * patch20: fixed confusion between a *var's real name and its effective name
- * patch20: added Atari ST portability
- * patch20: new warning for use of x with non-numeric right operand
- * patch20: modulus with highest bit in left operand set didn't always work
- * patch20: dbmclose(%array) didn't work
- * patch20: added ... as variant on ..
- * patch20: O_PIPE conflicted with Atari
- *
- * Revision 4.0.1.3 91/11/05 17:15:21 lwall
- * patch11: prepared for ctype implementations that don't define isascii()
- * patch11: various portability fixes
- * patch11: added sort {} LIST
- * patch11: added eval {}
- * patch11: sysread() in socket was substituting recv()
- * patch11: a last statement outside any block caused occasional core dumps
- * patch11: missing arguments caused core dump in -D8 code
- * patch11: eval 'stuff' now optimized to eval {stuff}
- *
- * Revision 4.0.1.2 91/06/07 11:07:23 lwall
- * patch4: new copyright notice
- * patch4: length($`), length($&), length($') now optimized to avoid string copy
- * patch4: assignment wasn't correctly de-tainting the assigned variable.
- * patch4: default top-of-form format is now FILEHANDLE_TOP
- * patch4: added $^P variable to control calling of perldb routines
- * patch4: taintchecks could improperly modify parent in vfork()
- * patch4: many, many itty-bitty portability fixes
- *
- * Revision 4.0.1.1 91/04/11 17:43:48 lwall
- * patch1: fixed failed fork to return undef as documented
- * patch1: reduced maximum branch distance in eval.c
- *
- * Revision 4.0 91/03/20 01:16:48 lwall
- * 4.0 baseline.
- *
- */
-
-#include "EXTERN.h"
-#include "perl.h"
-
-extern int (*ppaddr[])();
-extern int mark[];
-
-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
-#include <signal.h>
-#endif
-
-#ifdef I_FCNTL
-#include <fcntl.h>
-#endif
-#ifdef MSDOS
-/* I_FCNTL *MUST* not be defined for MS-DOS and OS/2
- but fcntl.h is required for O_BINARY */
-#include <fcntl.h>
-#endif
-#ifdef I_SYS_FILE
-#include <sys/file.h>
-#endif
-#ifdef I_VFORK
-# include <vfork.h>
-#endif
-
-double sin(), cos(), atan2(), pow();
-
-char *getlogin();
-
-int
-eval(arg,gimme,sp)
-register ARG *arg;
-int gimme;
-register int sp;
-{
- register STR *str;
- register int anum;
- register int optype;
- register STR **st;
- int maxarg;
- double value;
- register char *tmps;
- char *tmps2;
- int argflags;
- int argtype;
- union argptr argptr;
- int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
- unsigned long tmpulong;
- long tmplong;
- time_t when;
- STRLEN tmplen;
- FILE *fp;
- STR *tmpstr;
- FCMD *form;
- STAB *stab;
- STAB *stab2;
- STIO *stio;
- ARRAY *ary;
- int old_rslen;
- int old_rschar;
- VOIDRET (*ihand)(); /* place to save signal during system() */
- VOIDRET (*qhand)(); /* place to save signal during system() */
- bool assigning = FALSE;
- int mymarkbase = savestack->ary_fill;
-
- if (!arg)
- goto say_undef;
- optype = arg->arg_type;
- maxarg = arg->arg_len;
- arglast[0] = sp;
- str = arg->arg_ptr.arg_str;
- if (sp + maxarg > stack->ary_max)
- astore(stack, sp + maxarg, Nullstr);
- st = stack->ary_array;
-
-#ifdef DEBUGGING
- if (debug) {
- if (debug & 8) {
- deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
- }
- debname[dlevel] = opname[optype][0];
- debdelim[dlevel] = ':';
- if (++dlevel >= dlmax)
- grow_dlevel();
- }
-#endif
-
- if (mark[optype]) {
- saveint(&markbase);
- markbase = mymarkbase;
- saveint(&stack_mark);
- stack_mark = sp;
- }
- for (anum = 1; anum <= maxarg; anum++) {
- argflags = arg[anum].arg_flags;
- argtype = arg[anum].arg_type;
- argptr = arg[anum].arg_ptr;
- re_eval:
- switch (argtype) {
- default:
- if (!ppaddr[optype] || optype == O_SUBR || optype == O_DBSUBR) {
- st[++sp] = &str_undef;
- }
-#ifdef DEBUGGING
- tmps = "NULL";
-#endif
- break;
- case A_EXPR:
-#ifdef DEBUGGING
- if (debug & 8) {
- tmps = "EXPR";
- deb("%d.EXPR =>\n",anum);
- }
-#endif
- sp = eval(argptr.arg_arg,
- (argflags & AF_ARYOK) ? G_ARRAY : G_SCALAR, sp);
- if (sp + (maxarg - anum) > stack->ary_max)
- astore(stack, sp + (maxarg - anum), Nullstr);
- st = stack->ary_array; /* possibly reallocated */
- break;
- case A_CMD:
-#ifdef DEBUGGING
- if (debug & 8) {
- tmps = "CMD";
- deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
- }
-#endif
- sp = cmd_exec(argptr.arg_cmd, gimme, sp);
- if (sp + (maxarg - anum) > stack->ary_max)
- astore(stack, sp + (maxarg - anum), Nullstr);
- st = stack->ary_array; /* possibly reallocated */
- break;
- case A_LARYSTAB:
- ++sp;
- switch (optype) {
- case O_ITEM2: argtype = 2; break;
- case O_ITEM3: argtype = 3; break;
- default: argtype = anum; break;
- }
- str = afetch(stab_array(argptr.arg_stab),
- arg[argtype].arg_len - arybase, TRUE);
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"LARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
- arg[argtype].arg_len);
- tmps = buf;
- }
-#endif
- goto do_crement;
- case A_ARYSTAB:
- switch (optype) {
- case O_ITEM2: argtype = 2; break;
- case O_ITEM3: argtype = 3; break;
- default: argtype = anum; break;
- }
- st[++sp] = afetch(stab_array(argptr.arg_stab),
- arg[argtype].arg_len - arybase, FALSE);
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"ARYSTAB $%s[%d]",stab_name(argptr.arg_stab),
- arg[argtype].arg_len);
- tmps = buf;
- }
-#endif
- break;
- case A_STAR:
- stab = argptr.arg_stab;
- st[++sp] = (STR*)stab;
- if (!stab_xarray(stab))
- aadd(stab);
- if (!stab_xhash(stab))
- hadd(stab);
- if (!stab_io(stab))
- stab_io(stab) = stio_new();
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"STAR *%s -> *%s",
- stab_name(argptr.arg_stab), stab_ename(argptr.arg_stab));
- tmps = buf;
- }
-#endif
- break;
- case A_LSTAR:
- str = st[++sp] = (STR*)argptr.arg_stab;
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"LSTAR *%s -> *%s",
- stab_name(argptr.arg_stab), stab_ename(argptr.arg_stab));
- tmps = buf;
- }
-#endif
- break;
- case A_STAB:
- st[++sp] = STAB_STR(argptr.arg_stab);
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"STAB $%s",stab_name(argptr.arg_stab));
- tmps = buf;
- }
-#endif
- break;
- case A_LENSTAB:
- str_numset(str, (double)STAB_LEN(argptr.arg_stab));
- st[++sp] = str;
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"LENSTAB $%s",stab_name(argptr.arg_stab));
- tmps = buf;
- }
-#endif
- break;
- case A_LEXPR:
-#ifdef DEBUGGING
- if (debug & 8) {
- tmps = "LEXPR";
- deb("%d.LEXPR =>\n",anum);
- }
-#endif
- if (argflags & AF_ARYOK) {
- sp = eval(argptr.arg_arg, G_ARRAY, sp);
- if (sp + (maxarg - anum) > stack->ary_max)
- astore(stack, sp + (maxarg - anum), Nullstr);
- st = stack->ary_array; /* possibly reallocated */
- }
- else {
- sp = eval(argptr.arg_arg, G_SCALAR, sp);
- st = stack->ary_array; /* possibly reallocated */
- str = st[sp];
- goto do_crement;
- }
- break;
- case A_LVAL:
-#ifdef DEBUGGING
- if (debug & 8) {
- (void)sprintf(buf,"LVAL $%s",stab_name(argptr.arg_stab));
- tmps = buf;
- }
-#endif
- ++sp;
- str = STAB_STR(argptr.arg_stab);
- if (!str)
- fatal("panic: A_LVAL");
- do_crement:
- assigning = TRUE;
- if (argflags & AF_PRE) {
- if (argflags & AF_UP)
- str_inc(str);
- else
- str_dec(str);
- STABSET(str);
- st[sp] = str;
- str = arg->arg_ptr.arg_str;
- }
- else if (argflags & AF_POST) {
- st[sp] = str_mortal(str);
- if (argflags & AF_UP)
- str_inc(str);
- else
- str_dec(str);
- STABSET(str);
- str = arg->arg_ptr.arg_str;
- }
- else
- st[sp] = str;
- break;
- case A_LARYLEN:
- ++sp;
- stab = argptr.arg_stab;
- str = stab_array(argptr.arg_stab)->ary_magic;
- if (optype != O_SASSIGN || argflags & (AF_PRE|AF_POST))
- str_numset(str,(double)(stab_array(stab)->ary_fill+arybase));
-#ifdef DEBUGGING
- tmps = "LARYLEN";
-#endif
- if (!str)
- fatal("panic: A_LEXPR");
- goto do_crement;
- case A_ARYLEN:
- stab = argptr.arg_stab;
- st[++sp] = stab_array(stab)->ary_magic;
- str_numset(st[sp],(double)(stab_array(stab)->ary_fill+arybase));
-#ifdef DEBUGGING
- tmps = "ARYLEN";
-#endif
- break;
- case A_SINGLE:
- st[++sp] = argptr.arg_str;
-#ifdef DEBUGGING
- tmps = "SINGLE";
-#endif
- break;
- case A_DOUBLE:
- (void) interp(str,argptr.arg_str,sp);
- st = stack->ary_array;
- st[++sp] = str;
-#ifdef DEBUGGING
- tmps = "DOUBLE";
-#endif
- break;
- case A_BACKTICK:
- tmps = str_get(interp(str,argptr.arg_str,sp));
- st = stack->ary_array;
-#ifdef TAINT
- TAINT_PROPER("``");
-#endif
- fp = mypopen(tmps,"r");
- str_set(str,"");
- if (fp) {
- if (gimme == G_SCALAR) {
- while (str_gets(str,fp,str->str_cur) != Nullch)
- /*SUPPRESS 530*/
- ;
- }
- else {
- for (;;) {
- if (++sp > stack->ary_max) {
- astore(stack, sp, Nullstr);
- st = stack->ary_array;
- }
- str = st[sp] = Str_new(56,80);
- if (str_gets(str,fp,0) == Nullch) {
- sp--;
- break;
- }
- if (str->str_len - str->str_cur > 20) {
- str->str_len = str->str_cur+1;
- Renew(str->str_ptr, str->str_len, char);
- }
- str_2mortal(str);
- }
- }
- statusvalue = mypclose(fp);
- }
- else
- statusvalue = -1;
-
- if (gimme == G_SCALAR)
- st[++sp] = str;
-#ifdef DEBUGGING
- tmps = "BACK";
-#endif
- break;
- case A_WANTARRAY:
- {
- if (curcsv->wantarray == G_ARRAY)
- st[++sp] = &str_yes;
- else
- st[++sp] = &str_no;
- }
-#ifdef DEBUGGING
- tmps = "WANTARRAY";
-#endif
- break;
- case A_INDREAD:
- last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
- old_rschar = rschar;
- old_rslen = rslen;
- goto do_read;
- case A_GLOB:
- argflags |= AF_POST; /* enable newline chopping */
- last_in_stab = argptr.arg_stab;
- old_rschar = rschar;
- old_rslen = rslen;
- rslen = 1;
-#ifdef DOSISH
- rschar = 0;
-#else
-#ifdef CSH
- rschar = 0;
-#else
- rschar = '\n';
-#endif /* !CSH */
-#endif /* !MSDOS */
- goto do_read;
- case A_READ:
- last_in_stab = argptr.arg_stab;
- old_rschar = rschar;
- old_rslen = rslen;
- do_read:
- if (anum > 1) /* assign to scalar */
- gimme = G_SCALAR; /* force context to scalar */
- if (gimme == G_ARRAY)
- str = Str_new(57,0);
- ++sp;
- fp = Nullfp;
- if (stab_io(last_in_stab)) {
- fp = stab_io(last_in_stab)->ifp;
- if (!fp) {
- if (stab_io(last_in_stab)->flags & IOF_ARGV) {
- if (stab_io(last_in_stab)->flags & IOF_START) {
- stab_io(last_in_stab)->flags &= ~IOF_START;
- stab_io(last_in_stab)->lines = 0;
- if (alen(stab_array(last_in_stab)) < 0) {
- tmpstr = str_make("-",1); /* assume stdin */
- (void)apush(stab_array(last_in_stab), tmpstr);
- }
- }
- fp = nextargv(last_in_stab);
- if (!fp) { /* Note: fp != stab_io(last_in_stab)->ifp */
- (void)do_close(last_in_stab,FALSE); /* now it does*/
- stab_io(last_in_stab)->flags |= IOF_START;
- }
- }
- else if (argtype == A_GLOB) {
- (void) interp(str,stab_val(last_in_stab),sp);
- st = stack->ary_array;
- tmpstr = Str_new(55,0);
-#ifdef DOSISH
- str_set(tmpstr, "perlglob ");
- str_scat(tmpstr,str);
- str_cat(tmpstr," |");
-#else
-#ifdef CSH
- str_nset(tmpstr,cshname,cshlen);
- str_cat(tmpstr," -cf 'set nonomatch; glob ");
- str_scat(tmpstr,str);
- str_cat(tmpstr,"'|");
-#else
- str_set(tmpstr, "echo ");
- str_scat(tmpstr,str);
- str_cat(tmpstr,
- "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
-#endif /* !CSH */
-#endif /* !MSDOS */
- (void)do_open(last_in_stab,tmpstr->str_ptr,
- tmpstr->str_cur);
- fp = stab_io(last_in_stab)->ifp;
- str_free(tmpstr);
- }
- }
- }
- if (!fp && dowarn)
- warn("Read on closed filehandle <%s>",stab_ename(last_in_stab));
- tmplen = str->str_len; /* remember if already alloced */
- if (!tmplen)
- Str_Grow(str,80); /* try short-buffering it */
- keepgoing:
- if (!fp)
- st[sp] = &str_undef;
- else if (!str_gets(str,fp, optype == O_RCAT ? str->str_cur : 0)) {
- clearerr(fp);
- if (stab_io(last_in_stab)->flags & IOF_ARGV) {
- fp = nextargv(last_in_stab);
- if (fp)
- goto keepgoing;
- (void)do_close(last_in_stab,FALSE);
- stab_io(last_in_stab)->flags |= IOF_START;
- }
- else if (argflags & AF_POST) {
- (void)do_close(last_in_stab,FALSE);
- }
- st[sp] = &str_undef;
- rschar = old_rschar;
- rslen = old_rslen;
- if (gimme == G_ARRAY) {
- --sp;
- str_2mortal(str);
- goto array_return;
- }
- break;
- }
- else {
- stab_io(last_in_stab)->lines++;
- st[sp] = str;
-#ifdef TAINT
- str->str_tainted = 1; /* Anything from the outside world...*/
-#endif
- if (argflags & AF_POST) {
- if (str->str_cur > 0)
- str->str_cur--;
- if (str->str_ptr[str->str_cur] == rschar)
- str->str_ptr[str->str_cur] = '\0';
- else
- str->str_cur++;
- for (tmps = str->str_ptr; *tmps; tmps++)
- if (!isALPHA(*tmps) && !isDIGIT(*tmps) &&
- index("$&*(){}[]'\";\\|?<>~`",*tmps))
- break;
- if (*tmps && stat(str->str_ptr,&statbuf) < 0)
- goto keepgoing; /* unmatched wildcard? */
- }
- if (gimme == G_ARRAY) {
- if (str->str_len - str->str_cur > 20) {
- str->str_len = str->str_cur+1;
- Renew(str->str_ptr, str->str_len, char);
- }
- str_2mortal(str);
- if (++sp > stack->ary_max) {
- astore(stack, sp, Nullstr);
- st = stack->ary_array;
- }
- str = Str_new(58,80);
- goto keepgoing;
- }
- else if (!tmplen && str->str_len - str->str_cur > 80) {
- /* try to reclaim a bit of scalar space on 1st alloc */
- if (str->str_cur < 60)
- str->str_len = 80;
- else
- str->str_len = str->str_cur+40; /* allow some slop */
- Renew(str->str_ptr, str->str_len, char);
- }
- }
- rschar = old_rschar;
- rslen = old_rslen;
-#ifdef DEBUGGING
- tmps = "READ";
-#endif
- break;
- }
-#ifdef DEBUGGING
- if (debug & 8) {
- if (strEQ(tmps, "NULL"))
- deb("%d.%s\n",anum,tmps);
- else
- deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));
- }
-#endif
- if (anum < 8)
- arglast[anum] = sp;
- }
-
- if (ppaddr[optype]) {
- int status;
-
- /* pretend like we've been maintaining stack_* all along */
- stack_ary = stack->ary_array;
- stack_sp = stack_ary + sp;
- if (mark[optype] && stack_mark != arglast[0])
- warn("Inconsistent stack mark %d != %d", stack_mark, arglast[0]);
- stack_max = stack_ary + stack->ary_max;
-
- status = (*ppaddr[optype])(str, arg, gimme);
-
- if (savestack->ary_fill > mymarkbase) {
- warn("Inconsistent stack base");
- restorelist(mymarkbase);
- }
- sp = stack_sp - stack_ary;
- if (sp < arglast[0])
- warn("TOO MANY POPS");
- st += arglast[0];
- goto array_return;
- }
-
- st += arglast[0];
-
-#ifdef SMALLSWITCHES
- if (optype < O_CHOWN)
-#endif
- switch (optype) {
- case O_RCAT:
- STABSET(str);
- break;
- case O_ITEM:
- if (gimme == G_ARRAY)
- goto array_return;
- /* FALL THROUGH */
- case O_SCALAR:
- STR_SSET(str,st[1]);
- STABSET(str);
- break;
- case O_ITEM2:
- if (gimme == G_ARRAY)
- goto array_return;
- --anum;
- STR_SSET(str,st[arglast[anum]-arglast[0]]);
- STABSET(str);
- break;
- case O_ITEM3:
- if (gimme == G_ARRAY)
- goto array_return;
- --anum;
- STR_SSET(str,st[arglast[anum]-arglast[0]]);
- STABSET(str);
- break;
- case O_CONCAT:
- STR_SSET(str,st[1]);
- str_scat(str,st[2]);
- STABSET(str);
- break;
- case O_REPEAT:
- if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {
- sp = do_repeatary(arglast);
- goto array_return;
- }
- STR_SSET(str,st[1]);
- anum = (int)str_gnum(st[2]);
- if (anum >= 1) {
- tmpstr = Str_new(50, 0);
- tmps = str_get(str);
- str_nset(tmpstr,tmps,str->str_cur);
- tmps = str_get(tmpstr); /* force to be string */
- STR_GROW(str, (anum * str->str_cur) + 1);
- repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
- str->str_cur *= anum;
- str->str_ptr[str->str_cur] = '\0';
- str->str_nok = 0;
- str_free(tmpstr);
- }
- else {
- if (dowarn && st[2]->str_pok && !looks_like_number(st[2]))
- warn("Right operand of x is not numeric");
- str_sset(str,&str_no);
- }
- STABSET(str);
- break;
- case O_MATCH:
- sp = do_match(str,arg,
- gimme,arglast);
- if (gimme == G_ARRAY)
- goto array_return;
- STABSET(str);
- break;
- case O_NMATCH:
- sp = do_match(str,arg,
- G_SCALAR,arglast);
- str_sset(str, str_true(str) ? &str_no : &str_yes);
- STABSET(str);
- break;
- case O_SUBST:
- sp = do_subst(str,arg,arglast[0]);
- goto array_return;
- case O_NSUBST:
- sp = do_subst(str,arg,arglast[0]);
- str = arg->arg_ptr.arg_str;
- str_set(str, str_true(str) ? No : Yes);
- goto array_return;
- case O_ASSIGN:
- if (arg[1].arg_flags & AF_ARYOK) {
- if (arg->arg_len == 1) {
- arg->arg_type = O_LOCAL;
- goto local;
- }
- else {
- arg->arg_type = O_AASSIGN;
- goto aassign;
- }
- }
- else {
- arg->arg_type = O_SASSIGN;
- goto sassign;
- }
- case O_LOCAL:
- local:
- arglast[2] = arglast[1]; /* push a null array */
- /* FALL THROUGH */
- case O_AASSIGN:
- aassign:
- sp = do_assign(arg,
- gimme,arglast);
- goto array_return;
- case O_SASSIGN:
- sassign:
-#ifdef TAINT
- if (tainted && !st[2]->str_tainted)
- tainted = 0;
-#endif
- STR_SSET(str, st[2]);
- STABSET(str);
- break;
- case O_CHOP:
- st -= arglast[0];
- str = arg->arg_ptr.arg_str;
- for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
- do_chop(str,st[sp]);
- st += arglast[0];
- break;
- case O_DEFINED:
- if (arg[1].arg_type & A_DONT) {
- sp = do_defined(str,arg,
- gimme,arglast);
- goto array_return;
- }
- else if (str->str_pok || str->str_nok)
- goto say_yes;
- goto say_no;
- case O_UNDEF:
- if (arg[1].arg_type & A_DONT) {
- sp = do_undef(str,arg,
- gimme,arglast);
- goto array_return;
- }
- else if (str != stab_val(defstab)) {
- if (str->str_len) {
- if (str->str_state == SS_INCR)
- Str_Grow(str,0);
- Safefree(str->str_ptr);
- str->str_ptr = Nullch;
- str->str_len = 0;
- }
- str->str_pok = str->str_nok = 0;
- STABSET(str);
- }
- goto say_undef;
- case O_STUDY:
- sp = do_study(str,arg,
- gimme,arglast);
- goto array_return;
- case O_POW:
- value = str_gnum(st[1]);
- value = pow(value,str_gnum(st[2]));
- goto donumset;
- case O_MULTIPLY:
- value = str_gnum(st[1]);
- value *= str_gnum(st[2]);
- goto donumset;
- case O_DIVIDE:
- if ((value = str_gnum(st[2])) == 0.0)
- fatal("Illegal division by zero");
-#ifdef SLOPPYDIVIDE
- /* insure that 20./5. == 4. */
- {
- double x;
- int k;
- x = str_gnum(st[1]);
- if ((double)(int)x == x &&
- (double)(int)value == value &&
- (k = (int)x/(int)value)*(int)value == (int)x) {
- value = k;
- } else {
- value = x/value;
- }
- }
-#else
- value = str_gnum(st[1]) / value;
-#endif
- goto donumset;
- case O_MODULO:
- tmpulong = (unsigned long) str_gnum(st[2]);
- if (tmpulong == 0L)
- fatal("Illegal modulus zero");
-#ifndef lint
- value = str_gnum(st[1]);
- if (value >= 0.0)
- value = (double)(((unsigned long)value) % tmpulong);
- else {
- tmplong = (long)value;
- value = (double)(tmpulong - ((-tmplong - 1) % tmpulong)) - 1;
- }
-#endif
- goto donumset;
- case O_ADD:
- value = str_gnum(st[1]);
- value += str_gnum(st[2]);
- goto donumset;
- case O_SUBTRACT:
- value = str_gnum(st[1]);
- value -= str_gnum(st[2]);
- goto donumset;
- case O_LEFT_SHIFT:
- value = str_gnum(st[1]);
- anum = (int)str_gnum(st[2]);
-#ifndef lint
- value = (double)(U_L(value) << anum);
-#endif
- goto donumset;
- case O_RIGHT_SHIFT:
- value = str_gnum(st[1]);
- anum = (int)str_gnum(st[2]);
-#ifndef lint
- value = (double)(U_L(value) >> anum);
-#endif
- goto donumset;
- case O_LT:
- value = str_gnum(st[1]);
- value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_GT:
- value = str_gnum(st[1]);
- value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_LE:
- value = str_gnum(st[1]);
- value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_GE:
- value = str_gnum(st[1]);
- value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_EQ:
- if (dowarn) {
- if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
- (!st[2]->str_nok && !looks_like_number(st[2])) )
- warn("Possible use of == on string value");
- }
- value = str_gnum(st[1]);
- value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_NE:
- value = str_gnum(st[1]);
- value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
- goto donumset;
- case O_NCMP:
- value = str_gnum(st[1]);
- value -= str_gnum(st[2]);
- if (value > 0.0)
- value = 1.0;
- else if (value < 0.0)
- value = -1.0;
- goto donumset;
- case O_BIT_AND:
- if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
- value = str_gnum(st[1]);
-#ifndef lint
- value = (double)(U_L(value) & U_L(str_gnum(st[2])));
-#endif
- goto donumset;
- }
- else
- do_vop(optype,str,st[1],st[2]);
- break;
- case O_XOR:
- if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
- value = str_gnum(st[1]);
-#ifndef lint
- value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));
-#endif
- goto donumset;
- }
- else
- do_vop(optype,str,st[1],st[2]);
- break;
- case O_BIT_OR:
- if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
- value = str_gnum(st[1]);
-#ifndef lint
- value = (double)(U_L(value) | U_L(str_gnum(st[2])));
-#endif
- goto donumset;
- }
- else
- do_vop(optype,str,st[1],st[2]);
- break;
-/* use register in evaluating str_true() */
- case O_AND:
- if (str_true(st[1])) {
- anum = 2;
- optype = O_ITEM2;
- argflags = arg[anum].arg_flags;
- if (gimme == G_ARRAY)
- argflags |= AF_ARYOK;
- argtype = arg[anum].arg_type & A_MASK;
- argptr = arg[anum].arg_ptr;
- maxarg = anum = 1;
- sp = arglast[0];
- st -= sp;
- goto re_eval;
- }
- else {
- if (assigning) {
- str_sset(str, st[1]);
- STABSET(str);
- }
- else
- str = st[1];
- break;
- }
- case O_OR:
- if (str_true(st[1])) {
- if (assigning) {
- str_sset(str, st[1]);
- STABSET(str);
- }
- else
- str = st[1];
- break;
- }
- else {
- anum = 2;
- optype = O_ITEM2;
- argflags = arg[anum].arg_flags;
- if (gimme == G_ARRAY)
- argflags |= AF_ARYOK;
- argtype = arg[anum].arg_type & A_MASK;
- argptr = arg[anum].arg_ptr;
- maxarg = anum = 1;
- sp = arglast[0];
- st -= sp;
- goto re_eval;
- }
- case O_COND_EXPR:
- anum = (str_true(st[1]) ? 2 : 3);
- optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
- argflags = arg[anum].arg_flags;
- if (gimme == G_ARRAY)
- argflags |= AF_ARYOK;
- argtype = arg[anum].arg_type & A_MASK;
- argptr = arg[anum].arg_ptr;
- maxarg = anum = 1;
- sp = arglast[0];
- st -= sp;
- goto re_eval;
- case O_COMMA:
- if (gimme == G_ARRAY)
- goto array_return;
- str = st[2];
- break;
- case O_NEGATE:
- value = -str_gnum(st[1]);
- goto donumset;
- case O_NOT:
-#ifdef NOTNOT
- { char xxx = str_true(st[1]); value = (double) !xxx; }
-#else
- value = (double) !str_true(st[1]);
-#endif
- goto donumset;
- case O_COMPLEMENT:
- if (!sawvec || st[1]->str_nok) {
-#ifndef lint
- value = (double) ~U_L(str_gnum(st[1]));
-#endif
- goto donumset;
- }
- else {
- STR_SSET(str,st[1]);
- tmps = str_get(str);
- for (anum = str->str_cur; anum; anum--, tmps++)
- *tmps = ~*tmps;
- }
- break;
- case O_SELECT:
- stab_efullname(str,defoutstab);
- if (maxarg > 0) {
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- defoutstab = arg[1].arg_ptr.arg_stab;
- else
- defoutstab = stabent(str_get(st[1]),TRUE);
- if (!stab_io(defoutstab))
- stab_io(defoutstab) = stio_new();
- curoutstab = defoutstab;
- }
- STABSET(str);
- break;
- case O_WRITE:
- if (maxarg == 0)
- stab = defoutstab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD) {
- if (!(stab = arg[1].arg_ptr.arg_stab))
- stab = defoutstab;
- }
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab_io(stab)) {
- str_set(str, No);
- STABSET(str);
- break;
- }
- curoutstab = stab;
- fp = stab_io(stab)->ofp;
- if (stab_io(stab)->fmt_stab)
- form = stab_form(stab_io(stab)->fmt_stab);
- else
- form = stab_form(stab);
- if (!form || !fp) {
- if (dowarn) {
- if (form)
- warn("No format for filehandle");
- else {
- if (stab_io(stab)->ifp)
- warn("Filehandle only opened for input");
- else
- warn("Write on closed filehandle");
- }
- }
- str_set(str, No);
- STABSET(str);
- break;
- }
- format(&outrec,form,sp);
- do_write(&outrec,stab,sp);
- if (stab_io(stab)->flags & IOF_FLUSH)
- (void)fflush(fp);
- str_set(str, Yes);
- STABSET(str);
- break;
- case O_DBMOPEN:
-#ifdef SOME_DBM
- anum = arg[1].arg_type & A_MASK;
- if (anum == A_WORD || anum == A_STAB)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (st[3]->str_nok || st[3]->str_pok)
- anum = (int)str_gnum(st[3]);
- else
- anum = -1;
- value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
- goto donumset;
-#else
- fatal("No dbm or ndbm on this machine");
-#endif
- case O_DBMCLOSE:
-#ifdef SOME_DBM
- anum = arg[1].arg_type & A_MASK;
- if (anum == A_WORD || anum == A_STAB)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- hdbmclose(stab_hash(stab));
- goto say_yes;
-#else
- fatal("No dbm or ndbm on this machine");
-#endif
- case O_OPEN:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- tmps = str_get(st[2]);
- if (do_open(stab,tmps,st[2]->str_cur)) {
- value = (double)forkprocess;
- stab_io(stab)->lines = 0;
- goto donumset;
- }
- else if (forkprocess == 0) /* we are a new child */
- goto say_zero;
- else
- goto say_undef;
- /* break; */
- case O_TRANS:
- value = (double) do_trans(str,arg);
- str = arg->arg_ptr.arg_str;
- goto donumset;
- case O_NTRANS:
- str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
- str = arg->arg_ptr.arg_str;
- break;
- case O_CLOSE:
- if (maxarg == 0)
- stab = defoutstab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- str_set(str, do_close(stab,TRUE) ? Yes : No );
- STABSET(str);
- break;
- case O_EACH:
- sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
- gimme,arglast);
- goto array_return;
- case O_VALUES:
- case O_KEYS:
- sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
- gimme,arglast);
- goto array_return;
- case O_LARRAY:
- str->str_nok = str->str_pok = 0;
- str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
- str->str_state = SS_ARY;
- break;
- case O_ARRAY:
- ary = stab_array(arg[1].arg_ptr.arg_stab);
- maxarg = ary->ary_fill + 1;
- if (gimme == G_ARRAY) { /* array wanted */
- sp = arglast[0];
- st -= sp;
- if (maxarg > 0 && sp + maxarg > stack->ary_max) {
- astore(stack,sp + maxarg, Nullstr);
- st = stack->ary_array;
- }
- st += sp;
- Copy(ary->ary_array, &st[1], maxarg, STR*);
- sp += maxarg;
- goto array_return;
- }
- else {
- value = (double)maxarg;
- goto donumset;
- }
- case O_AELEM:
- anum = ((int)str_gnum(st[2])) - arybase;
- str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
- break;
- case O_DELETE:
- tmpstab = arg[1].arg_ptr.arg_stab;
- tmps = str_get(st[2]);
- str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
- if (tmpstab == envstab)
- my_setenv(tmps,Nullch);
- if (!str)
- goto say_undef;
- break;
- case O_LHASH:
- str->str_nok = str->str_pok = 0;
- str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
- str->str_state = SS_HASH;
- break;
- case O_HASH:
- if (gimme == G_ARRAY) { /* array wanted */
- sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
- gimme,arglast);
- goto array_return;
- }
- else {
- tmpstab = arg[1].arg_ptr.arg_stab;
- if (!stab_hash(tmpstab)->tbl_fill)
- goto say_zero;
- sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
- stab_hash(tmpstab)->tbl_max+1);
- str_set(str,buf);
- }
- break;
- case O_HELEM:
- tmpstab = arg[1].arg_ptr.arg_stab;
- tmps = str_get(st[2]);
- str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
- break;
- case O_LAELEM:
- anum = ((int)str_gnum(st[2])) - arybase;
- str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
- if (!str || str == &str_undef)
- fatal("Assignment to non-creatable value, subscript %d",anum);
- break;
- case O_LHELEM:
- tmpstab = arg[1].arg_ptr.arg_stab;
- tmps = str_get(st[2]);
- anum = st[2]->str_cur;
- str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
- if (!str || str == &str_undef)
- fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
- if (tmpstab == envstab) /* heavy wizardry going on here */
- str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
- /* he threw the brick up into the air */
- else if (tmpstab == sigstab)
- str_magic(str, tmpstab, 'S', tmps, anum);
-#ifdef SOME_DBM
- else if (stab_hash(tmpstab)->tbl_dbm)
- str_magic(str, tmpstab, 'D', tmps, anum);
-#endif
- else if (tmpstab == DBline)
- str_magic(str, tmpstab, 'L', tmps, anum);
- break;
- case O_LSLICE:
- anum = 2;
- argtype = FALSE;
- goto do_slice_already;
- case O_ASLICE:
- anum = 1;
- argtype = FALSE;
- goto do_slice_already;
- case O_HSLICE:
- anum = 0;
- argtype = FALSE;
- goto do_slice_already;
- case O_LASLICE:
- anum = 1;
- argtype = TRUE;
- goto do_slice_already;
- case O_LHSLICE:
- anum = 0;
- argtype = TRUE;
- do_slice_already:
- sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
- gimme,arglast);
- goto array_return;
- case O_SPLICE:
- sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),gimme,arglast);
- goto array_return;
- case O_PUSH:
- if (arglast[2] - arglast[1] != 1)
- str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
- else {
- str = Str_new(51,0); /* must copy the STR */
- str_sset(str,st[2]);
- (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
- }
- break;
- case O_POP:
- str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
- goto staticalization;
- case O_SHIFT:
- str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
- staticalization:
- if (!str)
- goto say_undef;
- if (ary->ary_flags & ARF_REAL)
- (void)str_2mortal(str);
- break;
- case O_UNPACK:
- sp = do_unpack(str,gimme,arglast);
- goto array_return;
- case O_SPLIT:
- value = str_gnum(st[3]);
- sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
- gimme,arglast);
- goto array_return;
- case O_LENGTH:
- if (maxarg < 1)
- value = (double)str_len(stab_val(defstab));
- else
- value = (double)str_len(st[1]);
- goto donumset;
- case O_SPRINTF:
- do_sprintf(str, sp-arglast[0], st+1);
- break;
- case O_SUBSTR:
- anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
- tmps = str_get(st[1]); /* force conversion to string */
- /*SUPPRESS 560*/
- if (argtype = (str == st[1]))
- str = arg->arg_ptr.arg_str;
- if (anum < 0)
- anum += st[1]->str_cur + arybase;
- if (anum < 0 || anum > st[1]->str_cur)
- str_nset(str,"",0);
- else {
- optype = maxarg < 3 ? st[1]->str_cur : (int)str_gnum(st[3]);
- if (optype < 0)
- optype = 0;
- tmps += anum;
- anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
- if (anum > optype)
- anum = optype;
- str_nset(str, tmps, anum);
- if (argtype) { /* it's an lvalue! */
- Lstring *lstr = (Lstring*)str;
-
- str->str_magic = st[1];
- st[1]->str_rare = 's';
- lstr->lstr_offset = tmps - str_get(st[1]);
- lstr->lstr_len = anum;
- }
- }
- break;
- case O_PACK:
- /*SUPPRESS 701*/
- (void)do_pack(str,arglast);
- break;
- case O_GREP:
- sp = do_grep(arg,str,gimme,arglast);
- goto array_return;
- case O_JOIN:
- do_join(str,arglast);
- break;
- case O_SLT:
- tmps = str_get(st[1]);
- value = (double) (str_cmp(st[1],st[2]) < 0);
- goto donumset;
- case O_SGT:
- tmps = str_get(st[1]);
- value = (double) (str_cmp(st[1],st[2]) > 0);
- goto donumset;
- case O_SLE:
- tmps = str_get(st[1]);
- value = (double) (str_cmp(st[1],st[2]) <= 0);
- goto donumset;
- case O_SGE:
- tmps = str_get(st[1]);
- value = (double) (str_cmp(st[1],st[2]) >= 0);
- goto donumset;
- case O_SEQ:
- tmps = str_get(st[1]);
- value = (double) str_eq(st[1],st[2]);
- goto donumset;
- case O_SNE:
- tmps = str_get(st[1]);
- value = (double) !str_eq(st[1],st[2]);
- goto donumset;
- case O_SCMP:
- tmps = str_get(st[1]);
- value = (double) str_cmp(st[1],st[2]);
- goto donumset;
- case O_SUBR:
- sp = do_subr(arg,gimme,arglast);
- st = stack->ary_array + arglast[0]; /* maybe realloced */
- goto array_return;
- case O_DBSUBR:
- sp = do_subr(arg,gimme,arglast);
- st = stack->ary_array + arglast[0]; /* maybe realloced */
- goto array_return;
- case O_CALLER:
- sp = do_caller(arg,maxarg,gimme,arglast);
- st = stack->ary_array + arglast[0]; /* maybe realloced */
- goto array_return;
- case O_SORT:
- sp = do_sort(str,arg,
- gimme,arglast);
- goto array_return;
- case O_REVERSE:
- if (gimme == G_ARRAY)
- sp = do_reverse(arglast);
- else
- sp = do_sreverse(str, arglast);
- goto array_return;
- case O_WARN:
- if (arglast[2] - arglast[1] != 1) {
- do_join(str,arglast);
- tmps = str_get(str);
- }
- else {
- str = st[2];
- tmps = str_get(st[2]);
- }
- if (!tmps || !*tmps)
- tmps = "Warning: something's wrong";
- warn("%s",tmps);
- goto say_yes;
- case O_DIE:
- if (arglast[2] - arglast[1] != 1) {
- do_join(str,arglast);
- tmps = str_get(str);
- }
- else {
- str = st[2];
- tmps = str_get(st[2]);
- }
- if (!tmps || !*tmps)
- tmps = "Died";
- fatal("%s",tmps);
- goto say_zero;
- case O_PRTF:
- case O_PRINT:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab)
- stab = defoutstab;
- if (!stab_io(stab)) {
- if (dowarn)
- warn("Filehandle never opened");
- goto say_zero;
- }
- if (!(fp = stab_io(stab)->ofp)) {
- if (dowarn) {
- if (stab_io(stab)->ifp)
- warn("Filehandle opened only for input");
- else
- warn("Print on closed filehandle");
- }
- goto say_zero;
- }
- else {
- if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
- value = (double)do_aprint(arg,fp,arglast);
- else {
- value = (double)do_print(st[2],fp);
- if (orslen && optype == O_PRINT)
- if (fwrite(ors, 1, orslen, fp) == 0)
- goto say_zero;
- }
- if (stab_io(stab)->flags & IOF_FLUSH)
- if (fflush(fp) == EOF)
- goto say_zero;
- }
- goto donumset;
- case O_CHDIR:
- if (maxarg < 1)
- tmps = Nullch;
- else
- tmps = str_get(st[1]);
- if (!tmps || !*tmps) {
- tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
- tmps = str_get(tmpstr);
- }
- if (!tmps || !*tmps) {
- tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
- tmps = str_get(tmpstr);
- }
-#ifdef TAINT
- TAINT_PROPER("chdir");
-#endif
- value = (double)(chdir(tmps) >= 0);
- goto donumset;
- case O_EXIT:
- if (maxarg < 1)
- anum = 0;
- else
- anum = (int)str_gnum(st[1]);
- my_exit(anum);
- goto say_zero;
- case O_RESET:
- if (maxarg < 1)
- tmps = "";
- else
- tmps = str_get(st[1]);
- str_reset(tmps,curcmd->c_stash);
- value = 1.0;
- goto donumset;
- case O_LIST:
- if (gimme == G_ARRAY)
- goto array_return;
- if (maxarg > 0)
- str = st[sp - arglast[0]]; /* unwanted list, return last item */
- else
- str = &str_undef;
- break;
- case O_EOF:
- if (maxarg <= 0)
- stab = last_in_stab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- str_set(str, do_eof(stab) ? Yes : No);
- STABSET(str);
- break;
- case O_GETC:
- if (maxarg <= 0)
- stab = stdinstab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab)
- stab = argvstab;
- if (!stab || do_eof(stab)) /* make sure we have fp with something */
- goto say_undef;
- else {
-#ifdef TAINT
- tainted = 1;
-#endif
- str_set(str," ");
- *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
- }
- STABSET(str);
- break;
- case O_TELL:
- if (maxarg <= 0)
- stab = last_in_stab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_tell(stab);
-#else
- (void)do_tell(stab);
-#endif
- goto donumset;
- case O_RECV:
- case O_READ:
- case O_SYSREAD:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- tmps = str_get(st[2]);
- anum = (int)str_gnum(st[3]);
- errno = 0;
- maxarg = sp - arglast[0];
- if (maxarg > 4)
- warn("Too many args on read");
- if (maxarg == 4)
- maxarg = (int)str_gnum(st[4]);
- else
- maxarg = 0;
- if (!stab_io(stab) || !stab_io(stab)->ifp)
- goto say_undef;
-#ifdef HAS_SOCKET
- if (optype == O_RECV) {
- argtype = sizeof buf;
- STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
- anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, maxarg,
- buf, &argtype);
- if (anum >= 0) {
- st[2]->str_cur = anum;
- st[2]->str_ptr[anum] = '\0';
- str_nset(str,buf,argtype);
- }
- else
- str_sset(str,&str_undef);
- break;
- }
-#else
- if (optype == O_RECV)
- goto badsock;
-#endif
- STR_GROW(st[2], anum+maxarg+1), (tmps = str_get(st[2])); /* sneaky */
- if (optype == O_SYSREAD) {
- anum = read(fileno(stab_io(stab)->ifp), tmps+maxarg, anum);
- }
- else
-#ifdef HAS_SOCKET
- if (stab_io(stab)->type == 's') {
- argtype = sizeof buf;
- anum = recvfrom(fileno(stab_io(stab)->ifp), tmps+maxarg, anum, 0,
- buf, &argtype);
- }
- else
-#endif
- anum = fread(tmps+maxarg, 1, anum, stab_io(stab)->ifp);
- if (anum < 0)
- goto say_undef;
- st[2]->str_cur = anum+maxarg;
- st[2]->str_ptr[anum+maxarg] = '\0';
- value = (double)anum;
- goto donumset;
- case O_SYSWRITE:
- case O_SEND:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- tmps = str_get(st[2]);
- anum = (int)str_gnum(st[3]);
- errno = 0;
- stio = stab_io(stab);
- maxarg = sp - arglast[0];
- if (!stio || !stio->ifp) {
- anum = -1;
- if (dowarn) {
- if (optype == O_SYSWRITE)
- warn("Syswrite on closed filehandle");
- else
- warn("Send on closed socket");
- }
- }
- else if (optype == O_SYSWRITE) {
- if (maxarg > 4)
- warn("Too many args on syswrite");
- if (maxarg == 4)
- optype = (int)str_gnum(st[4]);
- else
- optype = 0;
- anum = write(fileno(stab_io(stab)->ifp), tmps+optype, anum);
- }
-#ifdef HAS_SOCKET
- else if (maxarg >= 4) {
- if (maxarg > 4)
- warn("Too many args on send");
- tmps2 = str_get(st[4]);
- anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
- anum, tmps2, st[4]->str_cur);
- }
- else
- anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
-#else
- else
- goto badsock;
-#endif
- if (anum < 0)
- goto say_undef;
- value = (double)anum;
- goto donumset;
- case O_SEEK:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- value = str_gnum(st[2]);
- str_set(str, do_seek(stab,
- (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
- STABSET(str);
- break;
- case O_RETURN:
- tmps = "_SUB_"; /* just fake up a "last _SUB_" */
- optype = O_LAST;
- if (curcsv && curcsv->wantarray == G_ARRAY) {
- lastretstr = Nullstr;
- lastspbase = arglast[1];
- lastsize = arglast[2] - arglast[1];
- }
- else
- lastretstr = str_mortal(st[arglast[2] - arglast[0]]);
- goto dopop;
- case O_REDO:
- case O_NEXT:
- case O_LAST:
- tmps = Nullch;
- if (maxarg > 0) {
- tmps = str_get(arg[1].arg_ptr.arg_str);
- dopop:
- while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
- strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
-#ifdef DEBUGGING
- if (debug & 4) {
- deb("(Skipping label #%d %s)\n",loop_ptr,
- loop_stack[loop_ptr].loop_label);
- }
-#endif
- loop_ptr--;
- }
-#ifdef DEBUGGING
- if (debug & 4) {
- deb("(Found label #%d %s)\n",loop_ptr,
- loop_stack[loop_ptr].loop_label);
- }
-#endif
- }
- if (loop_ptr < 0) {
- if (tmps && strEQ(tmps, "_SUB_"))
- fatal("Can't return outside a subroutine");
- fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
- }
- if (!lastretstr && optype == O_LAST && lastsize) {
- st -= arglast[0];
- st += lastspbase + 1;
- optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
- if (optype) {
- for (anum = lastsize; anum > 0; anum--,st++)
- st[optype] = str_mortal(st[0]);
- }
- longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
- }
- longjmp(loop_stack[loop_ptr].loop_env, optype);
- case O_DUMP:
- case O_GOTO:/* shudder */
- goto_targ = str_get(arg[1].arg_ptr.arg_str);
- if (!*goto_targ)
- goto_targ = Nullch; /* just restart from top */
- if (optype == O_DUMP) {
- do_undump = TRUE;
- my_unexec();
- }
- longjmp(top_env, 1);
- case O_INDEX:
- tmps = str_get(st[1]);
- if (maxarg < 3)
- anum = 0;
- else {
- anum = (int) str_gnum(st[3]) - arybase;
- if (anum < 0)
- anum = 0;
- else if (anum > st[1]->str_cur)
- anum = st[1]->str_cur;
- }
-#ifndef lint
- if (!(tmps2 = fbminstr((unsigned char*)tmps + anum,
- (unsigned char*)tmps + st[1]->str_cur, st[2])))
-#else
- if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
-#endif
- value = (double)(-1 + arybase);
- else
- value = (double)(tmps2 - tmps + arybase);
- goto donumset;
- case O_RINDEX:
- tmps = str_get(st[1]);
- tmps2 = str_get(st[2]);
- if (maxarg < 3)
- anum = st[1]->str_cur;
- else {
- anum = (int) str_gnum(st[3]) - arybase + st[2]->str_cur;
- if (anum < 0)
- anum = 0;
- else if (anum > st[1]->str_cur)
- anum = st[1]->str_cur;
- }
-#ifndef lint
- if (!(tmps2 = rninstr(tmps, tmps + anum,
- tmps2, tmps2 + st[2]->str_cur)))
-#else
- if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
-#endif
- value = (double)(-1 + arybase);
- else
- value = (double)(tmps2 - tmps + arybase);
- goto donumset;
- case O_TIME:
-#ifndef lint
- value = (double) time(Null(long*));
-#endif
- goto donumset;
- case O_TMS:
- sp = do_tms(str,gimme,arglast);
- goto array_return;
- case O_LOCALTIME:
- if (maxarg < 1)
- (void)time(&when);
- else
- when = (time_t)str_gnum(st[1]);
- sp = do_time(str,localtime(&when),
- gimme,arglast);
- goto array_return;
- case O_GMTIME:
- if (maxarg < 1)
- (void)time(&when);
- else
- when = (time_t)str_gnum(st[1]);
- sp = do_time(str,gmtime(&when),
- gimme,arglast);
- goto array_return;
- case O_TRUNCATE:
- sp = do_truncate(str,arg,
- gimme,arglast);
- goto array_return;
- case O_LSTAT:
- case O_STAT:
- sp = do_stat(str,arg,
- gimme,arglast);
- goto array_return;
- case O_CRYPT:
-#ifdef HAS_CRYPT
- tmps = str_get(st[1]);
-#ifdef FCRYPT
- str_set(str,fcrypt(tmps,str_get(st[2])));
-#else
- str_set(str,crypt(tmps,str_get(st[2])));
-#endif
-#else
- fatal(
- "The crypt() function is unimplemented due to excessive paranoia.");
-#endif
- break;
- case O_ATAN2:
- value = str_gnum(st[1]);
- value = atan2(value,str_gnum(st[2]));
- goto donumset;
- case O_SIN:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- value = sin(value);
- goto donumset;
- case O_COS:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- value = cos(value);
- goto donumset;
- case O_RAND:
- if (maxarg < 1)
- value = 1.0;
- else
- value = str_gnum(st[1]);
- if (value == 0.0)
- value = 1.0;
-#if RANDBITS == 31
- value = rand() * value / 2147483648.0;
-#else
-#if RANDBITS == 16
- value = rand() * value / 65536.0;
-#else
-#if RANDBITS == 15
- value = rand() * value / 32768.0;
-#else
- value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
-#endif
-#endif
-#endif
- goto donumset;
- case O_SRAND:
- if (maxarg < 1) {
- (void)time(&when);
- anum = when;
- }
- else
- anum = (int)str_gnum(st[1]);
- (void)srand(anum);
- goto say_yes;
- case O_EXP:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- value = exp(value);
- goto donumset;
- case O_LOG:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- if (value <= 0.0)
- fatal("Can't take log of %g\n", value);
- value = log(value);
- goto donumset;
- case O_SQRT:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- if (value < 0.0)
- fatal("Can't take sqrt of %g\n", value);
- value = sqrt(value);
- goto donumset;
- case O_INT:
- if (maxarg < 1)
- value = str_gnum(stab_val(defstab));
- else
- value = str_gnum(st[1]);
- if (value >= 0.0)
- (void)modf(value,&value);
- else {
- (void)modf(-value,&value);
- value = -value;
- }
- goto donumset;
- case O_ORD:
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
-#ifndef I286
- value = (double) (*tmps & 255);
-#else
- anum = (int) *tmps;
- value = (double) (anum & 255);
-#endif
- goto donumset;
- case O_ALARM:
-#ifdef HAS_ALARM
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
- if (!tmps)
- tmps = "0";
- anum = alarm((unsigned int)atoi(tmps));
- if (anum < 0)
- goto say_undef;
- value = (double)anum;
- goto donumset;
-#else
- fatal("Unsupported function alarm");
- break;
-#endif
- case O_SLEEP:
- if (maxarg < 1)
- tmps = Nullch;
- else
- tmps = str_get(st[1]);
- (void)time(&when);
- if (!tmps || !*tmps)
- sleep((32767<<16)+32767);
- else
- sleep((unsigned int)atoi(tmps));
-#ifndef lint
- value = (double)when;
- (void)time(&when);
- value = ((double)when) - value;
-#endif
- goto donumset;
- case O_RANGE:
- sp = do_range(gimme,arglast);
- goto array_return;
- case O_F_OR_R:
- if (gimme == G_ARRAY) { /* it's a range */
- /* can we optimize to constant array? */
- if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
- (arg[2].arg_type & A_MASK) == A_SINGLE) {
- st[2] = arg[2].arg_ptr.arg_str;
- sp = do_range(gimme,arglast);
- st = stack->ary_array;
- maxarg = sp - arglast[0];
- str_free(arg[1].arg_ptr.arg_str);
- arg[1].arg_ptr.arg_str = Nullstr;
- str_free(arg[2].arg_ptr.arg_str);
- arg[2].arg_ptr.arg_str = Nullstr;
- arg->arg_type = O_ARRAY;
- arg[1].arg_type = A_STAB|A_DONT;
- arg->arg_len = 1;
- stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
- ary = stab_array(stab);
- afill(ary,maxarg - 1);
- anum = maxarg;
- st += arglast[0]+1;
- while (maxarg-- > 0)
- ary->ary_array[maxarg] = str_smake(st[maxarg]);
- st -= arglast[0]+1;
- goto array_return;
- }
- arg->arg_type = optype = O_RANGE;
- maxarg = arg->arg_len = 2;
- anum = 2;
- arg[anum].arg_flags &= ~AF_ARYOK;
- argflags = arg[anum].arg_flags;
- argtype = arg[anum].arg_type & A_MASK;
- arg[anum].arg_type = argtype;
- argptr = arg[anum].arg_ptr;
- sp = arglast[0];
- st -= sp;
- sp++;
- goto re_eval;
- }
- arg->arg_type = O_FLIP;
- /* FALL THROUGH */
- case O_FLIP:
- if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
- last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
- :
- str_true(st[1]) ) {
- arg[2].arg_type &= ~A_DONT;
- arg[1].arg_type |= A_DONT;
- arg->arg_type = optype = O_FLOP;
- if (arg->arg_flags & AF_COMMON) {
- str_numset(str,0.0);
- anum = 2;
- argflags = arg[2].arg_flags;
- argtype = arg[2].arg_type & A_MASK;
- argptr = arg[2].arg_ptr;
- sp = arglast[0];
- st -= sp++;
- goto re_eval;
- }
- else {
- str_numset(str,1.0);
- break;
- }
- }
- str_set(str,"");
- break;
- case O_FLOP:
- str_inc(str);
- if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
- last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
- :
- str_true(st[2]) ) {
- arg->arg_type = O_FLIP;
- arg[1].arg_type &= ~A_DONT;
- arg[2].arg_type |= A_DONT;
- str_cat(str,"E0");
- }
- break;
- case O_FORK:
-#ifdef HAS_FORK
- anum = fork();
- if (anum < 0)
- goto say_undef;
- if (!anum) {
- /*SUPPRESS 560*/
- if (tmpstab = stabent("$",allstabs))
- str_numset(STAB_STR(tmpstab),(double)getpid());
- hclear(pidstatus, FALSE); /* no kids, so don't wait for 'em */
- }
- value = (double)anum;
- goto donumset;
-#else
- fatal("Unsupported function fork");
- break;
-#endif
- case O_WAIT:
-#ifdef HAS_WAIT
-#ifndef lint
- anum = wait(&argflags);
- if (anum > 0)
- pidgone(anum,argflags);
- value = (double)anum;
-#endif
- statusvalue = (unsigned short)argflags;
- goto donumset;
-#else
- fatal("Unsupported function wait");
- break;
-#endif
- case O_WAITPID:
-#ifdef HAS_WAIT
-#ifndef lint
- anum = (int)str_gnum(st[1]);
- optype = (int)str_gnum(st[2]);
- anum = wait4pid(anum, &argflags,optype);
- value = (double)anum;
-#endif
- statusvalue = (unsigned short)argflags;
- goto donumset;
-#else
- fatal("Unsupported function wait");
- break;
-#endif
- case O_SYSTEM:
-#ifdef HAS_FORK
-#ifdef TAINT
- if (arglast[2] - arglast[1] == 1) {
- taintenv();
- tainted |= st[2]->str_tainted;
- TAINT_PROPER("system");
- }
-#endif
- while ((anum = vfork()) == -1) {
- if (errno != EAGAIN) {
- value = -1.0;
- goto donumset;
- }
- sleep(5);
- }
- if (anum > 0) {
-#ifndef lint
- ihand = signal(SIGINT, SIG_IGN);
- qhand = signal(SIGQUIT, SIG_IGN);
- argtype = wait4pid(anum, &argflags, 0);
-#else
- ihand = qhand = 0;
-#endif
- (void)signal(SIGINT, ihand);
- (void)signal(SIGQUIT, qhand);
- statusvalue = (unsigned short)argflags;
- if (argtype < 0)
- value = -1.0;
- else {
- value = (double)((unsigned int)argflags & 0xffff);
- }
- do_execfree(); /* free any memory child malloced on vfork */
- goto donumset;
- }
- if ((arg[1].arg_type & A_MASK) == A_STAB)
- value = (double)do_aexec(st[1],arglast);
- else if (arglast[2] - arglast[1] != 1)
- value = (double)do_aexec(Nullstr,arglast);
- else {
- value = (double)do_exec(str_get(str_mortal(st[2])));
- }
- _exit(-1);
-#else /* ! FORK */
- if ((arg[1].arg_type & A_MASK) == A_STAB)
- value = (double)do_aspawn(st[1],arglast);
- else if (arglast[2] - arglast[1] != 1)
- value = (double)do_aspawn(Nullstr,arglast);
- else {
- value = (double)do_spawn(str_get(str_mortal(st[2])));
- }
- goto donumset;
-#endif /* FORK */
- case O_EXEC_OP:
- if ((arg[1].arg_type & A_MASK) == A_STAB)
- value = (double)do_aexec(st[1],arglast);
- else if (arglast[2] - arglast[1] != 1)
- value = (double)do_aexec(Nullstr,arglast);
- else {
-#ifdef TAINT
- taintenv();
- tainted |= st[2]->str_tainted;
- TAINT_PROPER("exec");
-#endif
- value = (double)do_exec(str_get(str_mortal(st[2])));
- }
- goto donumset;
- case O_HEX:
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
- value = (double)scanhex(tmps, 99, &argtype);
- goto donumset;
-
- case O_OCT:
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
- while (*tmps && (isSPACE(*tmps) || *tmps == '0'))
- tmps++;
- if (*tmps == 'x')
- value = (double)scanhex(++tmps, 99, &argtype);
- else
- value = (double)scanoct(tmps, 99, &argtype);
- goto donumset;
-
-/* These common exits are hidden here in the middle of the switches for the
- benefit of those machines with limited branch addressing. Sigh. */
-
-array_return:
-#ifdef DEBUGGING
- if (debug) {
- dlevel--;
- if (debug & 8) {
- anum = sp - arglast[0];
- switch (anum) {
- case 0:
- deb("%s RETURNS ()\n",opname[optype]);
- break;
- case 1:
- deb("%s RETURNS (\"%s\")\n",opname[optype],
- st[1] ? str_get(st[1]) : "");
- break;
- default:
- tmps = st[1] ? str_get(st[1]) : "";
- deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\")\n",opname[optype],
- anum,tmps,anum==2?"":"...,",
- st[anum] ? str_get(st[anum]) : "");
- break;
- }
- }
- }
-#endif
- stack_ary = stack->ary_array;
- stack_max = stack_ary + stack->ary_max;
- stack_sp = stack_ary + sp;
- return sp;
-
-say_yes:
- str = &str_yes;
- goto normal_return;
-
-say_no:
- str = &str_no;
- goto normal_return;
-
-say_undef:
- str = &str_undef;
- goto normal_return;
-
-say_zero:
- value = 0.0;
- /* FALL THROUGH */
-
-donumset:
- str_numset(str,value);
- STABSET(str);
- st[1] = str;
-#ifdef DEBUGGING
- if (debug) {
- dlevel--;
- if (debug & 8)
- deb("%s RETURNS \"%f\"\n",opname[optype],value);
- }
-#endif
- stack_ary = stack->ary_array;
- stack_max = stack_ary + stack->ary_max;
- stack_sp = stack_ary + arglast[0] + 1;
- return arglast[0] + 1;
-#ifdef SMALLSWITCHES
- }
- else
- switch (optype) {
-#endif
- case O_CHOWN:
-#ifdef HAS_CHOWN
- value = (double)apply(optype,arglast);
- goto donumset;
-#else
- fatal("Unsupported function chown");
- break;
-#endif
- case O_KILL:
-#ifdef HAS_KILL
- value = (double)apply(optype,arglast);
- goto donumset;
-#else
- fatal("Unsupported function kill");
- break;
-#endif
- case O_UNLINK:
- case O_CHMOD:
- case O_UTIME:
- value = (double)apply(optype,arglast);
- goto donumset;
- case O_UMASK:
-#ifdef HAS_UMASK
- if (maxarg < 1) {
- anum = umask(0);
- (void)umask(anum);
- }
- else
- anum = umask((int)str_gnum(st[1]));
- value = (double)anum;
-#ifdef TAINT
- TAINT_PROPER("umask");
-#endif
- goto donumset;
-#else
- fatal("Unsupported function umask");
- break;
-#endif
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- case O_MSGGET:
- case O_SHMGET:
- case O_SEMGET:
- if ((anum = do_ipcget(optype, arglast)) == -1)
- goto say_undef;
- value = (double)anum;
- goto donumset;
- case O_MSGCTL:
- case O_SHMCTL:
- case O_SEMCTL:
- anum = do_ipcctl(optype, arglast);
- if (anum == -1)
- goto say_undef;
- if (anum != 0) {
- value = (double)anum;
- goto donumset;
- }
- str_set(str,"0 but true");
- STABSET(str);
- break;
- case O_MSGSND:
- value = (double)(do_msgsnd(arglast) >= 0);
- goto donumset;
- case O_MSGRCV:
- value = (double)(do_msgrcv(arglast) >= 0);
- goto donumset;
- case O_SEMOP:
- value = (double)(do_semop(arglast) >= 0);
- goto donumset;
- case O_SHMREAD:
- case O_SHMWRITE:
- value = (double)(do_shmio(optype, arglast) >= 0);
- goto donumset;
-#else /* not SYSVIPC */
- case O_MSGGET:
- case O_MSGCTL:
- case O_MSGSND:
- case O_MSGRCV:
- case O_SEMGET:
- case O_SEMCTL:
- case O_SEMOP:
- case O_SHMGET:
- case O_SHMCTL:
- case O_SHMREAD:
- case O_SHMWRITE:
- fatal("System V IPC is not implemented on this machine");
-#endif /* not SYSVIPC */
- case O_RENAME:
- tmps = str_get(st[1]);
- tmps2 = str_get(st[2]);
-#ifdef TAINT
- TAINT_PROPER("rename");
-#endif
-#ifdef HAS_RENAME
- value = (double)(rename(tmps,tmps2) >= 0);
-#else
- if (same_dirent(tmps2, tmps)) /* can always rename to same name */
- anum = 1;
- else {
- if (euid || stat(tmps2,&statbuf) < 0 || !S_ISDIR(statbuf.st_mode))
- (void)UNLINK(tmps2);
- if (!(anum = link(tmps,tmps2)))
- anum = UNLINK(tmps);
- }
- value = (double)(anum >= 0);
-#endif
- goto donumset;
- case O_LINK:
-#ifdef HAS_LINK
- tmps = str_get(st[1]);
- tmps2 = str_get(st[2]);
-#ifdef TAINT
- TAINT_PROPER("link");
-#endif
- value = (double)(link(tmps,tmps2) >= 0);
- goto donumset;
-#else
- fatal("Unsupported function link");
- break;
-#endif
- case O_MKDIR:
- tmps = str_get(st[1]);
- anum = (int)str_gnum(st[2]);
-#ifdef TAINT
- TAINT_PROPER("mkdir");
-#endif
-#ifdef HAS_MKDIR
- value = (double)(mkdir(tmps,anum) >= 0);
- goto donumset;
-#else
- (void)strcpy(buf,"mkdir ");
-#endif
-#if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
- one_liner:
- for (tmps2 = buf+6; *tmps; ) {
- *tmps2++ = '\\';
- *tmps2++ = *tmps++;
- }
- (void)strcpy(tmps2," 2>&1");
- rsfp = mypopen(buf,"r");
- if (rsfp) {
- *buf = '\0';
- tmps2 = fgets(buf,sizeof buf,rsfp);
- (void)mypclose(rsfp);
- if (tmps2 != Nullch) {
- for (errno = 1; errno < sys_nerr; errno++) {
- if (instr(buf,sys_errlist[errno])) /* you don't see this */
- goto say_zero;
- }
- errno = 0;
-#ifndef EACCES
-#define EACCES EPERM
-#endif
- if (instr(buf,"cannot make"))
- errno = EEXIST;
- else if (instr(buf,"existing file"))
- errno = EEXIST;
- else if (instr(buf,"ile exists"))
- errno = EEXIST;
- else if (instr(buf,"non-exist"))
- errno = ENOENT;
- else if (instr(buf,"does not exist"))
- errno = ENOENT;
- else if (instr(buf,"not empty"))
- errno = EBUSY;
- else if (instr(buf,"cannot access"))
- errno = EACCES;
- else
- errno = EPERM;
- goto say_zero;
- }
- else { /* some mkdirs return no failure indication */
- tmps = str_get(st[1]);
- anum = (stat(tmps,&statbuf) >= 0);
- if (optype == O_RMDIR)
- anum = !anum;
- if (anum)
- errno = 0;
- else
- errno = EACCES; /* a guess */
- value = (double)anum;
- }
- goto donumset;
- }
- else
- goto say_zero;
-#endif
- case O_RMDIR:
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
-#ifdef TAINT
- TAINT_PROPER("rmdir");
-#endif
-#ifdef HAS_RMDIR
- value = (double)(rmdir(tmps) >= 0);
- goto donumset;
-#else
- (void)strcpy(buf,"rmdir ");
- goto one_liner; /* see above in HAS_MKDIR */
-#endif
- case O_GETPPID:
-#ifdef HAS_GETPPID
- value = (double)getppid();
- goto donumset;
-#else
- fatal("Unsupported function getppid");
- break;
-#endif
- case O_GETPGRP:
-#ifdef HAS_GETPGRP
- if (maxarg < 1)
- anum = 0;
- else
- anum = (int)str_gnum(st[1]);
-#ifdef _POSIX_SOURCE
- if (anum != 0)
- fatal("POSIX getpgrp can't take an argument");
- value = (double)getpgrp();
-#else
- value = (double)getpgrp(anum);
-#endif
- goto donumset;
-#else
- fatal("The getpgrp() function is unimplemented on this machine");
- break;
-#endif
- case O_SETPGRP:
-#ifdef HAS_SETPGRP
- argtype = (int)str_gnum(st[1]);
- anum = (int)str_gnum(st[2]);
-#ifdef TAINT
- TAINT_PROPER("setpgrp");
-#endif
- value = (double)(setpgrp(argtype,anum) >= 0);
- goto donumset;
-#else
- fatal("The setpgrp() function is unimplemented on this machine");
- break;
-#endif
- case O_GETPRIORITY:
-#ifdef HAS_GETPRIORITY
- argtype = (int)str_gnum(st[1]);
- anum = (int)str_gnum(st[2]);
- value = (double)getpriority(argtype,anum);
- goto donumset;
-#else
- fatal("The getpriority() function is unimplemented on this machine");
- break;
-#endif
- case O_SETPRIORITY:
-#ifdef HAS_SETPRIORITY
- argtype = (int)str_gnum(st[1]);
- anum = (int)str_gnum(st[2]);
- optype = (int)str_gnum(st[3]);
-#ifdef TAINT
- TAINT_PROPER("setpriority");
-#endif
- value = (double)(setpriority(argtype,anum,optype) >= 0);
- goto donumset;
-#else
- fatal("The setpriority() function is unimplemented on this machine");
- break;
-#endif
- case O_CHROOT:
-#ifdef HAS_CHROOT
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
-#ifdef TAINT
- TAINT_PROPER("chroot");
-#endif
- value = (double)(chroot(tmps) >= 0);
- goto donumset;
-#else
- fatal("Unsupported function chroot");
- break;
-#endif
- case O_FCNTL:
- case O_IOCTL:
- if (maxarg <= 0)
- stab = last_in_stab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- argtype = U_I(str_gnum(st[2]));
-#ifdef TAINT
- TAINT_PROPER("ioctl");
-#endif
- anum = do_ctl(optype,stab,argtype,st[3]);
- if (anum == -1)
- goto say_undef;
- if (anum != 0) {
- value = (double)anum;
- goto donumset;
- }
- str_set(str,"0 but true");
- STABSET(str);
- break;
- case O_FLOCK:
-#ifdef HAS_FLOCK
- if (maxarg <= 0)
- stab = last_in_stab;
- else if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (stab && stab_io(stab))
- fp = stab_io(stab)->ifp;
- else
- fp = Nullfp;
- if (fp) {
- argtype = (int)str_gnum(st[2]);
- value = (double)(flock(fileno(fp),argtype) >= 0);
- }
- else
- value = 0;
- goto donumset;
-#else
- fatal("The flock() function is unimplemented on this machine");
- break;
-#endif
- case O_UNSHIFT:
- ary = stab_array(arg[1].arg_ptr.arg_stab);
- if (arglast[2] - arglast[1] != 1)
- do_unshift(ary,arglast);
- else {
- STR *tmpstr = Str_new(52,0); /* must copy the STR */
- str_sset(tmpstr,st[2]);
- aunshift(ary,1);
- (void)astore(ary,0,tmpstr);
- }
- value = (double)(ary->ary_fill + 1);
- goto donumset;
-
- case O_TRY:
- sp = do_try(arg[1].arg_ptr.arg_cmd,
- gimme,arglast);
- goto array_return;
-
- case O_EVALONCE:
- sp = do_eval(st[1], O_EVAL, curcmd->c_stash, TRUE,
- gimme,arglast);
- if (eval_root) {
- str_free(arg[1].arg_ptr.arg_str);
- arg[1].arg_ptr.arg_cmd = eval_root;
- arg[1].arg_type = (A_CMD|A_DONT);
- arg[0].arg_type = O_TRY;
- }
- goto array_return;
-
- case O_REQUIRE:
- case O_DOFILE:
- case O_EVAL:
- if (maxarg < 1)
- tmpstr = stab_val(defstab);
- else
- tmpstr =
- (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
-#ifdef TAINT
- tainted |= tmpstr->str_tainted;
- TAINT_PROPER("eval");
-#endif
- sp = do_eval(tmpstr, optype, curcmd->c_stash, FALSE,
- gimme,arglast);
- goto array_return;
-
- case O_FTRREAD:
- argtype = 0;
- anum = S_IRUSR;
- goto check_perm;
- case O_FTRWRITE:
- argtype = 0;
- anum = S_IWUSR;
- goto check_perm;
- case O_FTREXEC:
- argtype = 0;
- anum = S_IXUSR;
- goto check_perm;
- case O_FTEREAD:
- argtype = 1;
- anum = S_IRUSR;
- goto check_perm;
- case O_FTEWRITE:
- argtype = 1;
- anum = S_IWUSR;
- goto check_perm;
- case O_FTEEXEC:
- argtype = 1;
- anum = S_IXUSR;
- check_perm:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (cando(anum,argtype,&statcache))
- goto say_yes;
- goto say_no;
-
- case O_FTIS:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- goto say_yes;
- case O_FTEOWNED:
- case O_FTROWNED:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
- goto say_yes;
- goto say_no;
- case O_FTZERO:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (!statcache.st_size)
- goto say_yes;
- goto say_no;
- case O_FTSIZE:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- value = (double)statcache.st_size;
- goto donumset;
-
- case O_FTMTIME:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- value = (double)(basetime - statcache.st_mtime) / 86400.0;
- goto donumset;
- case O_FTATIME:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- value = (double)(basetime - statcache.st_atime) / 86400.0;
- goto donumset;
- case O_FTCTIME:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- value = (double)(basetime - statcache.st_ctime) / 86400.0;
- goto donumset;
-
- case O_FTSOCK:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISSOCK(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTCHR:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISCHR(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTBLK:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISBLK(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTFILE:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISREG(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTDIR:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISDIR(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTPIPE:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISFIFO(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_FTLINK:
- if (mylstat(arg,st[1]) < 0)
- goto say_undef;
- if (S_ISLNK(statcache.st_mode))
- goto say_yes;
- goto say_no;
- case O_SYMLINK:
-#ifdef HAS_SYMLINK
- tmps = str_get(st[1]);
- tmps2 = str_get(st[2]);
-#ifdef TAINT
- TAINT_PROPER("symlink");
-#endif
- value = (double)(symlink(tmps,tmps2) >= 0);
- goto donumset;
-#else
- fatal("Unsupported function symlink");
-#endif
- case O_READLINK:
-#ifdef HAS_SYMLINK
- if (maxarg < 1)
- tmps = str_get(stab_val(defstab));
- else
- tmps = str_get(st[1]);
- anum = readlink(tmps,buf,sizeof buf);
- if (anum < 0)
- goto say_undef;
- str_nset(str,buf,anum);
- break;
-#else
- goto say_undef; /* just pretend it's a normal file */
-#endif
- case O_FTSUID:
-#ifdef S_ISUID
- anum = S_ISUID;
- goto check_xid;
-#else
- goto say_no;
-#endif
- case O_FTSGID:
-#ifdef S_ISGID
- anum = S_ISGID;
- goto check_xid;
-#else
- goto say_no;
-#endif
- case O_FTSVTX:
-#ifdef S_ISVTX
- anum = S_ISVTX;
-#else
- goto say_no;
-#endif
- check_xid:
- if (mystat(arg,st[1]) < 0)
- goto say_undef;
- if (statcache.st_mode & anum)
- goto say_yes;
- goto say_no;
- case O_FTTTY:
- if (arg[1].arg_type & A_DONT) {
- stab = arg[1].arg_ptr.arg_stab;
- tmps = "";
- }
- else
- stab = stabent(tmps = str_get(st[1]),FALSE);
- if (stab && stab_io(stab) && stab_io(stab)->ifp)
- anum = fileno(stab_io(stab)->ifp);
- else if (isDIGIT(*tmps))
- anum = atoi(tmps);
- else
- goto say_undef;
- if (isatty(anum))
- goto say_yes;
- goto say_no;
- case O_FTTEXT:
- case O_FTBINARY:
- str = do_fttext(arg,st[1]);
- break;
-#ifdef HAS_SOCKET
- case O_SOCKET:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_socket(stab,arglast);
-#else
- (void)do_socket(stab,arglast);
-#endif
- goto donumset;
- case O_BIND:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_bind(stab,arglast);
-#else
- (void)do_bind(stab,arglast);
-#endif
- goto donumset;
- case O_CONNECT:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_connect(stab,arglast);
-#else
- (void)do_connect(stab,arglast);
-#endif
- goto donumset;
- case O_LISTEN:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_listen(stab,arglast);
-#else
- (void)do_listen(stab,arglast);
-#endif
- goto donumset;
- case O_ACCEPT:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if ((arg[2].arg_type & A_MASK) == A_WORD)
- stab2 = arg[2].arg_ptr.arg_stab;
- else
- stab2 = stabent(str_get(st[2]),TRUE);
- do_accept(str,stab,stab2);
- STABSET(str);
- break;
- case O_GHBYNAME:
- if (maxarg < 1)
- goto say_undef;
- case O_GHBYADDR:
- case O_GHOSTENT:
- sp = do_ghent(optype,
- gimme,arglast);
- goto array_return;
- case O_GNBYNAME:
- if (maxarg < 1)
- goto say_undef;
- case O_GNBYADDR:
- case O_GNETENT:
- sp = do_gnent(optype,
- gimme,arglast);
- goto array_return;
- case O_GPBYNAME:
- if (maxarg < 1)
- goto say_undef;
- case O_GPBYNUMBER:
- case O_GPROTOENT:
- sp = do_gpent(optype,
- gimme,arglast);
- goto array_return;
- case O_GSBYNAME:
- if (maxarg < 1)
- goto say_undef;
- case O_GSBYPORT:
- case O_GSERVENT:
- sp = do_gsent(optype,
- gimme,arglast);
- goto array_return;
- case O_SHOSTENT:
- value = (double) sethostent((int)str_gnum(st[1]));
- goto donumset;
- case O_SNETENT:
- value = (double) setnetent((int)str_gnum(st[1]));
- goto donumset;
- case O_SPROTOENT:
- value = (double) setprotoent((int)str_gnum(st[1]));
- goto donumset;
- case O_SSERVENT:
- value = (double) setservent((int)str_gnum(st[1]));
- goto donumset;
- case O_EHOSTENT:
- value = (double) endhostent();
- goto donumset;
- case O_ENETENT:
- value = (double) endnetent();
- goto donumset;
- case O_EPROTOENT:
- value = (double) endprotoent();
- goto donumset;
- case O_ESERVENT:
- value = (double) endservent();
- goto donumset;
- case O_SOCKPAIR:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if ((arg[2].arg_type & A_MASK) == A_WORD)
- stab2 = arg[2].arg_ptr.arg_stab;
- else
- stab2 = stabent(str_get(st[2]),TRUE);
-#ifndef lint
- value = (double)do_spair(stab,stab2,arglast);
-#else
- (void)do_spair(stab,stab2,arglast);
-#endif
- goto donumset;
- case O_SHUTDOWN:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
-#ifndef lint
- value = (double)do_shutdown(stab,arglast);
-#else
- (void)do_shutdown(stab,arglast);
-#endif
- goto donumset;
- case O_GSOCKOPT:
- case O_SSOCKOPT:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- sp = do_sopt(optype,stab,arglast);
- goto array_return;
- case O_GETSOCKNAME:
- case O_GETPEERNAME:
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab)
- goto say_undef;
- sp = do_getsockname(optype,stab,arglast);
- goto array_return;
-
-#else /* HAS_SOCKET not defined */
- case O_SOCKET:
- case O_BIND:
- case O_CONNECT:
- case O_LISTEN:
- case O_ACCEPT:
- case O_SOCKPAIR:
- case O_GHBYNAME:
- case O_GHBYADDR:
- case O_GHOSTENT:
- case O_GNBYNAME:
- case O_GNBYADDR:
- case O_GNETENT:
- case O_GPBYNAME:
- case O_GPBYNUMBER:
- case O_GPROTOENT:
- case O_GSBYNAME:
- case O_GSBYPORT:
- case O_GSERVENT:
- case O_SHOSTENT:
- case O_SNETENT:
- case O_SPROTOENT:
- case O_SSERVENT:
- case O_EHOSTENT:
- case O_ENETENT:
- case O_EPROTOENT:
- case O_ESERVENT:
- case O_SHUTDOWN:
- case O_GSOCKOPT:
- case O_SSOCKOPT:
- case O_GETSOCKNAME:
- case O_GETPEERNAME:
- badsock:
- fatal("Unsupported socket function");
-#endif /* HAS_SOCKET */
- case O_SSELECT:
-#ifdef HAS_SELECT
- sp = do_select(gimme,arglast);
- goto array_return;
-#else
- fatal("select not implemented");
-#endif
- case O_FILENO:
- if (maxarg < 1)
- goto say_undef;
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
- goto say_undef;
- value = fileno(fp);
- goto donumset;
- case O_BINMODE:
- if (maxarg < 1)
- goto say_undef;
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
- goto say_undef;
-#ifdef DOSISH
-#ifdef atarist
- if(fflush(fp))
- str_set(str, No);
- else
- {
- fp->_flag |= _IOBIN;
- str_set(str, Yes);
- }
-#else
- str_set(str, (setmode(fileno(fp), O_BINARY) != -1) ? Yes : No);
-#endif
-#else
- str_set(str, Yes);
-#endif
- STABSET(str);
- break;
- case O_VEC:
- sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
- goto array_return;
- case O_GPWNAM:
- case O_GPWUID:
- case O_GPWENT:
-#ifdef HAS_PASSWD
- sp = do_gpwent(optype,
- gimme,arglast);
- goto array_return;
- case O_SPWENT:
- value = (double) setpwent();
- goto donumset;
- case O_EPWENT:
- value = (double) endpwent();
- goto donumset;
-#else
- case O_EPWENT:
- case O_SPWENT:
- fatal("Unsupported password function");
- break;
-#endif
- case O_GGRNAM:
- case O_GGRGID:
- case O_GGRENT:
-#ifdef HAS_GROUP
- sp = do_ggrent(optype,
- gimme,arglast);
- goto array_return;
- case O_SGRENT:
- value = (double) setgrent();
- goto donumset;
- case O_EGRENT:
- value = (double) endgrent();
- goto donumset;
-#else
- case O_EGRENT:
- case O_SGRENT:
- fatal("Unsupported group function");
- break;
-#endif
- case O_GETLOGIN:
-#ifdef HAS_GETLOGIN
- if (!(tmps = getlogin()))
- goto say_undef;
- str_set(str,tmps);
-#else
- fatal("Unsupported function getlogin");
-#endif
- break;
- case O_OPEN_DIR:
- case O_READDIR:
- case O_TELLDIR:
- case O_SEEKDIR:
- case O_REWINDDIR:
- case O_CLOSEDIR:
- if (maxarg < 1)
- goto say_undef;
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if (!stab)
- goto say_undef;
- sp = do_dirop(optype,stab,gimme,arglast);
- goto array_return;
- case O_SYSCALL:
- value = (double)do_syscall(arglast);
- goto donumset;
- case O_PIPE_OP:
-#ifdef HAS_PIPE
- if ((arg[1].arg_type & A_MASK) == A_WORD)
- stab = arg[1].arg_ptr.arg_stab;
- else
- stab = stabent(str_get(st[1]),TRUE);
- if ((arg[2].arg_type & A_MASK) == A_WORD)
- stab2 = arg[2].arg_ptr.arg_stab;
- else
- stab2 = stabent(str_get(st[2]),TRUE);
- do_pipe(str,stab,stab2);
- STABSET(str);
-#else
- fatal("Unsupported function pipe");
-#endif
- break;
- }
-
- normal_return:
- st[1] = str;
-#ifdef DEBUGGING
- if (debug) {
- dlevel--;
- if (debug & 8)
- deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
- }
-#endif
- stack_ary = stack->ary_array;
- stack_max = stack_ary + stack->ary_max;
- stack_sp = stack_ary + arglast[0] + 1;
- return arglast[0] + 1;
-}