perl 3.0 patch #22 patch #19, continued
[p5sagit/p5-mst-13.2.git] / perly.c
diff --git a/perly.c b/perly.c
index 645ac3d..ad0075f 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -1,4 +1,4 @@
-char rcsid[] = "$Header: perly.c,v 3.0.1.1 89/11/11 04:50:04 lwall Locked $\nPatch level: ###\n";
+char rcsid[] = "$Header: perly.c,v 3.0.1.5 90/03/27 16:20:57 lwall Locked $\nPatch level: ###\n";
 /*
  *    Copyright (c) 1989, Larry Wall
  *
@@ -6,6 +6,23 @@ char rcsid[] = "$Header: perly.c,v 3.0.1.1 89/11/11 04:50:04 lwall Locked $\nPat
  *    as specified in the README file that comes with the perl 3.0 kit.
  *
  * $Log:       perly.c,v $
+ * Revision 3.0.1.5  90/03/27  16:20:57  lwall
+ * patch16: MSDOS support
+ * patch16: do FILE inside eval blows up
+ * 
+ * Revision 3.0.1.4  90/02/28  18:06:41  lwall
+ * patch9: perl can now start up other interpreters scripts
+ * patch9: nested evals clobbered their longjmp environment
+ * patch9: eval could mistakenly return undef in array context
+ * 
+ * Revision 3.0.1.3  89/12/21  20:15:41  lwall
+ * patch7: ANSI strerror() is now supported
+ * patch7: errno may now be a macro with an lvalue
+ * patch7: allowed setuid scripts to have a space after #!
+ * 
+ * Revision 3.0.1.2  89/11/17  15:34:42  lwall
+ * patch5: fixed possible confusion about current effective gid
+ * 
  * Revision 3.0.1.1  89/11/11  04:50:04  lwall
  * patch2: moved yydebug to where its type didn't matter
  * 
@@ -40,7 +57,6 @@ register char **env;
     register char *s;
     char *index(), *strcpy(), *getenv();
     bool dosearch = FALSE;
-    char **origargv = argv;
 #ifdef DOSUID
     char *validarg = "";
 #endif
@@ -53,13 +69,24 @@ setuid perl scripts securely.\n");
 #endif
 #endif
 
+    origargv = argv;
+    origargc = argc;
     uid = (int)getuid();
     euid = (int)geteuid();
     gid = (int)getgid();
     egid = (int)getegid();
+#ifdef MSDOS
+    /*
+     * There is no way we can refer to them from Perl so close them to save
+     * space.  The other alternative would be to provide STDAUX and STDPRN
+     * filehandles.
+     */
+    (void)fclose(stdaux);
+    (void)fclose(stdprn);
+#endif
     if (do_undump) {
        do_undump = 0;
-       loop_ptr = 0;           /* start label stack again */
+       loop_ptr = -1;          /* start label stack again */
        goto just_doit;
     }
     (void)sprintf(index(rcsid,'#'), "%d\n", PATCHLEVEL);
@@ -181,7 +208,12 @@ setuid perl scripts securely.\n");
            goto reswitch;
        case 'v':
            fputs(rcsid,stdout);
-           fputs("\nCopyright (c) 1989, Larry Wall\n\n\
+           fputs("\nCopyright (c) 1989, 1990, Larry Wall\n",stdout);
+#ifdef MSDOS
+           fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
+           stdout);
+#endif
+           fputs("\n\
 Perl may be copied only under the terms of the GNU General Public License,\n\
 a copy of which can be found with the Perl 3.0 distribution kit.\n",stdout);
            exit(0);
@@ -289,9 +321,6 @@ a copy of which can be found with the Perl 3.0 distribution kit.\n",stdout);
     else
        rsfp = fopen(argv[0],"r");
     if (rsfp == Nullfp) {
-       extern char *sys_errlist[];
-       extern int errno;
-
 #ifdef DOSUID
 #ifndef IAMSUID                /* in case script is not readable before setuid */
        if (euid && stat(filename,&statbuf) >= 0 &&
@@ -303,7 +332,7 @@ a copy of which can be found with the Perl 3.0 distribution kit.\n",stdout);
 #endif
 #endif
        fatal("Can't open perl script \"%s\": %s\n",
-         filename, sys_errlist[errno]);
+         filename, strerror(errno));
     }
     str_free(str);             /* free -I directories */
 
@@ -395,7 +424,9 @@ a copy of which can be found with the Perl 3.0 distribution kit.\n",stdout);
        if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
          strnNE(tokenbuf,"#!",2) )     /* required even on Sys V */
            fatal("No #! line");
-       for (s = tokenbuf+2; !isspace(*s); s++) ;
+       s = tokenbuf+2;
+       if (*s == ' ') s++;
+       while (!isspace(*s)) s++;
        if (strnNE(s-4,"perl",4))       /* sanity check */
            fatal("Not a perl script");
        while (*s == ' ' || *s == '\t') s++;
@@ -426,7 +457,7 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
            fatal("Can't do setuid\n");
        }
 
-       if (statbuf.st_mode & S_ISGID && statbuf.st_gid != getegid())
+       if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid)
 #ifdef SETEGID
            (void)setegid(statbuf.st_gid);
 #else
@@ -458,7 +489,10 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
            setuid((UIDTYPE)uid);
 #endif
 #endif
+       uid = (int)getuid();
        euid = (int)geteuid();
+       gid = (int)getgid();
+       egid = (int)getegid();
        if (!cando(S_IEXEC,TRUE,&statbuf))
            fatal("Permission denied\n");       /* they can't do this */
     }
@@ -660,7 +694,7 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
        str_numset(STAB_STR(tmpstab),(double)getpid());
 
     if (setjmp(top_env))       /* sets goto_targ on longjump */
-       loop_ptr = 0;           /* start label stack again */
+       loop_ptr = -1;          /* start label stack again */
 
 #ifdef DEBUGGING
     if (debug & 1024)
@@ -709,14 +743,15 @@ int *arglast;
     CMD *myroot;
     ARRAY *ar;
     int i;
-    char *oldfile = filename;
-    line_t oldline = line;
-    int oldtmps_base = tmps_base;
-    int oldsave = savestack->ary_fill;
-    SPAT *oldspat = curspat;
+    char * VOLATILE oldfile = filename;
+    VOLATILE line_t oldline = line;
+    VOLATILE int oldtmps_base = tmps_base;
+    VOLATILE int oldsave = savestack->ary_fill;
+    SPAT * VOLATILE oldspat = curspat;
     static char *last_eval = Nullch;
     static CMD *last_root = Nullcmd;
-    int sp = arglast[0];
+    VOLATILE int sp = arglast[0];
+    char *tmps;
 
     tmps_base = tmps_max;
     if (curstash != stash) {
@@ -731,7 +766,7 @@ int *arglast;
        str_cat(linestr,";");           /* be kind to them */
     }
     else {
-       if (last_root) {
+       if (last_root && !in_eval) {
            Safefree(last_eval);
            cmd_free(last_root);
            last_root = Nullcmd;
@@ -762,7 +797,18 @@ int *arglast;
     in_eval++;
     oldoldbufptr = oldbufptr = bufptr = str_get(linestr);
     bufend = bufptr + linestr->str_cur;
-    if (setjmp(eval_env)) {
+    if (++loop_ptr >= loop_max) {
+       loop_max += 128;
+       Renew(loop_stack, loop_max, struct loop);
+    }
+    loop_stack[loop_ptr].loop_label = "_EVAL_";
+    loop_stack[loop_ptr].loop_sp = sp;
+#ifdef DEBUGGING
+    if (debug & 4) {
+       deb("(Pushing label #%d _EVAL_)\n", loop_ptr);
+    }
+#endif
+    if (setjmp(loop_stack[loop_ptr].loop_env)) {
        retval = 1;
        last_root = Nullcmd;
     }
@@ -790,7 +836,10 @@ int *arglast;
     }
     myroot = eval_root;                /* in case cmd_exec does another eval! */
     if (retval || error_count) {
-       str = &str_undef;
+       st = stack->ary_array;
+       sp = arglast[0];
+       if (gimme != G_ARRAY)
+           st[++sp] = &str_undef;
        last_root = Nullcmd;    /* can't free on error, for some reason */
        if (rsfp) {
            fclose(rsfp);
@@ -807,6 +856,14 @@ int *arglast;
            cmd_free(myroot);
     }
     in_eval--;
+#ifdef DEBUGGING
+       if (debug & 4) {
+           tmps = loop_stack[loop_ptr].loop_label;
+           deb("(Popping label #%d %s)\n",loop_ptr,
+               tmps ? tmps : "" );
+       }
+#endif
+    loop_ptr--;
     filename = oldfile;
     line = oldline;
     tmps_base = oldtmps_base;