Bourne shell history + tilde + job control + more (Part 6 of 9)

sources-request at genrad.UUCP sources-request at genrad.UUCP
Wed Jun 12 01:47:17 AEST 1985


From: Arnold Robbins <gatech!arnold>

This is part 6 of 9.  It contains the second set of code diffs for the System V
Release 2 Bourne shell.

BSD users who happen to also have source for System V Release 2 will probably
want to use this version of the shell, since it has many bug fixes and
improvements over the (much) earlier version that comes with Berkeley Unix.

Arnold Robbins
arnold at gatech.{UUCP, CSNET}
----------- pretend your screen is really a paper towel ------------
:::::::: name.c :::::::
*** ../orig.u/name.c	Wed May 15 17:08:24 1985
--- name.c	Tue May 21 19:02:42 1985
***************
*** 15,21
  struct namnod ps2nod =
  {
  	(struct namnod *)NIL,
! 	&acctnod,
  	ps2name
  };
  struct namnod cdpnod = 

--- 15,21 -----
  struct namnod ps2nod =
  {
  	(struct namnod *)NIL,
! 	(struct namnod *)NIL,
  	ps2name
  };
  struct namnod cdpnod = 
***************
*** 32,38
  };
  struct namnod ifsnod =
  {
! 	&homenod,
  	&mailnod,
  	ifsname
  };

--- 32,38 -----
  };
  struct namnod ifsnod =
  {
! 	&histfnod,
  	&mailnod,
  	ifsname
  };
***************
*** 39,45
  struct namnod ps1nod =
  {
  	&pathnod,
! 	&ps2nod,
  	ps1name
  };
  struct namnod homenod =

--- 39,45 -----
  struct namnod ps1nod =
  {
  	&pathnod,
! 	&acctnod,
  	ps1name
  };
  struct namnod homenod =
***************
*** 44,50
  };
  struct namnod homenod =
  {
- 	&cdpnod,
  	(struct namnod *)NIL,
  	homename
  };

--- 44,49 -----
  };
  struct namnod homenod =
  {
  	(struct namnod *)NIL,
  	(struct namnod *)NIL,
  	homename
***************
*** 46,51
  {
  	&cdpnod,
  	(struct namnod *)NIL,
  	homename
  };
  struct namnod mailnod =

--- 45,51 -----
  struct namnod homenod =
  {
  	(struct namnod *)NIL,
+ 	(struct namnod *)NIL,
  	homename
  };
  struct namnod mailnod =
***************
*** 62,67
  };
  struct namnod acctnod =
  {
  	(struct namnod *)NIL,
  	(struct namnod *)NIL,
  	acctname

--- 62,71 -----
  };
  struct namnod acctnod =
  {
+ 	&ps2nod,
+ #if pyr
+ 	&univnod,
+ #else
  	(struct namnod *)NIL,
  #endif
  	acctname
***************
*** 63,69
  struct namnod acctnod =
  {
  	(struct namnod *)NIL,
! 	(struct namnod *)NIL,
  	acctname
  };
  struct namnod mailpnod =

--- 67,73 -----
  	&univnod,
  #else
  	(struct namnod *)NIL,
! #endif
  	acctname
  };
  struct namnod mailpnod =
***************
*** 72,77
  	(struct namnod *)NIL,
  	mailpname
  };
  
  
  struct namnod *namep = &mchknod;

--- 76,95 -----
  	(struct namnod *)NIL,
  	mailpname
  };
+ struct namnod histfnod =
+ {
+ 	&cdpnod,
+ 	&homenod,
+ 	histfilename
+ };
+ #if pyr
+ struct namnod univnod =
+ {
+ 	(struct namnod *)NIL,
+ 	(struct namnod *)NIL,
+ 	univname
+ };
+ #endif
  
  
  struct namnod *namep = &mchknod;
***************
*** 86,91
  	int	low;
  	int	high;
  	int	mid;
  	register int cond;
  
  	if (w == 0 || *w == 0)

--- 104,112 -----
  	int	low;
  	int	high;
  	int	mid;
+ #if gould
+ 	int	cond;	/* DAG -- avoid optimizer bug */
+ #else
  	register int cond;
  #endif
  
***************
*** 87,92
  	int	high;
  	int	mid;
  	register int cond;
  
  	if (w == 0 || *w == 0)
  		return(0);

--- 108,114 -----
  	int	cond;	/* DAG -- avoid optimizer bug */
  #else
  	register int cond;
+ #endif
  
  	if (w == 0 || *w == 0)
  		return(0);
***************
*** 228,233
  readvar(names)
  char	**names;
  {
  	struct fileblk	fb;
  	register struct fileblk *f = &fb;
  	register char	c;

--- 250,256 -----
  readvar(names)
  char	**names;
  {
+ 	extern long lseek();	/* DAG -- bug fix (was missing) */
  	struct fileblk	fb;
  	register struct fileblk *f = &fb;
  	register char	c;
***************
*** 238,244
  	push(f);
  	initf(dup(0));
  
! 	if (lseek(0, 0L, 1) == -1)
  		f->fsiz = 1;
  
  	/*

--- 261,267 -----
  	push(f);
  	initf(dup(0));
  
! 	if (lseek(0, 0L, 1) == -1L)	/* DAG */
  		f->fsiz = 1;
  
  	/*
:::::::: name.h :::::::
No differences encountered
:::::::: print.c :::::::
*** ../orig.u/print.c	Wed May 15 17:08:25 1985
--- print.c	Mon May 20 15:32:21 1985
***************
*** 7,12
   */
  
  #include	"defs.h"
  #include	<sys/param.h>
  
  #define		BUFLEN		256

--- 7,15 -----
   */
  
  #include	"defs.h"
+ #if JOBS
+ #define		HZ	60
+ #else
  #include	<sys/param.h>
  #endif
  
***************
*** 8,13
  
  #include	"defs.h"
  #include	<sys/param.h>
  
  #define		BUFLEN		256
  

--- 11,17 -----
  #define		HZ	60
  #else
  #include	<sys/param.h>
+ #endif
  
  #define		BUFLEN		256
  
***************
*** 66,73
  		prc_buff('h');
  	}
  
! 	prn_buff(min);
! 	prc_buff('m');
  	prn_buff(sec);
  	prc_buff('s');
  }

--- 70,80 -----
  		prc_buff('h');
  	}
  
! 	if (min)	/* BRL... for consistency */
! 	{
! 		prn_buff(min);
! 		prc_buff('m');
! 	}
  	prn_buff(sec);
  	prc_buff('s');
  }
***************
*** 230,233
  	itos(n);
  
  	prs_buff(numbuf);
  }

--- 237,357 -----
  	itos(n);
  
  	prs_buff(numbuf);
+ }
+ 
+ void
+ pr_prompt (str)
+ register char *str;
+ {
+ 	for (; *str; str++)
+ 	{
+ 		if (*str != '%')
+ 			prc_buff (*str);
+ 		else if (*(str+1) == 'd')
+ 		{
+ 			/* current directory */
+ 			str++;
+ 			prs_buff (retcwd());
+ 		}
+ 		else if (*(str+1) == 'e')
+ 		{
+ 			/* event count */
+ 			str++;
+ 			if ((flags & nohistflg) == 0)
+ 				prn_buff (event_count);
+ 		}
+ 		else if (*(str+1) == 'h')
+ 		{
+ 			/* hostname */
+ 			static char *cp = 0;
+ 			static int didhost = FALSE;
+ 			static int didgt = FALSE;
+ #ifdef JOBS
+ 			static char buf[257];
+ 
+ 			if (! didhost)
+ 			{
+ 				gethostname (buf, sizeof buf);
+ 				didhost = TRUE;
+ 				cp = buf;
+ 			}
+ #else
+ #include <sys/utsname.h>	/* has an extern declaration in it */
+ 			static struct utsname name;
+ 
+ 			if (! didhost)
+ 			{
+ 				uname (& name);
+ 				/* avoid emulation bug */
+ 				name.sysname[sizeof(name.sysname)-1] = '\0';
+ 				didhost = TRUE;
+ 				cp = name.sysname;
+ 			}
+ #endif
+ 
+ #ifdef GATECH
+ 			/*
+ 			 * this is to get rid of the dumb gt- convention.
+ 			 * a gt w/out the - is also removed.
+ 			 */
+ 			if (! didgt)
+ 			{
+ 				didgt = TRUE;
+ 				if (cp[0] == 'g' && cp[1] == 't' && cp[2])
+ 				{
+ 					cp += 2;
+ 					if (cp[0] == '-' && cp[1])
+ 						cp++;
+ 				}
+ 			}
+ #endif
+ 			prs_buff (cp);
+ 			str++;
+ 		}
+ 		else if (*(str+1) == 'l')
+ 		{
+ 			/* login name */
+ 			static char *cp = 0;
+ 			static int didname = FALSE;
+ 
+ 			str++;
+ 			if (! didname)
+ 			{
+ 				cp = username ();
+ 				didname = TRUE;
+ 			}
+ 
+ 			if (cp)
+ 				prs_buff (cp);
+ 		}
+ 		else if (*(str+1) == 't')
+ 		{
+ 			/* current time, HH:MM */
+ 			long l;
+ 			char *cp, *ctime ();
+ 
+ 			str++;
+ 			time (& l);
+ 			cp = ctime (& l);
+ 			cp[16] = '\0';
+ 			cp += 11;
+ 			prs_buff (cp);
+ 		}
+ #if pyr
+ 		else if (*(str+1) == 'u')
+ 		{
+ 			/* current univeserse */
+ 			str++;
+ 			prs_buff (univ_name[cur_univ-1]);
+ 		}
+ #endif
+ 		else if (*(str+1) == '\0')	/* % was last char in string */
+ 		{
+ 			prc_buff (*str);
+ 			continue;
+ 		}
+ 		else
+ 			prc_buff (*(++str));
+ 	}
+ 	flushb();
  }
:::::::: profile.c :::::::
No differences encountered
:::::::: pwd.c :::::::
*** ../orig.u/pwd.c	Wed May 15 17:08:27 1985
--- pwd.c	Mon May 20 17:20:51 1985
***************
*** 4,9
   *
   *	Bell Telephone Laboratories
   *
   */
  
  #include		"mac.h"

--- 4,14 -----
   *
   *	Bell Telephone Laboratories
   *
+  *	DAG -- Two ways of handling symbolic links in directory paths:
+  *		Define SYMLINK if you want "cd .." to do just that.
+  *		Otherwise, "cd .." takes you back the way you came.
+  *	The first method was implemented by Ron Natalie and the
+  *	second method was implemented by Douglas Gwyn, both of BRL.
   */
  
  #include		"defs.h"	/* DAG -- was just "mac.h" */
***************
*** 6,12
   *
   */
  
! #include		"mac.h"
  
  #define	DOT		'.'
  #define	NULL	0

--- 11,19 -----
   *	second method was implemented by Douglas Gwyn, both of BRL.
   */
  
! #include		"defs.h"	/* DAG -- was just "mac.h" */
! #include	<sys/types.h>		/* DAG -- moved for SYMLINK */
! #include	<sys/stat.h>		/* DAG -- moved for SYMLINK */
  
  #if defined(SYMLINK) && !defined(S_IFLNK)
  #define	S_IFLNK	0120000
***************
*** 8,13
  
  #include		"mac.h"
  
  #define	DOT		'.'
  #define	NULL	0
  #define	SLASH	'/'

--- 15,24 -----
  #include	<sys/types.h>		/* DAG -- moved for SYMLINK */
  #include	<sys/stat.h>		/* DAG -- moved for SYMLINK */
  
+ #if defined(SYMLINK) && !defined(S_IFLNK)
+ #define	S_IFLNK	0120000
+ #endif
+ 
  #define	DOT		'.'
  #define	NULL	0
  #define	SLASH	'/'
***************
*** 11,16
  #define	DOT		'.'
  #define	NULL	0
  #define	SLASH	'/'
  #define MAXPWD	256
  
  extern char	longpwd[];

--- 22,30 -----
  #define	DOT		'.'
  #define	NULL	0
  #define	SLASH	'/'
+ #if defined(JOBS)
+ #define MAXPWD	(24*256)	/* who knows */
+ #else
  #define MAXPWD	256
  #endif
  
***************
*** 12,17
  #define	NULL	0
  #define	SLASH	'/'
  #define MAXPWD	256
  
  extern char	longpwd[];
  

--- 26,32 -----
  #define MAXPWD	(24*256)	/* who knows */
  #else
  #define MAXPWD	256
+ #endif
  
  extern char	longpwd[];
  
***************
*** 17,22
  
  static char cwdname[MAXPWD];
  static int 	didpwd = FALSE;
  
  cwd(dir)
  	register char *dir;

--- 32,41 -----
  
  static char cwdname[MAXPWD];
  static int 	didpwd = FALSE;
+ #if SYMLINK
+ /* Stuff to handle chdirs around symbolic links */
+ static char	*symlink = 0;	/* Pointer to after last symlink in cwdname */
+ #endif
  
  cwd(dir)
  	register char *dir;
***************
*** 21,26
  cwd(dir)
  	register char *dir;
  {
  	register char *pcwd;
  	register char *pdir;
  

--- 40,48 -----
  cwd(dir)
  	register char *dir;
  {
+ #if SYMLINK
+ 	struct stat statb;
+ #endif
  	register char *pcwd;
  	register char *pdir;
  
***************
*** 44,51
  		if (*pdir) 
  			pdir++;
  	}
! 	if(*(--pdir)==DOT && pdir>dir && *(--pdir)==SLASH)
! 		*pdir = NULL;
  	
  
  	/* Remove extra /'s */

--- 66,73 -----
  		if (*pdir) 
  			pdir++;
  	}
! 	if(pdir>dir && *(--pdir)==DOT && pdir>dir && *(--pdir)==SLASH)	/* DAG -- bug fix (added first test) */
! 		*pdir = '\0';	/* DAG -- not NULL */
  	
  
  	/* Remove extra /'s */
***************
*** 65,70
  
  		pcwd = cwdname;
  		didpwd = TRUE;
  	}
  	else
  	{

--- 87,95 -----
  
  		pcwd = cwdname;
  		didpwd = TRUE;
+ #if SYMLINK
+ 		symlink = 0;		/* Starting over, no links yet */
+ #endif
  	}
  	else
  	{
***************
*** 71,76
  		/* Relative path */
  
  		if (didpwd == FALSE) 
  			return;
  			
  		pcwd = cwdname + length(cwdname) - 1;

--- 96,104 -----
  		/* Relative path */
  
  		if (didpwd == FALSE) 
+ #if !defined(SYMLINK) && defined(JOBS)
+ 			pwd();		/* Get absolute pathname into cwdname[] */
+ #else
  			return;
  #endif
  			
***************
*** 72,77
  
  		if (didpwd == FALSE) 
  			return;
  			
  		pcwd = cwdname + length(cwdname) - 1;
  		if(pcwd != cwdname+1)

--- 100,106 -----
  			pwd();		/* Get absolute pathname into cwdname[] */
  #else
  			return;
+ #endif
  			
  		pcwd = cwdname + length(cwdname) - 1;
  		if(pcwd != cwdname+1)
***************
*** 93,98
  				;
  			pcwd++;
  			dir += 2;
  			if(*dir==SLASH)
  			{
  				dir++;

--- 122,135 -----
  				;
  			pcwd++;
  			dir += 2;
+ #if SYMLINK
+ 			/* Just undid symlink, so pwd the hard way */
+ 			if(pcwd < symlink)
+ 			{
+ 				pwd();
+ 				return;
+ 			}
+ #endif
  			if(*dir==SLASH)
  			{
  				dir++;
***************
*** 102,107
  		*pcwd++ = *dir++;
  		while((*dir) && (*dir != SLASH))
  			*pcwd++ = *dir++;
  		if (*dir) 
  			*pcwd++ = *dir++;
  	}

--- 139,161 -----
  		*pcwd++ = *dir++;
  		while((*dir) && (*dir != SLASH))
  			*pcwd++ = *dir++;
+ #if SYMLINK
+ 		/* Check to see if this path component is a symbolic link */
+ 		*pcwd = 0;
+ 		if(lstat(cwdname, &statb) != 0)
+ 		{
+ 			prs(cwdname);	/* DAG */
+ 			error(nolstat);	/* DAG -- made string sharable */
+ 			pwd();
+ 			return;
+ 		}
+ 		if((statb.st_mode & S_IFMT) == S_IFLNK)
+ 			/* Set fence so that when we attempt to
+ 			 * "cd .." past it, we know that it is invalid
+ 			 * and have to do it the hard way
+ 			 */
+ 			symlink = dir;
+ #endif
  		if (*dir) 
  			*pcwd++ = *dir++;
  	}
***************
*** 105,111
  		if (*dir) 
  			*pcwd++ = *dir++;
  	}
! 	*pcwd = NULL;
  
  	--pcwd;
  	if(pcwd>cwdname && *pcwd==SLASH)

--- 159,165 -----
  		if (*dir) 
  			*pcwd++ = *dir++;
  	}
! 	*pcwd = '\0';	/* DAG -- not NULL */
  
  	--pcwd;
  	if(pcwd>cwdname && *pcwd==SLASH)
***************
*** 112,118
  	{
  		/* Remove trailing / */
  
! 		*pcwd = NULL;
  	}
  	return;
  }

--- 166,172 -----
  	{
  		/* Remove trailing / */
  
! 		*pcwd = '\0';	/* DAG -- not NULL */
  	}
  	return;
  }
***************
*** 168,174
   *	Find the current directory the hard way.
   */
  
! #include	<sys/types.h>
  #include	<sys/dir.h>
  #include	<sys/stat.h>
  

--- 222,230 -----
   *	Find the current directory the hard way.
   */
  
! #if JOBS
! #include	<dir.h>
! #else
  #include	<sys/dir.h>
  #endif
  
***************
*** 170,176
  
  #include	<sys/types.h>
  #include	<sys/dir.h>
! #include	<sys/stat.h>
  
  
  static char dotdots[] =

--- 226,232 -----
  #include	<dir.h>
  #else
  #include	<sys/dir.h>
! #endif
  
  
  static char dotdots[] =
***************
*** 176,181
  static char dotdots[] =
  "../../../../../../../../../../../../../../../../../../../../../../../..";
  
  extern struct direct	*getdir();
  extern char		*movstrn();
  

--- 232,240 -----
  static char dotdots[] =
  "../../../../../../../../../../../../../../../../../../../../../../../..";
  
+ #if JOBS
+ #define	getdir(dirf)	readdir(dirf)
+ #else
  extern struct direct	*getdir();
  extern char		*movstrn();
  #endif
***************
*** 178,183
  
  extern struct direct	*getdir();
  extern char		*movstrn();
  
  static
  pwd()

--- 237,243 -----
  #else
  extern struct direct	*getdir();
  extern char		*movstrn();
+ #endif
  
  static
  pwd()
***************
*** 185,190
  	struct stat		cdir;	/* current directory status */
  	struct stat		tdir;
  	struct stat		pdir;	/* parent directory status */
  	int				pdfd;	/* parent directory file descriptor */
  
  	struct direct	*dir;

--- 245,253 -----
  	struct stat		cdir;	/* current directory status */
  	struct stat		tdir;
  	struct stat		pdir;	/* parent directory status */
+ #if JOBS
+ 	DIR				*pdfd;	/* parent directory stream */
+ #else
  	int				pdfd;	/* parent directory file descriptor */
  #endif
  
***************
*** 186,191
  	struct stat		tdir;
  	struct stat		pdir;	/* parent directory status */
  	int				pdfd;	/* parent directory file descriptor */
  
  	struct direct	*dir;
  	char 			*dot = dotdots + sizeof(dotdots) - 3;

--- 249,255 -----
  	DIR				*pdfd;	/* parent directory stream */
  #else
  	int				pdfd;	/* parent directory file descriptor */
+ #endif
  
  	struct direct	*dir;
  	char 			*dot = dotdots + sizeof(dotdots) - 3;
***************
*** 193,198
  	int				cwdindex = MAXPWD - 1;
  	int 			i;
  	
  	cwdname[cwdindex] = 0;
  	dotdots[index] = 0;
  

--- 257,265 -----
  	int				cwdindex = MAXPWD - 1;
  	int 			i;
  	
+ #if SYMLINK
+ 	symlink = 0;			/* Starting over, no links yet */
+ #endif
  	cwdname[cwdindex] = 0;
  	dotdots[index] = 0;
  
***************
*** 206,212
  	for(;;)
  	{
  		cdir = pdir;
! 
  		if ((pdfd = open(dot, 0)) < 0)
  		{
  			error("pwd: cannot open ..");

--- 273,281 -----
  	for(;;)
  	{
  		cdir = pdir;
! #if JOBS
! 		if ((pdfd = opendir(dot)) == (DIR *)0)
! #else
  		if ((pdfd = open(dot, 0)) < 0)
  #endif
  		{
***************
*** 208,213
  		cdir = pdir;
  
  		if ((pdfd = open(dot, 0)) < 0)
  		{
  			error("pwd: cannot open ..");
  		}

--- 277,283 -----
  		if ((pdfd = opendir(dot)) == (DIR *)0)
  #else
  		if ((pdfd = open(dot, 0)) < 0)
+ #endif
  		{
  			error("pwd: cannot open ..");
  		}
***************
*** 211,217
  		{
  			error("pwd: cannot open ..");
  		}
! 
  		if(fstat(pdfd, &pdir) < 0)
  		{
  			close(pdfd);

--- 281,289 -----
  		{
  			error("pwd: cannot open ..");
  		}
! #if JOBS
! 		if(fstat(pdfd->dd_fd, &pdir) < 0)
! #else
  		if(fstat(pdfd, &pdir) < 0)
  #endif
  		{
***************
*** 213,218
  		}
  
  		if(fstat(pdfd, &pdir) < 0)
  		{
  			close(pdfd);
  			error("pwd: cannot stat ..");

--- 285,291 -----
  		if(fstat(pdfd->dd_fd, &pdir) < 0)
  #else
  		if(fstat(pdfd, &pdir) < 0)
+ #endif
  		{
  #if JOBS
  			closedir(pdfd);
***************
*** 214,219
  
  		if(fstat(pdfd, &pdir) < 0)
  		{
  			close(pdfd);
  			error("pwd: cannot stat ..");
  		}

--- 287,295 -----
  		if(fstat(pdfd, &pdir) < 0)
  #endif
  		{
+ #if JOBS
+ 			closedir(pdfd);
+ #else
  			close(pdfd);
  #endif
  			error("pwd: cannot stat ..");
***************
*** 215,220
  		if(fstat(pdfd, &pdir) < 0)
  		{
  			close(pdfd);
  			error("pwd: cannot stat ..");
  		}
  

--- 291,297 -----
  			closedir(pdfd);
  #else
  			close(pdfd);
+ #endif
  			error("pwd: cannot stat ..");
  		}
  
***************
*** 223,228
  			if(cdir.st_ino == pdir.st_ino)
  			{
  				didpwd = TRUE;
  				close(pdfd);
  				if (cwdindex == (MAXPWD - 1))
  					cwdname[--cwdindex] = SLASH;

--- 300,308 -----
  			if(cdir.st_ino == pdir.st_ino)
  			{
  				didpwd = TRUE;
+ #if JOBS
+ 				closedir(pdfd);
+ #else
  				close(pdfd);
  #endif
  				if (cwdindex == (MAXPWD - 1))
***************
*** 224,229
  			{
  				didpwd = TRUE;
  				close(pdfd);
  				if (cwdindex == (MAXPWD - 1))
  					cwdname[--cwdindex] = SLASH;
  

--- 304,310 -----
  				closedir(pdfd);
  #else
  				close(pdfd);
+ #endif
  				if (cwdindex == (MAXPWD - 1))
  					cwdname[--cwdindex] = SLASH;
  
***************
*** 235,240
  			{
  				if ((dir = getdir(pdfd)) == 0)
  				{
  					close(pdfd);
  					reset_dir();
  					error("pwd: read error in ..");

--- 316,324 -----
  			{
  				if ((dir = getdir(pdfd)) == 0)
  				{
+ #if JOBS
+ 					closedir(pdfd);
+ #else
  					close(pdfd);
  					reset_dir();
  #endif
***************
*** 237,242
  				{
  					close(pdfd);
  					reset_dir();
  					error("pwd: read error in ..");
  				}
  			}

--- 321,327 -----
  #else
  					close(pdfd);
  					reset_dir();
+ #endif
  					error("pwd: read error in ..");
  				}
  			}
***************
*** 244,250
  		}
  		else
  		{
! 			char name[512];
  			
  			movstr(dot, name);
  			i = length(name) - 1;

--- 329,335 -----
  		}
  		else
  		{
! 			char name[256+MAXPWD];	/* DAG -- (was 512) */
  			
  			movstr(dot, name);
  			i = length(name) - 1;
***************
*** 251,256
  
  			name[i++] = '/';
  
  			do
  			{
  				if ((dir = getdir(pdfd)) == 0)

--- 336,342 -----
  
  			name[i++] = '/';
  
+ 			tdir.st_dev = pdir.st_dev;	/* DAG -- (safety) */
  			do
  			{
  				if ((dir = getdir(pdfd)) == 0)
***************
*** 255,260
  			{
  				if ((dir = getdir(pdfd)) == 0)
  				{
  					close(pdfd);
  					reset_dir();
  					error("pwd: read error in ..");

--- 341,349 -----
  			{
  				if ((dir = getdir(pdfd)) == 0)
  				{
+ #if JOBS
+ 					closedir(pdfd);
+ #else
  					close(pdfd);
  					reset_dir();
  #endif
***************
*** 257,262
  				{
  					close(pdfd);
  					reset_dir();
  					error("pwd: read error in ..");
  				}
  				*(movstrn(dir->d_name, &name[i], DIRSIZ)) = 0;

--- 346,352 -----
  #else
  					close(pdfd);
  					reset_dir();
+ #endif
  					error("pwd: read error in ..");
  				}
  #if JOBS
***************
*** 259,264
  					reset_dir();
  					error("pwd: read error in ..");
  				}
  				*(movstrn(dir->d_name, &name[i], DIRSIZ)) = 0;
  				stat(name, &tdir);
  			}		

--- 349,357 -----
  #endif
  					error("pwd: read error in ..");
  				}
+ #if JOBS
+ 				movstr(dir->d_name, &name[i]);
+ #else
  				*(movstrn(dir->d_name, &name[i], DIRSIZ)) = 0;
  #endif
  				stat(name, &tdir);
***************
*** 260,265
  					error("pwd: read error in ..");
  				}
  				*(movstrn(dir->d_name, &name[i], DIRSIZ)) = 0;
  				stat(name, &tdir);
  			}		
  			while(tdir.st_ino != cdir.st_ino || tdir.st_dev != cdir.st_dev);

--- 353,359 -----
  				movstr(dir->d_name, &name[i]);
  #else
  				*(movstrn(dir->d_name, &name[i], DIRSIZ)) = 0;
+ #endif
  				stat(name, &tdir);
  			}		
  			while(tdir.st_ino != cdir.st_ino || tdir.st_dev != cdir.st_dev);
***************
*** 264,269
  			}		
  			while(tdir.st_ino != cdir.st_ino || tdir.st_dev != cdir.st_dev);
  		}
  		close(pdfd);
  		reset_dir();
  

--- 358,366 -----
  			}		
  			while(tdir.st_ino != cdir.st_ino || tdir.st_dev != cdir.st_dev);
  		}
+ #if JOBS
+ 		closedir(pdfd);
+ #else
  		close(pdfd);
  		reset_dir();
  #endif
***************
*** 266,271
  		}
  		close(pdfd);
  		reset_dir();
  
  		for (i = 0; i < DIRSIZ; i++)
  			if (dir->d_name[i] == 0)

--- 363,369 -----
  #else
  		close(pdfd);
  		reset_dir();
+ #endif
  
  #if JOBS
  		i = dir->d_namlen;
***************
*** 267,272
  		close(pdfd);
  		reset_dir();
  
  		for (i = 0; i < DIRSIZ; i++)
  			if (dir->d_name[i] == 0)
  				break;

--- 365,373 -----
  		reset_dir();
  #endif
  
+ #if JOBS
+ 		i = dir->d_namlen;
+ #else
  		for (i = 0; i < DIRSIZ; i++)
  			if (dir->d_name[i] == 0)
  				break;
***************
*** 270,275
  		for (i = 0; i < DIRSIZ; i++)
  			if (dir->d_name[i] == 0)
  				break;
  
  		if (i > cwdindex - 1)
  				error(longpwd);

--- 371,377 -----
  		for (i = 0; i < DIRSIZ; i++)
  			if (dir->d_name[i] == 0)
  				break;
+ #endif
  
  		if (i > cwdindex - 1)
  				error(longpwd);
***************
*** 284,287
  		if (dot<dotdots) 
  			error(longpwd);
  	}
  }

--- 386,419 -----
  		if (dot<dotdots) 
  			error(longpwd);
  	}
+ }
+ #if !defined(SYMLINK) && defined(JOBS)
+ 
+ /* The following chdir() interface is used to outwit symbolic links. */
+ 
+ int
+ cwdir( dir )				/* attempt a full-pathname chdir */
+ 	char		*dir;		/* name to feed to chdir() */
+ 	{
+ 	char		savname[MAXPWD];	/* saved cwdname[] */
+ 	register int	retval;		/* chdir() return value */
+ 
+ 	(void)movstr( cwdname, savname );	/* save current name */
+ 
+ 	cwd( dir );			/* adjust cwdname[] */
+ 
+ 	if ( (retval = chdir( cwdname )) < 0 )
+ 		(void)movstr( savname, cwdname );	/* restore name */
+ 
+ 	return retval;
+ 	}
+ #endif
+ 
+ char *
+ retcwd()
+ {
+ 	if (didpwd == FALSE)
+ 		pwd ();
+ 	
+ 	return (cwdname);
  }
:::::::: service.c :::::::
*** ../orig.u/service.c	Wed May 15 17:08:28 1985
--- service.c	Wed May 29 15:54:16 1985
***************
*** 8,13
  
  #include	"defs.h"
  #include	<errno.h>
  
  #define ARGMK	01
  

--- 8,17 -----
  
  #include	"defs.h"
  #include	<errno.h>
+ #if JOBS
+ extern int	errno;
+ #include	"/usr/include/sys/wait.h"
+ #endif
  
  #define ARGMK	01
  
***************
*** 24,29
  	struct ionod	*iop;
  	int		save;
  {
  	register char	*ion;
  	register int	iof, fd;
  	int		ioufd;

--- 28,34 -----
  	struct ionod	*iop;
  	int		save;
  {
+ 	extern long	lseek();	/* DAG -- bug fix (was missing) */
  	register char	*ion;
  	register int	iof, fd;
  	int		ioufd;
***************
*** 70,75
  				else
  					fd = dup(fd);
  			}
  			else if ((iof & IOPUT) == 0)
  				fd = chkopen(ion);
  			else if (flags & rshflg)

--- 75,85 -----
  				else
  					fd = dup(fd);
  			}
+ 			else if (iof & IORDW)
+ 			{
+ 				if ((fd = open(ion, 2)) < 0)
+ 					failed(ion, badopen);
+ 			}
  			else if ((iof & IOPUT) == 0)
  				fd = chkopen(ion);
  			else if (flags & rshflg)
***************
*** 145,150
  	 */
  	register char	*scanp = path;
  	register char	*argp = locstak();
  
  	while (*scanp && *scanp != COLON)
  		*argp++ = *scanp++;

--- 155,162 -----
  	 */
  	register char	*scanp = path;
  	register char	*argp = locstak();
+ 	char	*save = argp;
+ 	char	*cp;
  
  	while (*scanp && *scanp != COLON)
  		*argp++ = *scanp++;
***************
*** 148,153
  
  	while (*scanp && *scanp != COLON)
  		*argp++ = *scanp++;
  	if (scanp != path)
  		*argp++ = '/';
  	if (*scanp == COLON)

--- 160,172 -----
  
  	while (*scanp && *scanp != COLON)
  		*argp++ = *scanp++;
+ 	*argp = '\0';
+ 	/* try a tilde expansion */
+ 	if (*save == SQUIGGLE && (cp = homedir (save + 1)) != nullstr)
+ 	{
+ 		movstr (cp, save);
+ 		argp = save + length (save) - 1;
+ 	}
  	if (scanp != path)
  		*argp++ = '/';
  	if (*scanp == COLON)
***************
*** 232,237
  		if (input)
  			close(input);
  		input = chkopen(p);
  	
  #ifdef ACCT
  		preacct(p);	/* reset accounting */

--- 251,271 -----
  		if (input)
  			close(input);
  		input = chkopen(p);
+ #if JOBS
+ 		/* don't try to interpret directories etc. */
+ 		{
+ #include	<sys/types.h>
+ #include	<sys/stat.h>
+ 			struct stat	sbuf;
+ 
+ 			if (fstat(input, &sbuf) == 0
+ 				&& (sbuf.st_mode&S_IFMT) != S_IFREG)
+ 			{
+ 				close (input);
+ 				goto def;	/* badexec unless other found */
+ 			}
+ 		}
+ #endif
  	
  #ifdef ACCT
  		preacct(p);	/* reset accounting */
***************
*** 254,259
  		failed(p, txtbsy);
  
  	default:
  		xecmsg = badexec;
  	case ENOENT:
  		return(prefix);

--- 288,296 -----
  		failed(p, txtbsy);
  
  	default:
+ #if JOBS
+ 	def:
+ #endif
  		xecmsg = badexec;
  	case ENOENT:
  		return(prefix);
***************
*** 268,273
  static int	pwlist[MAXP];
  static int	pwc;
  
  postclr()
  {
  	register int	*pw = pwlist;

--- 305,355 -----
  static int	pwlist[MAXP];
  static int	pwc;
  
+ #if JOBS
+ static int	*wf_pwlist;
+ static int	wf_pwc;
+ 
+ void
+ set_wfence()
+ {
+ 	wf_pwlist = &pwlist[pwc];
+ 	wf_pwc = 0;
+ }
+ 
+ BOOL
+ unpost(pcsid)
+ 	int	pcsid;
+ {
+ 	register int	*pw = pwlist;
+ 
+ 	if (pcsid)
+ 	{
+ 		while (pw <= &pwlist[pwc])
+ 		{
+ 			if (pcsid == *pw)
+ 			{
+ 				if (pw >= wf_pwlist)
+ 					wf_pwc--;
+ 				else
+ 					wf_pwlist--;
+ 				while (pw <= &pwlist[pwc])
+ 				{
+ 					*pw = pw[1];
+ 					pw++;
+ 				}
+ 				pw[pwc] = 0;
+ 				pwc--;
+ 				return TRUE;
+ 			}
+ 			pw++;
+ 		}
+ 		return FALSE;
+ 	}
+ 	else
+ 		return TRUE;
+ }
+ #endif
+ 
  postclr()
  {
  	register int	*pw = pwlist;
***************
*** 273,278
  	register int	*pw = pwlist;
  
  	while (pw <= &pwlist[pwc])
  		*pw++ = 0;
  	pwc = 0;
  }

--- 355,364 -----
  	register int	*pw = pwlist;
  
  	while (pw <= &pwlist[pwc])
+ 	{
+ #if JOBS
+ 		j_child_clear(*pw);
+ #endif
  		*pw++ = 0;
  	}
  	pwc = 0;
***************
*** 274,279
  
  	while (pw <= &pwlist[pwc])
  		*pw++ = 0;
  	pwc = 0;
  }
  

--- 360,366 -----
  		j_child_clear(*pw);
  #endif
  		*pw++ = 0;
+ 	}
  	pwc = 0;
  }
  
***************
*** 285,291
  	if (pcsid)
  	{
  		while (*pw)
! 			pw++;
  		if (pwc >= MAXP - 1)
  			pw--;
  		else

--- 372,383 -----
  	if (pcsid)
  	{
  		while (*pw)
! #if JOBS
! 			if (pcsid == *pw)
! 				return;
! 			else
! #endif
! 				pw++;
  		if (pwc >= MAXP - 1)
  			pw--;
  		else
***************
*** 289,294
  		if (pwc >= MAXP - 1)
  			pw--;
  		else
  			pwc++;
  		*pw = pcsid;
  	}

--- 381,387 -----
  		if (pwc >= MAXP - 1)
  			pw--;
  		else
+ 		{
  			pwc++;
  #if JOBS
  			wf_pwc++;
***************
*** 290,295
  			pw--;
  		else
  			pwc++;
  		*pw = pcsid;
  	}
  }

--- 383,392 -----
  		else
  		{
  			pwc++;
+ #if JOBS
+ 			wf_pwc++;
+ #endif
+ 		}
  		*pw = pcsid;
  	}
  }
***************
*** 297,302
  await(i, bckg)
  int	i, bckg;
  {
  	int	rc = 0, wx = 0;
  	int	w;
  	int	ipwc = pwc;

--- 394,404 -----
  await(i, bckg)
  int	i, bckg;
  {
+ #if JOBS
+ #include	"/usr/include/sys/time.h"
+ #include	"/usr/include/sys/resource.h"
+ 	struct rusage	ru;
+ #endif
  	int	rc = 0, wx = 0;
  	int	w;
  	int	ipwc = pwc;
***************
*** 300,305
  	int	rc = 0, wx = 0;
  	int	w;
  	int	ipwc = pwc;
  
  	post(i);
  	while (pwc)

--- 402,409 -----
  	int	rc = 0, wx = 0;
  	int	w;
  	int	ipwc = pwc;
+ #if JOBS
+ 	BOOL	update_only = i == -2;
  
  	if (update_only)
  		i = -1;
***************
*** 301,307
  	int	w;
  	int	ipwc = pwc;
  
! 	post(i);
  	while (pwc)
  	{
  		register int	p;

--- 405,418 -----
  #if JOBS
  	BOOL	update_only = i == -2;
  
! 	if (update_only)
! 		i = -1;
! 	if ((flags&jobflg) == 0 || i != -1)
! #endif
! 		post(i);
! #if JOBS
! 	while (pwc || (flags&jobflg))
! #else
  	while (pwc)
  #endif
  	{
***************
*** 303,308
  
  	post(i);
  	while (pwc)
  	{
  		register int	p;
  		register int	sig;

--- 414,420 -----
  	while (pwc || (flags&jobflg))
  #else
  	while (pwc)
+ #endif
  	{
  		register int	p;
  		register int	sig;
***************
*** 310,315
  		int	found = 0;
  
  		{
  			register int	*pw = pwlist;
  
  			p = wait(&w);

--- 422,428 -----
  		int	found = 0;
  
  		{
+ #ifndef JOBS
  			register int	*pw = pwlist;
  #endif
  
***************
*** 311,316
  
  		{
  			register int	*pw = pwlist;
  
  			p = wait(&w);
  			if (wasintr)

--- 424,430 -----
  		{
  #ifndef JOBS
  			register int	*pw = pwlist;
+ #endif
  
  #if JOBS
  			if (i == 0 && (flags&jobflg) && wf_pwc == 0)
***************
*** 312,317
  		{
  			register int	*pw = pwlist;
  
  			p = wait(&w);
  			if (wasintr)
  			{

--- 426,447 -----
  			register int	*pw = pwlist;
  #endif
  
+ #if JOBS
+ 			if (i == 0 && (flags&jobflg) && wf_pwc == 0)
+ 				break;
+ 			if ((pwc == 0 && (flags&jobflg)) || update_only)
+ 			{
+ 				if ((p = wait3(&w, WUNTRACED|WNOHANG, &ru)) == 0)
+ 				{
+ 					unpost (i);
+ 					break;
+ 				}
+ 				if (pwc == 0 && p == -1)
+ 					break;
+ 			}
+ 			else
+ 				p = wait3(&w, WUNTRACED, &ru);
+ #else
  			p = wait(&w);
  #endif
  			if (wasintr)
***************
*** 313,318
  			register int	*pw = pwlist;
  
  			p = wait(&w);
  			if (wasintr)
  			{
  				wasintr = 0;

--- 443,449 -----
  				p = wait3(&w, WUNTRACED, &ru);
  #else
  			p = wait(&w);
+ #endif
  			if (wasintr)
  			{
  				wasintr = 0;
***************
*** 321,326
  					break;
  				}
  			}
  			while (pw <= &pwlist[ipwc])
  			{
  				if (*pw == p)

--- 452,462 -----
  					break;
  				}
  			}
+ 
+ #if JOBS
+ 			if (unpost(p))
+ 				found++;
+ #else
  			while (pw <= &pwlist[ipwc])
  			{
  				if (*pw == p)
***************
*** 332,337
  				else
  					pw++;
  			}
  		}
  		if (p == -1)
  		{

--- 468,474 -----
  				else
  					pw++;
  			}
+ #endif
  		}
  		if (p == -1)
  		{
***************
*** 337,342
  		{
  			if (bckg)
  			{
  				register int *pw = pwlist;
  
  				while (pw <= &pwlist[ipwc] && i != *pw)

--- 474,483 -----
  		{
  			if (bckg)
  			{
+ #if JOBS
+ 				j_child_clear(i);
+ 				unpost(i);
+ #else
  				register int *pw = pwlist;
  
  				while (pw <= &pwlist[ipwc] && i != *pw)
***************
*** 346,351
  					*pw = 0;
  					pwc--;
  				}
  			}
  			continue;
  		}

--- 487,493 -----
  					*pw = 0;
  					pwc--;
  				}
+ #endif
  			}
  			continue;
  		}
***************
*** 354,360
  		{
  			if (sig == 0177)	/* ptrace! return */
  			{
- 				prs("ptrace: ");
  				sig = w_hi;
  			}
  			if (sysmsg[sig])

--- 496,501 -----
  		{
  			if (sig == 0177)	/* ptrace! return */
  			{
  				sig = w_hi;
  #if JOBS
  				if ((flags&jobflg) &&
***************
*** 356,361
  			{
  				prs("ptrace: ");
  				sig = w_hi;
  			}
  			if (sysmsg[sig])
  			{

--- 497,512 -----
  			if (sig == 0177)	/* ptrace! return */
  			{
  				sig = w_hi;
+ #if JOBS
+ 				if ((flags&jobflg) &&
+ 					(sig == SIGSTOP || sig == SIGTSTP ||
+ 					 sig == SIGTTOU || sig == SIGTTIN))
+ 				{
+ 					j_child_stop(p, sig);
+ 					goto j_bypass;
+ 				}
+ #endif
+ 				prs("ptrace: ");
  			}
  			if (sysmsg[sig])
  			{
***************
*** 371,376
  			}
  			newline();
  		}
  		if (rc == 0 && found != 0)
  			rc = (sig ? sig | SIGFLG : w_hi);
  		wx |= w;

--- 522,558 -----
  			}
  			newline();
  		}
+ #if JOBS
+ 		if (flags&infoflg)
+ 		{
+ 			register int	k;
+ 			long		l;
+ 
+ 			prc('[');
+ 			l = ru.ru_utime.tv_sec * 1000000L + ru.ru_utime.tv_usec
+ 			  + ru.ru_stime.tv_sec * 1000000L + ru.ru_stime.tv_usec;
+ 			prn((int)(l / 1000000));	/* integral seconds */
+ 			k = (int)(l % 1000000L) / 1000;	/* thousandths */
+ 			prc('.');
+ 			if (k < 100)
+ 				prc('0');
+ 			if (k < 10)
+ 				prc('0');
+ 			prn(k);
+ 			blank();
+ 			prn((int)ru.ru_inblock);
+ 			blank();
+ 			prn((int)ru.ru_oublock);
+ 			blank();
+ 			prn((int)ru.ru_minflt);
+ 			blank();
+ 			prn((int)ru.ru_majflt);
+ 			prc(']');
+ 			newline();
+ 		}
+ 		j_child_die(p);
+ 	j_bypass:
+ #endif
  		if (rc == 0 && found != 0)
  			rc = (sig ? sig | SIGFLG : w_hi);
  		wx |= w;
:::::::: setbrk.c :::::::
No differences encountered
:::::::: sh.mk :::::::
*** ../orig.u/sh.mk	Wed May 15 17:08:30 1985
--- sh.mk	Wed May 29 16:28:26 1985
***************
*** 5,11
  ROOT=
  INS = /etc/install -n $(ROOT)/bin
  INSDIR =
! CFLAGS = -O -DNICE -DACCT -DNICEVAL=4
  LDFLAGS = -n -s
  
  OFILES = setbrk.o blok.o stak.o cmd.o fault.o main.o word.o string.o\

--- 5,11 -----
  ROOT=
  INS = /etc/install -n $(ROOT)/bin
  INSDIR =
! CFLAGS = -O -DNICE -DNICEVAL=4 -DJOBS
  LDFLAGS = -n -s
  
  OFILES = setbrk.o blok.o stak.o cmd.o fault.o main.o word.o string.o\
***************
*** 10,15
  
  OFILES = setbrk.o blok.o stak.o cmd.o fault.o main.o word.o string.o\
  name.o args.o xec.o service.o error.o io.o print.o macro.o expand.o\
  ctype.o msg.o test.o defs.o echo.o hash.o hashserv.o pwd.o func.o
  
  all: sh

--- 10,17 -----
  
  OFILES = setbrk.o blok.o stak.o cmd.o fault.o main.o word.o string.o\
  name.o args.o xec.o service.o error.o io.o print.o macro.o expand.o\
+ history.o homedir.o \
+ jobs.o signal.o ulimit.o \
  ctype.o msg.o test.o defs.o echo.o hash.o hashserv.o pwd.o func.o
  
  all: sh
***************
*** 20,34
  $(OFILES):	defs.h $(FRC)
  
  ctype.o:	ctype.h
! 		if [ "${_ID_}" ];\
! 		then \
! 			$(CC) $(CFLAGS) -c ctype.c; \
! 		elif [ "${_SH_}" ]; \
! 		then \
! 			CC=$(CC) AS=$(AS) $(_SH_) ./:fix ctype; \
! 		else \
! 			CC=$(CC) AS=$(AS) sh ./:fix ctype; \
! 		fi
  
  xec.o:		xec.c
  	set +e; if u370;\

--- 22,32 -----
  $(OFILES):	defs.h $(FRC)
  
  ctype.o:	ctype.h
! 		$(CC) $(CFLAGS) -S ctype.c
! 		sed '/^[ 	]*\.data/s/data/text/' < ctype.s > x.s
! 		mv x.s ctype.s
! 		$(AS) ctype.s -o ctype.o
! 		rm ctype.s
  
  xec.o:		xec.c
  	set +e; if u370;\
***************
*** 55,69
  
  
  msg.o:		msg.c $(FRC)
! 		if [ "${_ID_}" ];\
! 		then \
! 			$(CC) $(CFLAGS) -c msg.c; \
! 		elif [ "${_SH_}" ]; \
! 		then \
! 			CC=$(CC) AS=$(AS) $(_SH_) ./:fix msg; \
! 		else \
! 			CC=$(CC) AS=$(AS) sh ./:fix msg; \
! 		fi
  
  test:
  	  rtest $(TESTDIR)/sh

--- 53,63 -----
  
  
  msg.o:		msg.c $(FRC)
! 		$(CC) $(CFLAGS) -S msg.c
! 		sed '/^[ 	]*\.data/s/data/text/' < msg.s > x.s
! 		mv x.s msg.s
! 		$(AS) msg.s -o msg.o
! 		rm msg.s
  
  test:
  	  rtest $(TESTDIR)/sh
:::::::: stak.c :::::::
No differences encountered
:::::::: stak.h :::::::
No differences encountered
:::::::: string.c :::::::
No differences encountered
:::::::: sym.h :::::::
*** ../orig.u/sym.h	Wed May 15 17:08:32 1985
--- sym.h	Sun May 19 16:37:20 1985
***************
*** 45,47
  #define ESCAPE	'\\'
  #define BRACE	'{'
  #define COMCHAR '#'

--- 45,48 -----
  #define ESCAPE	'\\'
  #define BRACE	'{'
  #define COMCHAR '#'
+ #define PERCENT '%'	/* DAG -- useful addition */
:::::::: test.c :::::::
*** ../orig.u/test.c	Wed May 15 17:08:33 1985
--- test.c	Mon May 20 15:57:01 1985
***************
*** 126,131
  		if (eq(a, "-k"))
  			return(ftype(nxtarg(0), S_ISVTX));
  		if (eq(a, "-p"))
  			return(filtyp(nxtarg(0),S_IFIFO));
     		if (eq(a, "-s"))
  			return(fsizep(nxtarg(0)));

--- 126,134 -----
  		if (eq(a, "-k"))
  			return(ftype(nxtarg(0), S_ISVTX));
  		if (eq(a, "-p"))
+ #if JOBS && !defined(pyr)
+ #define	S_IFIFO		S_IFSOCK	/* fifo - map to socket on 4.2BSD */
+ #endif
  			return(filtyp(nxtarg(0),S_IFIFO));
     		if (eq(a, "-s"))
  			return(fsizep(nxtarg(0)));
:::::::: timeout.h :::::::
No differences encountered
:::::::: word.c :::::::
*** ../orig.u/word.c	Wed May 15 17:08:34 1985
--- word.c	Thu Jun  6 14:37:41 1985
***************
*** 19,24
  	struct argnod	*arg = (struct argnod *)locstak();
  	register char	*argp = arg->argval;
  	int		alpha = 1;
  
  	wdnum = 0;
  	wdset = 0;

--- 19,25 -----
  	struct argnod	*arg = (struct argnod *)locstak();
  	register char	*argp = arg->argval;
  	int		alpha = 1;
+ 	char		*save;
  
  	wdnum = 0;
  	wdset = 0;
***************
*** 23,28
  	wdnum = 0;
  	wdset = 0;
  
  	while (1)
  	{
  		while (c = nextc(0), space(c))		/* skipc() */

--- 24,30 -----
  	wdnum = 0;
  	wdset = 0;
  
+ 	catcheof = TRUE;
  	while (1)
  	{
  		while (c = nextc(0), space(c))		/* skipc() */
***************
*** 38,43
  			break;	/* out of comment - white space loop */
  		}
  	}
  	if (!eofmeta(c))
  	{
  		do

--- 40,46 -----
  			break;	/* out of comment - white space loop */
  		}
  	}
+ 	save = argp;	/* save start of word */
  	if (!eofmeta(c))
  	{
  		do
***************
*** 69,74
  							chkpr();
  					}
  				}
  			}
  		} while ((c = nextc(0), !eofmeta(c)));
  		argp = endstak(argp);

--- 72,93 -----
  							chkpr();
  					}
  				}
+ 				else if (c == SQUIGGLE &&
+ 						validtilde (save, argp))
+ 				{
+ 					char *name, *home;
+ 
+ 					name = argp;
+ 					while ((c = nextc(0)) != '/' &&
+ 							!eofmeta(c))
+ 						*name++ = c;
+ 					peekc = c;
+ 					*name = '\0';
+ 					home = homedir (argp);
+ 					if(*home)
+ 						movstr (home, --argp);
+ 					argp += length (argp) - 1;
+ 				}
  			}
  		} while ((c = nextc(0), !eofmeta(c)));
  		argp = endstak(argp);
***************
*** 117,122
  			wdval = EOFSYM;
  		if (iopend && eolchar(c))
  		{
  			copy(iopend);
  			iopend = 0;
  		}

--- 136,144 -----
  			wdval = EOFSYM;
  		if (iopend && eolchar(c))
  		{
+ 			int histon = (flags&nohistflg) == 0;
+ 
+ 			flags |= nohistflg;	/* no history for here docs */
  			copy(iopend);
  			if (histon)		/* turn history back on */
  				flags &= ~nohistflg;
***************
*** 118,123
  		if (iopend && eolchar(c))
  		{
  			copy(iopend);
  			iopend = 0;
  		}
  	}

--- 140,147 -----
  
  			flags |= nohistflg;	/* no history for here docs */
  			copy(iopend);
+ 			if (histon)		/* turn history back on */
+ 				flags &= ~nohistflg;
  			iopend = 0;
  		}
  	}
***************
*** 121,126
  			iopend = 0;
  		}
  	}
  	reserv = FALSE;
  	return(wdval);
  }

--- 145,151 -----
  			iopend = 0;
  		}
  	}
+ 	catcheof = FALSE;
  	reserv = FALSE;
  	return(wdval);
  }
***************
*** 157,162
  
  readc()
  {
  	register char	c;
  	register int	len;
  	register struct fileblk *f;

--- 182,188 -----
  
  readc()
  {
+ 	static int	eofcount = 0;	/* to break endless catcheof loop */
  	register char	c;
  	register int	len;
  	register struct fileblk *f;
***************
*** 200,209
  	}
  	else if ((len = readb()) <= 0)
  	{
! 		close(f->fdes);
! 		f->fdes = -1;
! 		c = EOF;
! 		f->feof++;
  	}
  	else
  	{

--- 226,260 -----
  	}
  	else if ((len = readb()) <= 0)
  	{
! 		if (catcheof
! #if JOBS
! 		 && (flags&(ttyflg|prompt|dotflg)) == (ttyflg|prompt)
! 		 && ((flags&noeotflg) || j_finish(FALSE))
! #else
! 		 && (flags&(ttyflg|prompt|noeotflg|dotflg)) == (ttyflg|prompt|noeotflg)
! #endif
! 		 && ++eofcount < 10)	/* in case terminal is disconnected */
! 		{
! #if JOBS
! 			if ((flags&(ttyflg|prompt|noeotflg))
! 			 == (ttyflg|prompt|noeotflg))
! #endif
! 				prs ("use \"exit\"\n");
! #if JOBS
! 			/* else "there are stopped jobs" was printed */
! #endif
! 			c = NL;
! 		}
! 		else
! 		{
! 			close(f->fdes);
! 			f->fdes = -1;
! 			c = EOF;
! 			f->feof++;
! #if JOBS
! 			j_finish(TRUE);
! #endif
! 		}
  	}
  	else
  	{
***************
*** 207,213
  	}
  	else
  	{
! 		f->fend = (f->fnxt = f->fbuf) + len;
  		goto retry;
  	}
  	return(c);

--- 258,265 -----
  	}
  	else
  	{
! 		f->fend = f->fnxt + len;
! 		eofcount = 0;
  		goto retry;
  	}
  	return(c);
***************
*** 214,220
  }
  
  static
! readb()
  {
  	register struct fileblk *f = standin;
  	register int	len;

--- 266,272 -----
  }
  
  static
! readblock ()	/* ADR -- changed the name */
  {
  	register struct fileblk *f = standin;
  	register int	len;
***************
*** 234,237
  		}
  	} while ((len = read(f->fdes, f->fbuf, f->fsiz)) < 0 && trapnote);
  	return(len);
  }

--- 286,486 -----
  		}
  	} while ((len = read(f->fdes, f->fbuf, f->fsiz)) < 0 && trapnote);
  	return(len);
+ }
+ 
+ /* readb --- read a block from the outside world, and history process it */
+ 
+ /*
+  * In BSD systems, using the literal next capability of the tty driver, it
+  * is actually possible to put a newline in the middle of the input line,
+  * and then hit return, so that the shell sees two lines of input.
+  *
+  * As a design decision, if there is a \n in the middle of what we've read
+  * from a terminal, treat the commands as two separately typed commands. I.e.
+  *
+  *	echo hi ^J echo there
+  *
+  * is the same as
+  *
+  *	echo hi
+  *	echo there
+  *
+  * The major reason for doing it this way is that the history mechanism knows
+  * that a \n is the end of a line.
+  *
+  * Finally, on USG systems, we just leave this code alone, since it won't
+  * get executed anyway.
+  */
+ 
+ /*
+  * In word.c, the readc() function keeps a pointer to what standin pointed to
+  * when readc first gets called.  Therefore, where standin points to can not 
+  * not change across calls to readb().  To get around this, we change the
+  * contents of the structure pointed to by standin, saving and restoring
+  * it as necessary.
+  */
+ 
+ #define LARGEBUF	(HISTSIZE / 2)	/* size of expanded history */
+ 
+ static
+ readb()
+ {
+ 	int ilen, i, j;
+ 	char ibuf[BUFSIZ];	/* input into scratch area, pass to history */
+ 	static char expansion[LARGEBUF];
+ 	static int moreinbuf = FALSE;
+ 	static int saved_ilen = 0;
+ 	static int start_here = 0;
+ 	static struct fileblk *f = 0;
+ 	auto int gotoutofbuf = 0;
+ 
+ 	if (expanded)	/* just did a history substitution */
+ 		expanded = 0;
+ 
+ 	if ((flags & nohistflg) || (flags & prompt) == 0 || ! isatty (input)
+ 			|| standin->fstak != 0)
+ 	{
+ 		ilen = readblock ();
+ 		if (ilen > 0)
+ 			standin->fnxt = standin->fbuf;
+ 		return (ilen);
+ 		/* not doing history expansion at all */
+ 	}
+ 
+ 	if (f == 0)
+ 		f = standin;
+ 
+ 	ilen = 0;
+ 
+ 	/*
+ 	 * First, if there was more stuff in the last buffer, go and get it.
+ 	 * If not get some more from the outside world.
+ 	 *
+ 	 * Then, make sure we've read up to a newline.
+ 	 * This is basically in case someone has done something bizarre
+ 	 * like 'stty raw', and input is coming in one character at a time.
+ 	 *
+ 	 * We use a heuristic.  If amount read is just 1, keep reading till
+ 	 * we get a newline.  Else, read in a complete line from the terminal.
+ 	 * Once we're in raw mode, can't reset it until a newline is typed.
+ 	 *
+ 	 * If not reading one character at a time, then do the stuff for
+ 	 * embedded newlines.
+ 	 */
+ 
+ 	if (moreinbuf)
+ 	{
+ 		for (i = 0, j = start_here; f->fbuf[j] != NL && j < saved_ilen; i++, j++)
+ 			ibuf[i] = f->fbuf[j];
+ 
+ #ifdef notdef
+ 		if (f->fbuf[j] != NL)
+ 		{
+ 			prs ("internal i/o error C in readb\n");
+ 			return (0);
+ 		}
+ #endif
+ 
+ 		if (f->fbuf[j] == NL)
+ 			ibuf[i++] = NL;
+ 		ibuf[i] = '\0';
+ 		ilen = i;
+ 		/* embedded newline */
+ 		moreinbuf = (++j < saved_ilen - 1);
+ 		if (moreinbuf)
+ 			start_here = j;	/* where to start next time */
+ 		gotoutofbuf = 1;
+ 	}
+ 	else	/* wasn't an embedded \n last time */
+ 	{
+ 		ilen = readblock ();
+ 	
+ 		if (ilen <= 0)	/* EOF or error */
+ 			return (ilen);
+ 
+ 		if (ilen == 1)	/* either in raw mode, or an empty line */
+ 		{
+ 			i = 0;
+ 			ibuf[i++] = f->fbuf[0];
+ 			if (f->fbuf[0] == NL)
+ 			{
+ 				ibuf[i] = '\0';
+ 				goto dohist;
+ 			}
+ 
+ 			while ((ilen = readblock()) > 0)
+ 			{
+ 				if (ilen != 1)
+ 				{
+ 					prs ("internal i/o error A in readb\n");
+ 					return (0);
+ 				}
+ 				ibuf[i++] = f->fbuf[0];
+ 				if (f->fbuf[0] == NL)
+ 				{
+ 					ibuf[i] = '\0';
+ 					break;	/* while */
+ 				}
+ 			}
+ 			ilen = i;
+ 			gotoutofbuf = TRUE;
+ 			/* force code below to use collected string */
+ 		}
+ 		else
+ 		{
+ 			/* reading bunches of characters at once */
+ 			for (i = 0; f->fbuf[i] != NL && i < ilen; i++)
+ 				ibuf[i] = f->fbuf[i];
+ 
+ #ifdef notdef
+ 			if (f->fbuf[i] != NL)
+ 			{
+ 				prs ("internal i/o error B in readb\n");
+ 				return (0);
+ 			}
+ #endif
+ 
+ 			ibuf[i++] = NL;
+ 			ibuf[i] = '\0';
+ 			/* ilen was set by readblock() */
+ 			/* embedded newline */
+ 			moreinbuf = (i < ilen - 1);
+ 			if (moreinbuf)
+ 			{
+ 				saved_ilen = ilen;
+ 				start_here = i;
+ 				/* where to start next time */
+ 				gotoutofbuf = 1;
+ 			}
+ 		}
+ 	}
+ 
+ dohist:
+ 	/* quick heuristic */
+ 	if (! gotoutofbuf && ilen == 1 && f->fbuf[0] == NL)
+ 	{
+ 		f->fnxt = f->fbuf;
+ 		return (ilen);
+ 	}
+ 
+ 	if (histsub (ibuf, expansion, sizeof expansion))
+ 	{
+ 		int olen = length (expansion) - 1;
+ 		if (! expanded && ! gotoutofbuf)
+ 		{
+ 			standin->fnxt = standin->fbuf;
+ 			return (ilen);
+ 		}
+ 		/* else
+ 			expanded == TRUE or from buffer */
+ 		standin->fnxt = expansion;
+ 		return (olen);
+ 	}
+ 	else
+ 	{
+ 		/* hist expansion failed, return an empty line */
+ 		standin->fnxt = standin->fbuf;
+ 		standin->fbuf[0] = NL;
+ 		return (1);
+ 	}
  }
:::::::: xec.c :::::::
*** ../orig.u/xec.c	Wed May 15 17:08:37 1985
--- xec.c	Wed Jun  5 11:11:18 1985
***************
*** 27,32
  	 */
  	register struct trenod	*t;
  	char		*sav = savstak();
  
  	sigchk();
  	if (!errorflg)

--- 27,42 -----
  	 */
  	register struct trenod	*t;
  	char		*sav = savstak();
+ #if pyr
+ 	auto int change_univ = FALSE;
+ 	auto int new_univ = 0;
+ 	/*
+ 	 * univesrses run from 1 to NUMUNIV: We start out at 0
+ 	 * and increment new_univ in the switch for internal
+ 	 * commands, below.  new_univ must *not* be assigned to, directly
+ 	 * or via side effects, any place else.
+ 	 */
+ #endif
  
  	sigchk();
  	if (!errorflg)
***************
*** 109,114
  					if (flags & execpr)
  						execprint(com);
  
  					if (comtype == NOTFOUND)
  					{
  						pos = hashdata(cmdhash);

--- 119,130 -----
  					if (flags & execpr)
  						execprint(com);
  
+ 					/*
+ 					 * fix a bug which caused the shell
+ 					 * to do not do a second command if
+ 					 * the first was not found. (bug fix
+ 					 * from USENET)
+ 					 */
  					if (comtype == NOTFOUND)
  					{
  						char *errstr;
***************
*** 111,116
  
  					if (comtype == NOTFOUND)
  					{
  						pos = hashdata(cmdhash);
  						if (pos == 1)
  							failed(*com, notfound);

--- 127,134 -----
  					 */
  					if (comtype == NOTFOUND)
  					{
+ 						char *errstr;
+ 
  						pos = hashdata(cmdhash);
  						if (pos == 1)
  							errstr = notfound;
***************
*** 113,119
  					{
  						pos = hashdata(cmdhash);
  						if (pos == 1)
! 							failed(*com, notfound);
  						else if (pos == 2)
  							failed(*com, badexec);
  						else

--- 131,137 -----
  
  						pos = hashdata(cmdhash);
  						if (pos == 1)
! 							errstr = notfound;
  						else if (pos == 2)
  							errstr = badexec;
  						else
***************
*** 115,121
  						if (pos == 1)
  							failed(*com, notfound);
  						else if (pos == 2)
! 							failed(*com, badexec);
  						else
  							failed(*com, badperm);
  						break;

--- 133,139 -----
  						if (pos == 1)
  							errstr = notfound;
  						else if (pos == 2)
! 							errstr = badexec;
  						else
  							errstr = badperm;
  						prp();
***************
*** 117,123
  						else if (pos == 2)
  							failed(*com, badexec);
  						else
! 							failed(*com, badperm);
  						break;
  					}
  

--- 135,147 -----
  						else if (pos == 2)
  							errstr = badexec;
  						else
! 							errstr = badperm;
! 						prp();
! 						prs_cntl(*com);
! 						prs (colon);
! 						prs (errstr);
! 						newline();
! 						exitval = 1;
  						break;
  					}
  
***************
*** 148,153
  								if ((f = pathopen(getpath(a1), a1)) < 0)	
  									failed(a1, notfound);	
  								else	
  									execexp(0, f);	
  							}	
  							break;	

--- 172,181 -----
  								if ((f = pathopen(getpath(a1), a1)) < 0)	
  									failed(a1, notfound);	
  								else	
+ 								{
+ 									int	savedot = flags&dotflg;
+ 
+ 									flags |= dotflg;
  									execexp(0, f);	
  									flags &= ~dotflg;
  									flags |= savedot;
***************
*** 149,154
  									failed(a1, notfound);	
  								else	
  									execexp(0, f);	
  							}	
  							break;	
  				

--- 177,185 -----
  
  									flags |= dotflg;
  									execexp(0, f);	
+ 									flags &= ~dotflg;
+ 									flags |= savedot;
+ 								}
  							}	
  							break;	
  				
***************
*** 163,169
  								prc_buff(NL);	
  							}	
  							break;	
! 				
  						case SYSEXIT:	
  							flags |= forked;	/* force exit */	
  							exitsh(a1 ? stoi(a1) : retval);

--- 194,200 -----
  								prc_buff(NL);	
  							}	
  							break;	
! 
  						case SYSEXIT:	
  #if JOBS
  							if (j_finish(FALSE))
***************
*** 165,170
  							break;	
  				
  						case SYSEXIT:	
  							flags |= forked;	/* force exit */	
  							exitsh(a1 ? stoi(a1) : retval);
  				

--- 196,207 -----
  							break;	
  
  						case SYSEXIT:	
+ #if JOBS
+ 							if (j_finish(FALSE))
+ 								break;
+ #endif
+ 							histsave (histfnod.namval);
+ 							/* save before setting flag */
  							flags |= forked;	/* force exit */	
  
  							exitsh(a1 ? stoi(a1) : retval);
***************
*** 166,171
  				
  						case SYSEXIT:	
  							flags |= forked;	/* force exit */	
  							exitsh(a1 ? stoi(a1) : retval);
  				
  						case SYSNULL:	

--- 203,209 -----
  							histsave (histfnod.namval);
  							/* save before setting flag */
  							flags |= forked;	/* force exit */	
+ 
  							exitsh(a1 ? stoi(a1) : retval);
  				
  						case SYSNULL:	
***************
*** 248,256
  							}	
  		
  #ifdef RES	/* Research includes login as part of the shell */	
! 		
! 						case SYSLOGIN:	
! 							oldsigs();	
  							execa(com, -1);
  							done();	
  #else	

--- 286,296 -----
  							}	
  		
  #ifdef RES	/* Research includes login as part of the shell */	
! 
! 						case SYSLOGIN:
! 							histsave (histfnod.namval);
! 							flags |= forked;	/* DAG -- bug fix (force bad exec to terminate shell) */
! 							oldsigs();
  							execa(com, -1);
  							done();
  #else
***************
*** 252,260
  						case SYSLOGIN:	
  							oldsigs();	
  							execa(com, -1);
! 							done();	
! #else	
! 			
  						case SYSNEWGRP:	
  							if (flags & rshflg)	
  								failed(com[0], restricted);	

--- 292,299 -----
  							flags |= forked;	/* DAG -- bug fix (force bad exec to terminate shell) */
  							oldsigs();
  							execa(com, -1);
! 							done();
! #else
  						case SYSNEWGRP:	
  							if (flags & rshflg)	
  								failed(com[0], restricted);	
***************
*** 260,265
  								failed(com[0], restricted);	
  							else	
  							{	
  								flags |= forked;	/* force bad exec to terminate shell */	
  								oldsigs();	
  								execa(com, -1);

--- 299,305 -----
  								failed(com[0], restricted);	
  							else	
  							{	
+ 								histsave (histfnod.namval);
  								flags |= forked;	/* force bad exec to terminate shell */	
  								oldsigs();	
  								execa(com, -1);
***************
*** 266,272
  								done();	
  							}	
  		
! #endif	
  		
  						case SYSCD:	
  							if (flags & rshflg)	

--- 306,312 -----
  								done();	
  							}	
  		
! #endif
  		
  						case SYSCD:	
  							if (flags & rshflg)	
***************
*** 273,278
  								failed(com[0], restricted);	
  							else if ((a1 && *a1) || (a1 == 0 && (a1 = homenod.namval)))	
  							{	
  								char *cdpath;	
  								char *dir;	
  								int f;	

--- 313,319 -----
  								failed(com[0], restricted);	
  							else if ((a1 && *a1) || (a1 == 0 && (a1 = homenod.namval)))	
  							{	
+ 								register char *safe;	/* DAG -- added (see note, below) */
  								char *cdpath;	
  								char *dir;	
  								int f;	
***************
*** 279,286
  		
  								if ((cdpath = cdpnod.namval) == 0 ||	
  								     *a1 == '/' ||	
! 								     cf(a1, ".") == 0 ||	
! 								     cf(a1, "..") == 0 ||	
  								     (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/')))	
  									cdpath = nullstr;	
  		

--- 320,327 -----
  		
  								if ((cdpath = cdpnod.namval) == 0 ||	
  								     *a1 == '/' ||	
! 								     cf(a1, ".") == 0 ||
! 								     cf(a1, "..") == 0 ||
  								     (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/')))	
  									cdpath = nullstr;	
  		
***************
*** 284,289
  								     (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/')))	
  									cdpath = nullstr;	
  		
  								do	
  								{	
  									dir = cdpath;	

--- 325,337 -----
  								     (*a1 == '.' && (*(a1+1) == '/' || *(a1+1) == '.' && *(a1+2) == '/')))	
  									cdpath = nullstr;	
  		
+ /* DAG -- catpath() leaves the trial directory above the top of the "stack".
+ 	This is too dangerous; systems using directory access routines may
+ 	alloc() storage and clobber the string.  Therefore I have changed the
+ 	code to alloc() a safe place to put the trial strings.  Most of the
+ 	changes involved replacing "curstak()" with "safe".
+ */								safe = alloc((unsigned)(length(cdpath) + length(a1)));	/* DAG -- added */
+ 
  								do	
  								{	
  									dir = cdpath;	
***************
*** 288,293
  								{	
  									dir = cdpath;	
  									cdpath = catpath(cdpath,a1);	
  								}	
  								while ((f = (chdir(curstak()) < 0)) && cdpath);
  		

--- 336,342 -----
  								{	
  									dir = cdpath;	
  									cdpath = catpath(cdpath,a1);	
+ 									(void)movstr(curstak(),safe);	/* DAG -- added (see note, above) */
  								}	
  #if !defined(SYMLINK) && defined(JOBS)
  								while ((f = (cwdir(safe) < 0)) && cdpath);	/* DAG */
***************
*** 289,295
  									dir = cdpath;	
  									cdpath = catpath(cdpath,a1);	
  								}	
! 								while ((f = (chdir(curstak()) < 0)) && cdpath);
  		
  								if (f)	
  									failed(a1, baddir);	

--- 338,348 -----
  									cdpath = catpath(cdpath,a1);	
  									(void)movstr(curstak(),safe);	/* DAG -- added (see note, above) */
  								}	
! #if !defined(SYMLINK) && defined(JOBS)
! 								while ((f = (cwdir(safe) < 0)) && cdpath);	/* DAG */
! #else
! 								while ((f = (chdir(safe) < 0)) && cdpath);	/* DAG */
! #endif
  		
  								if (f)	
  								{
***************
*** 292,297
  								while ((f = (chdir(curstak()) < 0)) && cdpath);
  		
  								if (f)	
  									failed(a1, baddir);	
  								else 
  								{

--- 345,352 -----
  #endif
  		
  								if (f)	
+ 								{
+ 									free(safe);	/* DAG -- added (see note, above) */
  									failed(a1, baddir);	
  								}
  								else 
***************
*** 293,298
  		
  								if (f)	
  									failed(a1, baddir);	
  								else 
  								{
  									cwd(curstak());

--- 348,354 -----
  								{
  									free(safe);	/* DAG -- added (see note, above) */
  									failed(a1, baddir);	
+ 								}
  								else 
  								{
  #if defined(SYMLINK) || !defined(JOBS)
***************
*** 295,301
  									failed(a1, baddir);	
  								else 
  								{
! 									cwd(curstak());
  									if (cf(nullstr, dir) &&	
  									    *dir != ':' &&	
  									 	any('/', curstak()) &&	

--- 351,359 -----
  								}
  								else 
  								{
! #if defined(SYMLINK) || !defined(JOBS)
! 									cwd(safe);	/* DAG */
! #endif
  									if (cf(nullstr, dir) &&	
  									    *dir != ':' &&	
  									 	any('/', safe) &&	/* DAG */
***************
*** 298,304
  									cwd(curstak());
  									if (cf(nullstr, dir) &&	
  									    *dir != ':' &&	
! 									 	any('/', curstak()) &&	
  									 	flags & prompt)	
  									{	
  										prs_buff(curstak());	

--- 356,362 -----
  #endif
  									if (cf(nullstr, dir) &&	
  									    *dir != ':' &&	
! 									 	any('/', safe) &&	/* DAG */
  									 	flags & prompt)	
  										cwdprint();	/* DAG -- improvement */
  									free(safe);	/* DAG -- added (see note, above) */
***************
*** 300,309
  									    *dir != ':' &&	
  									 	any('/', curstak()) &&	
  									 	flags & prompt)	
! 									{	
! 										prs_buff(curstak());	
! 										prc_buff(NL);	
! 									}
  								}
  								zapcd();
  							}	

--- 358,365 -----
  									    *dir != ':' &&	
  									 	any('/', safe) &&	/* DAG */
  									 	flags & prompt)	
! 										cwdprint();	/* DAG -- improvement */
! 									free(safe);	/* DAG -- added (see note, above) */
  								}
  								zapcd();
  							}	
***************
*** 452,458
  								if (command == 1 || command == 4)	
  								{	
  									prl(i);	
! 									prc_buff('\n');	
  								}	
  								break;	
  							}				

--- 508,514 -----
  								if (command == 1 || command == 4)	
  								{	
  									prl(i);	
! 									prc_buff(NL);	
  								}	
  								break;	
  							}				
***************
*** 478,486
  								prc_buff(NL);	
  							}	
  							break;	
! 		
! #endif	
! 		
  						case SYSTST:
  							exitval = test(argn, com);
  							break;

--- 534,540 -----
  								prc_buff(NL);	
  							}	
  							break;	
! 
  						case SYSTST:
  							exitval = test(argn, com);
  							break;
***************
*** 484,489
  						case SYSTST:
  							exitval = test(argn, com);
  							break;
  
  						case SYSECHO:
  							exitval = echo(argn, com);

--- 538,544 -----
  						case SYSTST:
  							exitval = test(argn, com);
  							break;
+ #endif	/* RES (DAG -- bug fix: SYSTST not in RES) */
  
  						case SYSECHO:
  							exitval = echo(argn, com);
***************
*** 548,553
  							}
  							break;
  
  						default:	
  							prs_buff("unknown builtin\n");
  						}	

--- 603,675 -----
  							}
  							break;
  
+ #if JOBS
+ 						case SYSJOBS:
+ 
+ 							j_print();
+ 							break;
+ 
+ 						case SYSFG:
+ 
+ 							j_resume(a1, FALSE);
+ 							break;
+ 
+ 						case SYSBG:
+ 
+ 							j_resume(a1, TRUE);
+ 							break;
+ 
+ 						case SYSSUSPEND:
+ 							exitval = 1;
+ 							if (getppid() == 1)
+ 								prs ("cannot suspend a login shell\n");	/* yet ... */
+ 							else
+ 							{
+ 								exitval = 0;
+ 								kill (getpid(), SIGSTOP);
+ 							}
+ 							break;
+ #endif
+ 
+ #if pyr
+ 						/*
+ 						 * UCB is Universe 2
+ 						 * ATT is Universe 1
+ 						 * new_univ == 0
+ 						 */
+ 						case SYSUCB:
+ 							new_univ++;
+ 							/* fall thru */
+ 						case SYSATT:
+ 							new_univ++;
+ 							if (argn > 1)
+ 							{
+ 								change_univ = TRUE;
+ 								com++;
+ 								goto doit;
+ 							}
+ 							else
+ 							{
+ 								setuniverse (cur_univ = new_univ);
+ 								univnod.namflg &= ~N_RDONLY;
+ 								assign (& univnod, univ_name[cur_univ - 1]);
+ 								attrib ((& univnod), N_RDONLY);
+ 								break;
+ 							}
+ 						
+ 						case SYSUNIVERSE:
+ 							if (eq(com[1], "-l"))
+ 								prs_buff (univ_longname[cur_univ - 1]);
+ 							else
+ 								prs_buff (univ_name[cur_univ - 1]);
+ 							prc_buff (NL);
+ 							break;
+ #endif
+ 
+ 						case SYSHISTORY:
+ 							exitval = history (argn, com);
+ 							break;
+ 
  						default:	
  							prs_buff("unknown builtin\n");
  						}	
***************
*** 586,591
  			}
  
  		case TFORK:
  			exitval = 0;
  			if (execflg && (treeflgs & (FAMP | FPOU)) == 0)
  				parent = 0;

--- 708,716 -----
  			}
  
  		case TFORK:
+ #if pyr
+ 		doit:
+ #endif
  			exitval = 0;
  			if (execflg && (treeflgs & (FAMP | FPOU)) == 0)
  				parent = 0;
***************
*** 625,630
  					alarm(forkcnt);
  					pause(); 
  				}
  			}
  			if (parent)
  			{

--- 750,759 -----
  					alarm(forkcnt);
  					pause(); 
  				}
+ #if JOBS
+ 				if (parent == 0)
+ 					j_top_level = FALSE;
+ #endif
  			}
  			if (parent)
  			{
***************
*** 633,638
  				 * it may or may not wait for the child
  				 */
  				if (treeflgs & FPRS && flags & ttyflg)
  				{
  					prn(parent);
  					newline();

--- 762,770 -----
  				 * it may or may not wait for the child
  				 */
  				if (treeflgs & FPRS && flags & ttyflg)
+ #if JOBS
+ 				if ((flags&jobflg) == 0)
+ #endif
  				{
  					prn(parent);
  					newline();
***************
*** 639,644
  				}
  				if (treeflgs & FPCL)
  					closepipe(pf1);
  				if ((treeflgs & (FAMP | FPOU)) == 0)
  					await(parent, 0);
  				else if ((treeflgs & FAMP) == 0)

--- 771,779 -----
  				}
  				if (treeflgs & FPCL)
  					closepipe(pf1);
+ #if JOBS
+ 				j_child_post(parent, treeflgs&FAMP, treeflgs&FPIN, t);
+ #endif
  				if ((treeflgs & (FAMP | FPOU)) == 0)
  				{
  					await(parent, 0);
***************
*** 640,645
  				if (treeflgs & FPCL)
  					closepipe(pf1);
  				if ((treeflgs & (FAMP | FPOU)) == 0)
  					await(parent, 0);
  				else if ((treeflgs & FAMP) == 0)
  					post(parent);

--- 775,781 -----
  				j_child_post(parent, treeflgs&FAMP, treeflgs&FPIN, t);
  #endif
  				if ((treeflgs & (FAMP | FPOU)) == 0)
+ 				{
  					await(parent, 0);
  #if JOBS
  					j_reset_pg();
***************
*** 641,646
  					closepipe(pf1);
  				if ((treeflgs & (FAMP | FPOU)) == 0)
  					await(parent, 0);
  				else if ((treeflgs & FAMP) == 0)
  					post(parent);
  				else

--- 777,786 -----
  				if ((treeflgs & (FAMP | FPOU)) == 0)
  				{
  					await(parent, 0);
+ #if JOBS
+ 					j_reset_pg();
+ #endif
+ 				}
  				else if ((treeflgs & FAMP) == 0)
  					post(parent);
  				else
***************
*** 650,655
  			}
  			else	/* this is the forked branch (child) of execute */
  			{
  				flags |= forked;
  				fiotemp  = 0;
  

--- 790,805 -----
  			}
  			else	/* this is the forked branch (child) of execute */
  			{
+ #if pyr
+ 				if (change_univ)
+ 				{
+ 					setuniverse (new_univ);
+ 					univnod.namflg &= ~N_RDONLY;
+ 					assign (& univnod, univ_name[cur_univ - 1]);
+ 					attrib ((& univnod), N_RDONLY);
+ 				}
+ #endif
+ 
  				flags |= forked;
  				fiotemp  = 0;
  
***************
*** 674,679
  				 */
  				oldsigs();
  				if (treeflgs & FINT)
  				{
  					signal(SIGINT, 1);
  					signal(SIGQUIT, 1);

--- 824,832 -----
  				 */
  				oldsigs();
  				if (treeflgs & FINT)
+ #if JOBS
+ 				if ((flags&jobflg) == 0)
+ #endif
  				{
  					signal(SIGINT, SIG_IGN);	/* DAG */
  					signal(SIGQUIT, SIG_IGN);	/* DAG */
***************
*** 675,682
  				oldsigs();
  				if (treeflgs & FINT)
  				{
! 					signal(SIGINT, 1);
! 					signal(SIGQUIT, 1);
  
  #ifdef NICE
  					nice(NICEVAL);

--- 828,835 -----
  				if ((flags&jobflg) == 0)
  #endif
  				{
! 					signal(SIGINT, SIG_IGN);	/* DAG */
! 					signal(SIGQUIT, SIG_IGN);	/* DAG */
  
  #ifdef NICE
  					nice(NICEVAL);
***************
*** 700,705
  				 * default std input for &
  				 */
  				if (treeflgs & FINT && ioset == 0)
  					rename(chkopen(devnull), 0);
  				/*
  				 * io redirection

--- 853,861 -----
  				 * default std input for &
  				 */
  				if (treeflgs & FINT && ioset == 0)
+ #if JOBS
+ 				if ((flags&jobflg) == 0)
+ #endif
  					rename(chkopen(devnull), 0);
  				/*
  				 * io redirection



More information about the Mod.sources mailing list