🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.utils.bug
Article #478

Make 3.56: Xenix patches and bug fixes

#478
From: Chip Salzenberg
Date: Mon, 09 Oct 1989 14:02
803 lines
20595 bytes
Patches to GNU Make 3.56.  I really hope that these will be adopted into
the official GNU Make release, since there are a _lot_ of Xenix users out
there, and I'm tired of porting each Make version.  (:-))

Features:
    Port to SCO Xenix/386.
    Create new "dir.h" header, used for opendir() readdir() etc.
    Use Doug Gwyn's getcwd() replacement.  It's faster, and unlike
	the Xenix one, it doesn't break when SIGCLD is being caught.
    Support a command prefix (default: "\t" unless "-n" flag specified).
	Prefix is printed before each command.
    Pass all variables in the child environment only if VARS_IN_ENV is
	defined.  (Otherwise large variables overwhelm the environment.)
	Perhaps the default should be the current behavior; that's a
	small change.

Bug fixes:
    Fix core dump bug when NO_ARCHIVES is defined --
	$@ was being defined to an uninitialized pointer.
    Fix handling of multiple job slots --
	but it's still not completely right.
    Fix creation of MFLAGS and MAKEFLAGS in presence of multiple job slots --
	the presence of "-j" lopped off the rest of the flags.
    Change update_status to a short, since many compilers don't support
	signed bitfields.
    Line buffer standard output, so output of multiple makes processes
	interleave correctly.
    Fix core dump bug when numeric option has the value omitted.

# This file contains patches for GNU Make 3.56.
# (Be sure to use the "-p" option of patch.)
# Patches are enclosed for the following file(s):
#	commands.c
#	dir.c
#	dir.h
#	file.c
#	file.h
#	function.c
#	glob.c
#	job.c
#	main.c
#	make.h
#	remake.c
#	variable.c

Index: commands.c
***************
*** 120,124 ****
    /* If the target is an archive member `lib(member)',
       then $@ is `lib' and $% is `member'.  */
- 
    if (ar_name (file->name))
      {
--- 120,123 ----
***************
*** 129,132 ****
--- 128,132 ----
      }
    else
+ #endif
      {
        at = savestring (file->name, strlen (file->name));
***************
*** 133,137 ****
        percent = "";
      }
- #endif
  
    DEFINE_VARIABLE ("@", 1, at);
--- 133,136 ----
***************
*** 335,353 ****
      }
  
-   /* First set the automatic variables according to this file.  */
- 
-   initialize_file_variables (file);
- 
-   set_file_variables (file);
- 
    /* Chop the commands up into lines.  */
    if (cmds->command_lines == 0)
      chop_commands (cmds);
  
    if (job_slots > 0)
!     /* Wait for a job slot to be freed up.  */
!     while (job_slots_used == job_slots)
!       wait_for_children (1, 0);
  
    /* Start the command sequence, record it in a new
       `struct child', and add that to the chain.  */
--- 334,355 ----
      }
  
    /* Chop the commands up into lines.  */
+ 
    if (cmds->command_lines == 0)
      chop_commands (cmds);
  
+   /* Wait for a job slot to be freed up.  */
+ 
    if (job_slots > 0)
!     {
!       while (job_slots_used == job_slots)
! 	wait_for_children (1, 0);
!     }
  
+   /* Set the automatic variables according to this file.  */
+ 
+   initialize_file_variables (file);
+   set_file_variables (file);
+ 
    /* Start the command sequence, record it in a new
       `struct child', and add that to the chain.  */
***************
*** 370,383 ****
      }
  
!   unblock_children ();
! 
!   if (status)
      {
        free (c->commands);
        free ((char *) c);
- 
        file->update_status = (just_print_flag || touch_flag) ? 0 : 1;
      }
!   else if (job_slots == 1)
      {
        /* Since there is only one job slot, make things run linearly.
--- 372,387 ----
      }
  
!   if (status == 0)
!     file->update_status = 0;
!   else
      {
        free (c->commands);
        free ((char *) c);
        file->update_status = (just_print_flag || touch_flag) ? 0 : 1;
      }
! 
!   unblock_children ();
! 
!   if (status == 0 && job_slots == 1)
      {
        /* Since there is only one job slot, make things run linearly.
***************
*** 385,390 ****
        while (file->command_state != cs_finished)
  	wait_for_children (1, 0);
- 
      }
    notice_finished_file (file);
  }
--- 389,394 ----
        while (file->command_state != cs_finished)
  	wait_for_children (1, 0);
      }
+ 
    notice_finished_file (file);
  }

Index: dir.c
***************
*** 18,43 ****
  
  #include "make.h"
  
- #if	defined(USGr3) || defined(DIRENT)
- 
- #include <dirent.h>
- #	if	!defined(d_ino) && !defined(d_fileno)
- #define	d_ino	d_fileno
- #	endif
- #define direct dirent
- #define	D_NAMLEN(d) strlen((d)->d_name)
- 
- #else	/* Not USGr3 and not DIRENT.  */
- 
- #define D_NAMLEN(d) ((d)->d_namlen)
- #	ifdef	USG
- #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
- #	else	/* Not USG.  */
- #include <sys/dir.h>
- #	endif	/* USG.  */
- 
- #endif	/* USGr3 or DIRENT.  */
- 
- 
  /* Hash table of directories.  */
  
--- 18,24 ----
  
  #include "make.h"
+ #include "dir.h"
+ #include <errno.h>
  
  /* Hash table of directories.  */
  
***************
*** 385,386 ****
--- 366,556 ----
    printf (" impossibilities in %u directories.\n", dirs);
  }
+ 
+ /*
+     getcurdir -- get current working directory name
+ 		 (compatible with POSIX and SVID getcwd())
+   
+     last edit:      21-Sep-1987     D A Gwyn
+   
+     This public-domain getcurdir() routine can be used to replace the UNIX
+     System V library routine (which uses popen() to capture the output of
+     the "pwd" command).  Once that is done, "pwd" can be reimplemented as
+     just puts(getcurdir()).
+   
+     This implementation depends on every directory having entries for
+     "." and "..".  It also depends on the internals of the readdir()
+     data structures to some degree.
+   
+     I considered using chdir() to ascend the hierarchy, followed by a
+     final chdir() to the path being returned by getcurdir() to restore the
+     location, but decided that error recovery was too difficult that way.
+     The algorithm I settled on was inspired by my rewrite of the "pwd"
+     utility, combined with the dotdots[] array trick from the SVR2 shell.
+ */
+ 
+ char   *
+ getcurdir(buf, size)			/* returns pointer to CWD pathname */
+ char   *buf;				/* where to put name (NULL to malloc) */
+ int     size;				/* size of buf[] or malloc()ed memory */
+ {
+   static char dotdots[] =
+   "../../../../../../../../../../../../../../../../../../../../../../../../../..";
+   char   *dotdot;			/* -> dotdots[.], right to left */
+   DIR    *dirp;				/* -> parent directory stream */
+   struct direct *dir;			/* -> directory entry */
+   struct stat stat1,
+           stat2;			/* info from stat() */
+   struct stat *d = &stat1;		/* -> info about "." */
+   struct stat *dd = &stat2;		/* -> info about ".." */
+   register char *buffer;		/* local copy of buf, or malloc()ed */
+   char   *bufend;			/* -> buffer[size] */
+   register char *endp;			/* -> end of reversed string */
+   register char *dname;			/* entry name ("" for root) */
+   int     serrno = errno;		/* save entry errno */
+ 
+   if (size == 0)
+   {
+     errno = EINVAL;			/* invalid argument */
+     return NULL;
+   }
+ 
+   if ((buffer = buf) == NULL		/* wants us to malloc() the string */
+       && (buffer = (char *) malloc((unsigned) size)) == NULL)
+   {
+     errno = ENOMEM;			/* cannot malloc() specified size */
+     return NULL;
+   }
+ 
+   if (stat(".", dd) != 0)		/* prime the pump */
+     goto error;				/* errno already set */
+ 
+   endp = buffer;			/* initially, empty string */
+   bufend = &buffer[size];
+ 
+   for (dotdot = &dotdots[sizeof(dotdots)]; dotdot != dotdots;)
+   {
+     /* include one more "/.." section */
+     /* (first time is actually "..") */
+     dotdot -= 3;
+ 
+     /* swap stat() info buffers */
+     {
+       register struct stat *temp = d;
+ 
+       d = dd;				/* new current dir is old parent dir */
+       dd = temp;
+     }
+ 
+     if ((dirp = opendir(dotdot)) == NULL)	/* new parent */
+       goto error;			/* errno already set */
+ 
+     if (fstat(dirp->dd_fd, dd) != 0)
+     {
+       serrno = errno;			/* set by fstat() */
+       (void) closedir(dirp);
+       errno = serrno;			/* in case closedir() clobbered it */
+       goto error;
+     }
+ 
+     if (d->st_dev == dd->st_dev)
+     {
+       /* not crossing a mount point */
+ 
+       if (d->st_ino == dd->st_ino)
+       {
+ 	/* root directory */
+ 	dname = "";
+ 	goto append;
+       }
+ 
+       do
+       {
+ 	if ((dir = readdir(dirp)) == NULL)
+ 	{
+ 	  (void) closedir(dirp);
+ 	  errno = ENOENT;		/* missing entry */
+ 	  goto error;
+ 	}
+       } while (dir->d_ino != d->st_ino);
+     }
+     else
+     {					/* crossing a mount point */
+       struct stat t;			/* info re. test entry */
+       char    name[sizeof(dotdots) + 1 + MAXNAMLEN];
+ 
+       (void) strcpy(name, dotdot);
+       dname = &name[strlen(name)];
+       *dname++ = '/';
+ 
+       do
+       {
+ 	if ((dir = readdir(dirp)) == NULL)
+ 	{
+ 	  (void) closedir(dirp);
+ 	  errno = ENOENT;		/* missing entry */
+ 	  goto error;
+ 	}
+ 
+ 	(void) strcpy(dname, dir->d_name);
+ 	/* must fit if MAXNAMLEN is not a lie */
+       } while (stat(name, &t) != 0
+ 	       || t.st_ino != d->st_ino
+ 	       || t.st_dev != d->st_dev);
+     }
+ 
+     dname = dir->d_name;
+ 
+     /* append "/" and reversed dname string onto buffer */
+ append:
+     if (endp != buffer			/* avoid trailing / in final name */
+ 	|| dname[0] == '\0'		/* but allow "/" when CWD is root */
+ 	    )
+       *endp++ = '/';
+ 
+     {
+       register char *app;		/* traverses dname string */
+ 
+       for (app = dname; *app != '\0'; ++app)
+ 	;
+ 
+       if (app - dname >= bufend - endp)
+       {
+ 	(void) closedir(dirp);
+ 	errno = ERANGE;			/* won't fit allotted space */
+ 	goto error;
+       }
+ 
+       while (app != dname)
+ 	*endp++ = *--app;
+     }
+ 
+     (void) closedir(dirp);
+ 
+     if (dname[0] == '\0')
+     {					/* reached root; wrap it up */
+       register char *startp;		/* -> buffer[.] */
+ 
+       *endp = '\0';			/* plant null terminator */
+ 
+       /* straighten out reversed pathname string */
+       for (startp = buffer; --endp > startp; ++startp)
+       {
+ 	char    temp = *endp;
+ 
+ 	*endp = *startp;
+ 	*startp = temp;
+       }
+ 
+       errno = serrno;			/* restore entry errno */
+       return buffer;
+     }
+   }
+ 
+   errno = ENOMEM;			/* actually, algorithm failure */
+ 
+ error:
+   if (buf == NULL)
+     free((char *) buffer);
+ 
+   return NULL;
+ }

Index: dir.h
***************
*** 1,0 ****
--- 1,45 ----
+ /* Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+ This file is part of GNU Make.
+ 
+ GNU Make is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+ 
+ GNU Make is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GNU Make; see the file COPYING.  If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ #if     defined(M_XENIX)
+ 
+ #include <sys/ndir.h>
+ #define D_NAMLEN(d) ((d)->d_namlen)
+ 
+ #else   /* Not Xenix */
+ 
+ #if	defined(USGr3) || defined(DIRENT)
+ 
+ #include <dirent.h>
+ #	if	!defined(d_ino) && !defined(d_fileno)
+ #define	d_ino	d_fileno
+ #	endif
+ #define direct dirent
+ #define	D_NAMLEN(d) strlen((d)->d_name)
+ 
+ #else   /* Not Xenix, not USGr3 and not DIRENT.  */
+ 
+ #define D_NAMLEN(d) ((d)->d_namlen)
+ #	ifdef	USG
+ #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
+ #	else	/* Not USG.  */
+ #include <sys/dir.h>
+ #	endif	/* USG.  */
+ 
+ #endif	/* USGr3 or DIRENT.  */
+ 
+ #endif  /* Xenix */

Index: file.c
***************
*** 225,228 ****
--- 225,229 ----
  	      else if (!silent_flag && !just_print_flag)
  		{
+ 		  fputs (command_prefix, stdout);
  		  if (!doneany)
  		    {

Index: file.h
***************
*** 51,55 ****
        } command_state ENUM_BITFIELD (2);
  
!     int update_status:2;	/* Status of the last attempt to update,
  				   or -1 if none has been made.  */
      unsigned int double_colon:1;/* Nonzero for double-colon entry */
--- 51,55 ----
        } command_state ENUM_BITFIELD (2);
  
!     short update_status;        /* Status of the last attempt to update,
  				   or -1 if none has been made.  */
      unsigned int double_colon:1;/* Nonzero for double-colon entry */

Index: function.c
***************
*** 420,428 ****
  		   newlines in its output with spaces, and put
  		   that in the variable output buffer.  */
! 		if (buffer[i - 1] == '\n')
  		  --i;
! 		for (p = buffer; p < buffer + i; ++p)
! 		  if (*p == '\n')
! 		    *p = ' ';
  		o = variable_buffer_output (o, buffer, i);
  	      }
--- 420,428 ----
  		   newlines in its output with spaces, and put
  		   that in the variable output buffer.  */
! 		if (i > 0 && buffer[i - 1] == '\n')
  		  --i;
! 		buffer[i] = '\0';
! 		for (p = buffer; (p = index(p, '\n')) != NULL; ++p)
! 		  *p = ' ';
  		o = variable_buffer_output (o, buffer, i);
  	      }

Index: glob.c
***************
*** 21,45 ****
  
  #include <sys/types.h>
  
- #if	defined(USGr3) || defined(DIRENT)
- 
- #include <dirent.h>
- #	if	!defined(d_ino) && !defined(d_fileno)
- #define	d_ino	d_fileno
- #	endif
- #define direct dirent
- #define	D_NAMLEN(d) strlen((d)->d_name)
- 
- #else	/* Not USGr3 and not DIRENT.  */
- 
- #define D_NAMLEN(d) ((d)->d_namlen)
- #	ifdef	USG
- #include "ndir.h"   /* Get ndir.h from the Emacs distribution.  */
- #	else	/* Not USG.  */
- #include <sys/dir.h>
- #	endif	/* USG.  */
- 
- #endif	/* USGr3 or DIRENT.  */
- 
  #ifdef USG
  #include <memory.h>
--- 21,26 ----
  
  #include <sys/types.h>
+ #include "dir.h"
  
  #ifdef USG
  #include <memory.h>

Index: job.c
***************
*** 489,493 ****
  
    if (just_print_flag || (!noprint && !silent_flag))
!     puts (p);
  
    /* If -n was given, recurse to get the next line in the sequence.  */
--- 489,496 ----
  
    if (just_print_flag || (!noprint && !silent_flag))
!     {
!       fputs (command_prefix, stdout);
!       puts (p);
!     }
  
    /* If -n was given, recurse to get the next line in the sequence.  */

Index: main.c
***************
*** 247,250 ****
--- 247,254 ----
  char *program;
  
+ /* The string to print before each command. */
+ 
+ char *command_prefix = "\t";
+ 
  /* Value of the MAKELEVEL variable at startup (or 0).  */
  
***************
*** 332,335 ****
--- 336,351 ----
  #endif
  
+   /* Line buffer stdout. */
+ 
+ #ifdef USGr3
+   setvbuf(stdout, (char *)0, _IOLBF, BUFSIZ);
+ #else
+ #ifdef USG
+   setvbuf(stdout, _IOLBF, (char *)0, BUFSIZ);
+ #else
+   setlinebuf(stdout);
+ #endif
+ #endif
+ 
    /* Figure out where this program lives.  */
  
***************
*** 376,379 ****
--- 392,400 ----
      print_version ();
  
+   /* If we're just printing commands, then we omit the prefix. */
+ 
+   if (just_print_flag)
+     command_prefix = "";
+ 
    /* Construct the list of include directories to search.  */
  
***************
*** 909,913 ****
  		      break;
  		    case string:
! 		      if (*sw == '\0')
  			arg = argv[++i];
  		      else
--- 930,934 ----
  		      break;
  		    case string:
! 		      if ((*sw == '\0') && (i + 1) < argc)
  			arg = argv[++i];
  		      else
***************
*** 943,947 ****
  
  		    case positive_int:
! 		      if (*sw == '\0')
  			arg = argv[++i];
  		      else
--- 964,968 ----
  
  		    case positive_int:
! 		      if ((*sw == '\0') && (i + 1) < argc)
  			arg = argv[++i];
  		      else
***************
*** 979,983 ****
  
  		    case floating:
! 		      if (*sw == '\0')
  			arg = argv[++i];
  		      else
--- 1000,1004 ----
  
  		    case floating:
! 		      if ((*sw == '\0') && (i + 1) < argc)
  			arg = argv[++i];
  		      else
***************
*** 1108,1115 ****
  
    i = 0;
-   flags[i++] = '-';
  
    for (cs = switches; cs->c != '\0'; ++cs)
!     if (cs->toenv)
        switch (cs->type)
  	{
--- 1129,1139 ----
  
    i = 0;
  
    for (cs = switches; cs->c != '\0'; ++cs)
!     {
!       if (! cs->toenv)
! 	continue;
!       if (i == 0 || flags[i - 1] == ' ')
! 	flags[i++] = '-';
        switch (cs->type)
  	{
***************
*** 1142,1153 ****
  		{
  		  strcpy (&flags[i], "j1 ");
! 		  i += 5;
  		}
  	      else
  		{
! 		  char *p = &flags[i];
! 		  sprintf (p, "%c%u ", cs->c,
  			   *(unsigned int *) cs->value_ptr);
! 		  i += strlen (p);
  		}
  	    }
--- 1166,1176 ----
  		{
  		  strcpy (&flags[i], "j1 ");
! 		  i += strlen (&flags[i]);
  		}
  	      else
  		{
! 		  sprintf (&flags[i], "%c%u ", cs->c,
  			   *(unsigned int *) cs->value_ptr);
! 		  i += strlen (&flags[i]);
  		}
  	    }
***************
*** 1174,1177 ****
--- 1197,1201 ----
  	  break;
  	}
+     }
  
    if (i == 0)

Index: make.h
***************
*** 89,92 ****
--- 89,93 ----
  extern struct dep *copy_dep_chain ();
  extern char *find_percent ();
+ extern char *getcurdir ();
  
  #ifndef	NO_ARCHIVES
***************
*** 131,142 ****
  extern char **environ;
  
! #ifdef	USG
! extern char *getcwd ();
! #define	getwd(buf)	getcwd (buf, MAXPATHLEN - 2)
! #else	/* Not USG.  */
! extern char *getwd ();
! #endif	/* USG.  */
  
- 
  extern char *reading_filename;
  extern unsigned int *reading_lineno_ptr;
--- 132,137 ----
  extern char **environ;
  
! #define getwd(buf)      getcurdir (buf, MAXPATHLEN - 2)
  
  extern char *reading_filename;
  extern unsigned int *reading_lineno_ptr;
***************
*** 151,154 ****
--- 146,150 ----
  
  extern char *program;
+ extern char *command_prefix;
  
  extern unsigned int makelevel;

Index: remake.c
***************
*** 578,582 ****
    if (!silent_flag)
      {
!       printf ("touch %s\n", file->name);
        fflush (stdout);
      }
--- 578,585 ----
    if (!silent_flag)
      {
!       fputs (command_prefix, stdout);
!       fputs ("touch ", stdout);
!       fputs (file->name, stdout);
!       fputc ('\n', stdout);
        fflush (stdout);
      }
***************
*** 630,633 ****
--- 633,638 ----
       struct file *file;
  {
+   int has_commands = 0;
+ 
    if (file->cmds == 0 && !(touch_flag && !file->is_target))
      {
***************
*** 664,672 ****
  	}
        else
! 	execute_file_commands (file);
      }
  
!   file->command_state = cs_finished;
!   notice_finished_file (file);
  }
  
--- 669,683 ----
  	}
        else
! 	{
! 	  execute_file_commands (file);
! 	  has_commands = 1;
! 	}
      }
  
!   if (!has_commands)
!     {
!       file->command_state = cs_finished;
!       notice_finished_file (file);
!     }
  }
  

Index: variable.c
***************
*** 383,389 ****
  	      register char *p = v->name;
  
! 	      if (v->origin == o_default
! 		  || streq (p, "MAKELEVEL"))
  		continue;
  
  	      if (*p != '_' && (*p < 'A' || *p > 'Z')
--- 383,395 ----
  	      register char *p = v->name;
  
! #ifdef VARS_IN_ENV
! 	      if (v->origin == o_default)
  		continue;
+ #else
+ 	      if ((v->origin != o_env) && (v->origin != o_env_override))
+ 		continue;
+ #endif
+ 	      if (streq (p, "MAKELEVEL"))
+ 		continue;
  
  	      if (*p != '_' && (*p < 'A' || *p > 'Z')
Technical Details
Message-ID: <m0gE0aU-0006HMC@ateng.ateng.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!ateng.ateng.com!chip

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!ateng.ateng.com!chip
From: chip@ateng.ateng.com (Chip Salzenberg)
Newsgroups: gnu.utils.bug
Subject: Make 3.56: Xenix patches and bug fixes
Message-ID: <m0gE0aU-0006HMC@ateng.ateng.com>
Date: 9 Oct 89 14:02:45 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 803