-/* $Header: eval.c,v 3.0 89/10/18 15:17:04 lwall Locked $
+/* $Header: eval.c,v 3.0.1.3 89/12/21 20:03:05 lwall Locked $
*
* Copyright (c) 1989, Larry Wall
*
* as specified in the README file that comes with the perl 3.0 kit.
*
* $Log: eval.c,v $
+ * Revision 3.0.1.3 89/12/21 20:03:05 lwall
+ * patch7: errno may now be a macro with an lvalue
+ * patch7: ANSI strerror() is now supported
+ * patch7: send() didn't allow a TO argument
+ * patch7: ord() now always returns positive even on signed char machines
+ *
+ * Revision 3.0.1.2 89/11/17 15:19:34 lwall
+ * patch5: constant numeric subscripts get lost inside ?:
+ *
+ * Revision 3.0.1.1 89/11/11 04:31:51 lwall
+ * patch2: mkdir and rmdir needed to quote argument when passed to shell
+ * patch2: mkdir and rmdir now return better error codes
+ * patch2: fileno, seekdir, rewinddir and closedir now disallow defaults
+ *
* Revision 3.0 89/10/18 15:17:04 lwall
* 3.0 baseline
*
#include "perl.h"
#include <signal.h>
-#include <errno.h>
#ifdef I_VFORK
# include <vfork.h>
#endif
-extern int errno;
-
#ifdef VOIDSIG
static void (*ihand)();
static void (*qhand)();
char *getlogin();
-extern int sys_nerr;
-extern char *sys_errlist[];
-
int
eval(arg,gimme,sp)
register ARG *arg;
if (arg[1].arg_flags & AF_ARYOK) {
if (arg->arg_len == 1) {
arg->arg_type = O_LOCAL;
- arg->arg_flags |= AF_LOCAL;
goto local;
}
else {
str = afetch(ary,maxarg - 1,FALSE);
break;
case O_AELEM:
- str = afetch(stab_array(arg[1].arg_ptr.arg_stab),
- ((int)str_gnum(st[2])) - arybase,FALSE);
+ anum = ((int)str_gnum(st[2])) - arybase;
+ str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
if (!str)
goto say_undef;
break;
errno = 0;
if (optype > 4)
warn("Too many args on send");
- if (optype >= 4) {
+ stio = stab_io(stab);
+ if (!stio || !stio->ifp) {
+ anum = -1;
+ if (dowarn)
+ warn("Send on closed socket");
+ }
+ else if (optype >= 4) {
tmps2 = str_get(st[4]);
anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
anum, tmps2, st[4]->str_cur);
else
tmps = str_get(st[1]);
#ifndef I286
- value = (double) *tmps;
+ value = (double) (*tmps & 255);
#else
anum = (int) *tmps;
- value = (double) anum;
+ value = (double) (anum & 255);
#endif
goto donumset;
case O_SLEEP:
#endif
#ifdef MKDIR
value = (double)(mkdir(tmps,anum) >= 0);
+ goto donumset;
#else
- (void)sprintf(buf,"mkdir %s 2>&1",tmps);
+ (void)strcpy(buf,"mkdir ");
+#endif
+#if !defined(MKDIR) || !defined(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++) {
+ 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,"non-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
- value = 1.0;
+ 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
- goto donumset;
case O_RMDIR:
if (maxarg < 1)
tmps = str_get(stab_val(defstab));
value = (double)(rmdir(tmps) >= 0);
goto donumset;
#else
- (void)sprintf(buf,"rmdir %s 2>&1",tmps);
+ (void)strcpy(buf,"rmdir ");
goto one_liner; /* see above in MKDIR */
#endif
case O_GETPPID:
goto say_no;
#endif
case O_FTLINK:
-#ifdef SYMLINK
+#ifdef LSTAT
if (lstat(str_get(st[1]),&statcache) < 0)
goto say_undef;
if ((statcache.st_mode & S_IFMT) == S_IFLNK )
fatal("Unsupported socket function");
#endif /* SOCKET */
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
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