[comp.sources.bugs] Patches to some Perl 3.0 bugs

guy@auspex.auspex.com (Guy Harris) (09/09/89)

Unofficial patches (which I'll forward to Larry Wall) for some problems:

1) a little problem "lint" caught in "cons.c".  "lint" is your friend.

*** cons.c.dist	Fri Sep  8 17:35:38 1989
--- cons.c	Fri Sep  8 18:46:26 1989
***************
*** 173,179 ****
      Newz(103,loc,258,CMD*);
      loc++;				/* lie a little */
      while (count--) {
! 	if ((cur->c_flags && CF_OPTIMIZE) == CFT_CCLASS) {
  	    for (i = 0; i <= 255; i++) {
  		if (!loc[i] && cur->c_short->str_ptr[i>>3] & (1 << (i&7))) {
  		    loc[i] = cur;
--- 173,179 ----
      Newz(103,loc,258,CMD*);
      loc++;				/* lie a little */
      while (count--) {
! 	if ((cur->c_flags & CF_OPTIMIZE) == CFT_CCLASS) {
  	    for (i = 0; i <= 255; i++) {
  		if (!loc[i] && cur->c_short->str_ptr[i>>3] & (1 << (i&7))) {
  		    loc[i] = cur;

2) One "#ifdef SYMLINK"/"#endif" was missed in "doio.c", causing Perl
   not to build on machines without "lstat".

*** doio.c.dist	Fri Sep  8 17:35:38 1989
--- doio.c	Fri Sep  8 18:47:26 1989
***************
*** 457,465 ****
--- 457,467 ----
      else {
  	str_sset(statname,ary->ary_array[sp]);
  	statstab = Nullstab;
+ #ifdef SYMLINK
  	if (arg->arg_type == O_LSTAT)
  	    i = lstat(str_get(statname),&statcache);
  	else
+ #endif
  	    i = stat(str_get(statname),&statcache);
  	if (i < 0)
  	    max = 0;

3) The "lstat()" function for which the "lstat"s were stuck in there in
   the first place seemed not to be recognized by the lexical analyzer. 
   (It also appears not to have been documented, but then again the
   BSD socket functions in Perl don't seem to be documented, either....)

*** toke.c.dist	Fri Sep  8 17:35:43 1989
--- toke.c	Fri Sep  8 18:49:16 1989
***************
*** 635,640 ****
--- 635,642 ----
  	    FUN2(O_LINK);
  	if (strEQ(d,"listen"))
  	    FOP2(O_LISTEN);
+ 	if (strEQ(d,"lstat"))
+ 	    FOP(O_LSTAT);
  	break;
      case 'm': case 'M':
  	SNARFWORD;

4) "vfork" interacts unpleasantly with register windows on SPARC
   machines.

5) "mypopen" required that the system have "dup2()"; some versions of
   UNIX do not but do have "fcntl" (S3, S5"R1", S5R2 - S5R3 has both).

*** eval.c.dist	Fri Sep  8 17:35:39 1989
--- eval.c	Fri Sep  8 17:51:15 1989
***************
*** 14,19 ****
--- 14,23 ----
  #include <signal.h>
  #include <errno.h>
  
+ #ifdef sparc
+ #  include <vfork.h>
+ #endif
+ 
  extern int errno;
  
  #ifdef VOIDSIG

*** util.c.dist	Fri Sep  8 17:35:44 1989
--- util.c	Fri Sep  8 19:02:10 1989
***************
*** 12,17 ****
--- 12,30 ----
  #include "perl.h"
  #include "errno.h"
  
+ #ifdef sparc
+ /*
+  * XXX - should be "#include <vfork.h>"; however, that doesn't seem
+  * to be sufficient to fix the problem, so we just #define "vfork"
+  * to be "fork"....
+  */
+ #define	vfork	fork
+ #endif
+ 
+ #ifdef FCNTL
+ #  include <fcntl.h>
+ #endif
+ 
  #ifdef VARARGS
  #  include <varargs.h>
  #endif
***************
*** 1001,1008 ****
  	this = !this;	/* swap this and that */
  	that = !this;
  	close(p[that]);
! 	if (p[this] != (*mode == 'r')) {
! 	    dup2(p[this], *mode == 'r');
  	    close(p[this]);
  	}
  	if (doexec) {
--- 1014,1026 ----
  	this = !this;	/* swap this and that */
  	that = !this;
  	close(p[that]);
! 	if (p[this] != this) {
! #ifdef FCNTL
! 	    close(this);
! 	    fcntl(p[this], F_DUPFD, this);
! #else
! 	    dup2(p[this], this);
! #endif
  	    close(p[this]);
  	}
  	if (doexec) {

tytso@athena.mit.edu (Theodore Y. Ts'o) (09/09/89)

Here are a few more unofficial patchs to Perl 3.0.  I've forwarded them
to Larry Wall already, but I haven't gotten an ack yet.  (There may be
some mailer problems; I'm not sure.)

With these patches, I've managed to Perl 3.0 beta on a Dec PMAX (a Mips
machine with Vax byte order) which passes all the regression tests but
op.sort.  One of the problems is that it is extremely picky on alignment
restrictions, and Perl seems to fall into a few of them.  For example, I
had to use the system malloc, instead of the perl supplied malloc.

Has anyone else tried getting it work on a PMAX, or some other MIPS
machine?

1)  There was a fencepost error in the realloc'ing of arg; since our
system malloc was a linear allocator, this particular bug caused a lot
of trouble, since malloc control blocks were getting stomped on.....

RCS file: RCS/consarg.c,v
retrieving revision 1.1
diff -c -r1.1 consarg.c
*** /tmp/,RCSt1000501   Sat Sep  9 00:07:39 1989
--- consarg.c   Mon Sep  4 16:52:50 1989
***************
*** 33,39 ****
        spat->spat_runtime = arg;
        arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
      }
!     Renew(arg,3,ARG);
      arg->arg_len = 3;
      if (limarg) {
        if (limarg->arg_type == O_ITEM) {
--- 33,39 ----
        spat->spat_runtime = arg;
        arg = make_match(O_MATCH,stab2arg(A_STAB,defstab),spat);
      }
!     Renew(arg,4,ARG);
      arg->arg_len = 3;
      if (limarg) {
        if (limarg->arg_type == O_ITEM) {

2)  At least in BSD 4.3, the array returned by getgroups() is NOT gid_t;
it is definied in the man page to be an array of ints.  Since gid_t is
defined as a short, if you belong to more than NGROUP/2 groups your
stack frame gets stomped on.  I'm not sure how portable this fix is.....
can someone check this one, to see how other systems (in particular the
Posix standard) handle getgroups()?  In the meantime, the following
patch will work for BSD systems. 

RCS file: RCS/doio.c,v
retrieving revision 1.1
diff -c -r1.1 doio.c
*** /tmp/,RCSt1000507   Sat Sep  9 00:08:54 1989
--- doio.c      Sun Sep  3 23:25:08 1989
***************
*** 1537,1543 ****
  #define NGROUPS 32
  #endif
      {
!       GIDTYPE gary[NGROUPS];
        int anum;

        anum = getgroups(NGROUPS,gary);
--- 1537,1543 ----
  #define NGROUPS 32
  #endif
      {
!       int gary[NGROUPS];
        int anum;

        anum = getgroups(NGROUPS,gary);

3) This fixes a problem where if s is a zero-length string, the index call
succeeds (since there is a null at the end of "Ee") and the reference to
s[1] oversteps the array bounds.  There a possibility of a similar
confusion happening just above this section code, again involving an
index() call, but I'm not sure whether it absolutely needs changing or
not, so I left it alone.  Overstepping an array bounds like will
probably very rarely cause a core dump, unless you get very unlucky, on
some wierd system/malloc(), but it's good to fix it in the interest of
cleanliness.  

RCS file: RCS/toke.c,v
retrieving revision 1.1
diff -c -r1.1 toke.c
*** /tmp/,RCSt1000515   Sat Sep  9 00:13:07 1989
--- toke.c      Mon Sep  4 14:53:56 1989
***************
*** 1506,1512 ****
                    *d++ = *s++;
            }
        }
!       if (index("eE",*s) && index("+-0123456789",s[1])) {
            *d++ = *s++;
            if (*s == '+' || *s == '-')
                *d++ = *s++;
--- 1506,1512 ----
                    *d++ = *s++;
            }
        }
!       if (*s && index("eE",*s) && index("+-0123456789",s[1])) {
            *d++ = *s++;
            if (*s == '+' || *s == '-')
                *d++ = *s++;

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Theodore Ts'o				bloom-beacon!mit-athena!tytso
3 Ames St., Cambridge, MA 02139		tytso@athena.mit.edu
   Everybody's playing the game, but nobody's rules are the same!