perl 3.0 patch #8 patch 7 continued
[p5sagit/p5-mst-13.2.git] / eval.c
diff --git a/eval.c b/eval.c
index 32da854..95870b1 100644 (file)
--- a/eval.c
+++ b/eval.c
@@ -1,4 +1,4 @@
-/* $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
  *
@@ -6,6 +6,20 @@
  *    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)();
@@ -42,9 +53,6 @@ double sin(), cos(), atan2(), pow();
 
 char *getlogin();
 
-extern int sys_nerr;
-extern char *sys_errlist[];
-
 int
 eval(arg,gimme,sp)
 register ARG *arg;
@@ -169,7 +177,6 @@ register int sp;
        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 {
@@ -553,8 +560,8 @@ register int sp;
            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;
@@ -955,7 +962,13 @@ register int sp;
        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);
@@ -1190,10 +1203,10 @@ register int sp;
        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:
@@ -1449,29 +1462,59 @@ register int sp;
 #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));
@@ -1484,7 +1527,7 @@ register int sp;
        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:
@@ -1705,7 +1748,7 @@ register int sp;
        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 )
@@ -1968,6 +2011,8 @@ register int sp;
        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
@@ -2014,6 +2059,8 @@ register int sp;
     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