Subject: fchdir(2) is missing from 2.11BSD (#187)
Index:	sys/ufs_syscalls.c,lib/libc/pdp/sys/fchdir.s 2.11BSD

Description:
	The file descriptor counterpart to 'chdir(2)' is missing from
	2.11BSD.  There is a 'fchmod(2)' to go along with 'chmod(2)',
	a 'fchown(2)' to match 'chown(2)' and so on but no 'fchdir(2)'
	to correspond to 'chdir(2)'.

Repeat-By:
	Observation.

	Another way is to attempt to port a program which uses 'fchdir'
	to 2.11 and notice the undefined symbol message from the linker.

Fix:
	Apply the patches below.  A kernel rebuild and reboot is necessary
	before using the syscall added to libc.a

	Detailed instructions follow the explanatory notes.

	The following file is added to the system (when the shar file is
	unpacked):
		
		/usr/src/lib/libc/pdp/sys/fchdir.s

	The following files are modified by the patch kit:

		/usr/include/syscall.h
		/usr/src/sys/sys/init_sysent.c
		/usr/src/sys/sys/syscalls.c
		/usr/src/sys/sys/ufs_syscalls.c
		/usr/src/include/syscall.h
		/usr/src/lib/libc/pdp/sys/Makefile
		/usr/src/man/man2/chdir.2
		/usr/src/man/man2/Makefile
		/usr/lib/lint/llib-lc
		/usr/src/usr.bin/find/find.c

	There are a number of changes to 'ufs_syscalls.c' not directly
	related to adding the 'fchdir' routine.
	
	By adding a fairly large number of 'register' declarations and 
	changing some of the (less frequently used) ILOCK/IUNLOCK macros 
	to the ilock/iunlock function calls enough space was saved that 
	the kernel is *smaller* after adding 'fchdir' than it was before!

	The other major change to ufs_syscalls.c was the usage of the
	routine 'getinode'.  Since getinode() is local to this file it
	was made static.  The previous idiom was (casts, etc omitted
	for clarity):

		fp = getinode(fd);
		if (fp == NULL)
			return;
		ip = fp->f_data;

	Changing 'getinode' to return "inode *" instead of "file *" 
	results in the shorter idiom:

		if ((ip = getinode(fd)) == NULL)
			return;

	The 'ftruncate' function which needed a 'file *' was modified
	to call 'getf()' instead of 'getinode'.

	The chdir(2) man page was updated to reflect the addition of
	fchdir(2).  The chapter 2 Makefile was also updated to install
	a fchdir.0 link to chdir.0 in the cat directory.

	The 'libc' lint library is also updated.

	Lastly the 'find' program was modified to use the new system call.
	This allowed the removal of 'getwd' from find.c (saving a couple
	hundred bytes).  The 'find' program gained a modest speed increase
	by using 'fchdir' instead of 'chdir'.

	INSTALLATION INSTRUCTIONS:

	0) Save the shar archive below into a file - /tmp/xxx is a good choice.
	   Then:
		cd /tmp

	   Further steps must be done as 'root'.

	1) Unpack the shar file:
		sh /tmp/xxx

	   This creates the files:

		/usr/src/lib/libc/sys/pdp/fchdir.s
		/tmp/187

	2) Apply the patches:

		patch -p0 < 187

	3) cd /sys/YOUR_KERNEL_DIRECTORY
	   make
	   install the new kernel and reboot.  if you are building a
	   networking system this is usually done by:

		mv unix netnix /
		chmod 744 /unix /netnix
		fastboot

	4) cd /usr/lib/lint
	   /lib/cpp -C -Dlint llib-lc | ./lint1 -v > llib-lc.ln

	5) cd /usr/src/lib/libc/pdp/sys
	   make
	   (this will take a while.  If you are impatient you can figure
	    out the appropriate commands to manually build fchdir.o and
	    profiled/fchdir.o)

	   ar rv /lib/libc.a *.o
	   cd profiled
	   ar rv /usr/lib/libc_p.a *.o
	   cd ..
	   make clean
	   ranlib /lib/libc.a /usr/lib/libc_p.a

	6) cd /usr/src/man/man2
	   /usr/man/manroff chdir.2 > /usr/man/cat2/chdir.0
	   cd /usr/man/cat2
	   ln chdir.0 fchdir.0

	7) cd /usr/src/usr.bin/find
	   make
	   make install
	   make clean

==========cut here
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	/tmp/187
#	/usr/src/lib/libc/pdp/sys/fchdir.s
# This archive created: Fri Apr 29 21:32:05 1994
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '/tmp/187'
then
	echo shar: "will not over-write existing file '/tmp/187'"
else
sed 's/^X//' << \SHAR_EOF > '/tmp/187'
X*** /usr/include/syscall.h.old	Mon Jan 10 21:26:51 1994
X--- /usr/include/syscall.h	Thu Apr 21 21:08:59 1994
X***************
X*** 3,9 ****
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscall.h	5.4.1 (2.11BSD GTE) 12/31/93
X   */
X  
X  #define	SYS_exit	1
X--- 3,9 ----
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscall.h	5.4.2 (2.11BSD GTE) 4/21/94
X   */
X  
X  #define	SYS_exit	1
X***************
X*** 18,24 ****
X  #define	SYS_unlink	10
X  #define	SYS_execv	11
X  #define	SYS_chdir	12
X! 				/* 13 is old: time */
X  #define	SYS_mknod	14
X  #define	SYS_chmod	15
X  #define	SYS_chown	16
X--- 18,24 ----
X  #define	SYS_unlink	10
X  #define	SYS_execv	11
X  #define	SYS_chdir	12
X! #define	SYS_fchdir	13
X  #define	SYS_mknod	14
X  #define	SYS_chmod	15
X  #define	SYS_chown	16
X*** /usr/src/sys/sys/init_sysent.c.old	Fri Dec 31 23:27:22 1993
X--- /usr/src/sys/sys/init_sysent.c	Thu Apr 21 19:47:00 1994
X***************
X*** 3,9 ****
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)init_sysent.c	1.4 (2.11BSD GTE) 12/31/93
X   */
X  
X  /*
X--- 3,9 ----
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)init_sysent.c	1.5 (2.11BSD GTE) 4/21/94
X   */
X  
X  /*
X***************
X*** 53,59 ****
X  int	read(),write(),readv(),writev(),ioctl();
X  
X  /* 2.2 file system */
X! int	chdir(),chroot();
X  int	mkdir(),rmdir();
X  int	creat(),open(),mknod(),unlink(),stat(),fstat(),lstat();
X  int	chown(),fchown(),chmod(),fchmod(),utimes();
X--- 53,59 ----
X  int	read(),write(),readv(),writev(),ioctl();
X  
X  /* 2.2 file system */
X! int	chdir(), fchdir(), chroot();
X  int	mkdir(),rmdir();
X  int	creat(),open(),mknod(),unlink(),stat(),fstat(),lstat();
X  int	chown(),fchown(),chmod(),fchmod(),utimes();
X***************
X*** 118,124 ****
X  	1, unlink,			/*  10 = unlink */
X  	2, execv,			/*  11 = execv */
X  	1, chdir,			/*  12 = chdir */
X! 	0, nosys,			/*  13 = old time */
X  	3, mknod,			/*  14 = mknod */
X  	2, chmod,			/*  15 = chmod */
X  	3, chown,			/*  16 = chown; now 3 args */
X--- 118,124 ----
X  	1, unlink,			/*  10 = unlink */
X  	2, execv,			/*  11 = execv */
X  	1, chdir,			/*  12 = chdir */
X! 	1, fchdir,			/*  13 = fchdir */
X  	3, mknod,			/*  14 = mknod */
X  	2, chmod,			/*  15 = chmod */
X  	3, chown,			/*  16 = chown; now 3 args */
X*** /usr/src/sys/sys/syscalls.c.old	Mon Jan 10 21:28:05 1994
X--- /usr/src/sys/sys/syscalls.c	Thu Apr 21 19:47:53 1994
X***************
X*** 3,9 ****
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscalls.c	1.2 (2.11BSD GTE) 12/31/93
X   */
X  
X  /*
X--- 3,9 ----
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscalls.c	1.3 (2.11BSD GTE) 4/21/94
X   */
X  
X  /*
X***************
X*** 24,30 ****
X  	"unlink",		/*  10 = unlink */
X  	"execv",		/*  11 = execv */
X  	"chdir",		/*  12 = chdir */
X! 	"old time - nosys",	/*  13 = old time */
X  	"mknod",		/*  14 = mknod */
X  	"chmod",		/*  15 = chmod */
X  	"chown",		/*  16 = chown; now 3 args */
X--- 24,30 ----
X  	"unlink",		/*  10 = unlink */
X  	"execv",		/*  11 = execv */
X  	"chdir",		/*  12 = chdir */
X! 	"fchdir",		/*  13 = fchdir */
X  	"mknod",		/*  14 = mknod */
X  	"chmod",		/*  15 = chmod */
X  	"chown",		/*  16 = chown; now 3 args */
X*** /usr/src/sys/sys/ufs_syscalls.c.old	Thu May 31 09:35:14 1990
X--- /usr/src/sys/sys/ufs_syscalls.c	Fri Apr 29 19:48:59 1994
X***************
X*** 3,9 ****
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)ufs_syscalls.c	1.3 (2.10BSD Berkeley) 1/26/90
X   */
X  
X  #include "param.h"
X--- 3,9 ----
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)ufs_syscalls.c	1.4 (2.11BSD GTE) 4/29/94
X   */
X  
X  #include "param.h"
X***************
X*** 19,25 ****
X  #include "quota.h"
X  #endif
X  
X! struct	file *getinode();
X  
X  /*
X   * Change current working directory (``.'').
X--- 19,25 ----
X  #include "quota.h"
X  #endif
X  
X! static struct	inode *getinode();
X  
X  /*
X   * Change current working directory (``.'').
X***************
X*** 30,35 ****
X--- 30,61 ----
X  	chdirec(&u.u_cdir);
X  }
X  
X+ fchdir()
X+ {
X+ 	register struct	a {
X+ 		int	fd;
X+ 		} *uap = (struct a *)u.u_ap;
X+ 	register struct	inode *ip;
X+ 
X+ 	if ((ip = getinode(uap->fd)) == NULL)
X+ 		return;
X+ 	ILOCK(ip);
X+ 	if ((ip->i_mode & IFMT) != IFDIR) {
X+ 		u.u_error = ENOTDIR;
X+ 		goto bad;
X+ 	}
X+ 	if (access(ip, IEXEC))
X+ 		goto bad;
X+ 	IUNLOCK(ip);
X+ 	ip->i_count++;
X+ 	irele(u.u_cdir);
X+ 	u.u_cdir = ip;
X+ 	return;
X+ bad:
X+ 	iunlock(ip);
X+ 	return;
X+ }
X+ 
X  /*
X   * Change notion of root (``/'') directory.
X   */
X***************
X*** 47,53 ****
X  	register struct inode **ipp;
X  {
X  	register struct inode *ip;
X! 	register struct a {
X  		char	*fname;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct	nameidata *ndp = &u.u_nd;
X--- 73,79 ----
X  	register struct inode **ipp;
X  {
X  	register struct inode *ip;
X! 	struct a {
X  		char	*fname;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct	nameidata *ndp = &u.u_nd;
X***************
X*** 79,85 ****
X   */
X  open()
X  {
X! 	struct a {
X  		char	*fname;
X  		int	mode;
X  		int	crtmode;
X--- 105,111 ----
X   */
X  open()
X  {
X! 	register struct a {
X  		char	*fname;
X  		int	mode;
X  		int	crtmode;
X***************
X*** 93,99 ****
X   */
X  creat()
X  {
X! 	struct a {
X  		char	*fname;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X--- 119,125 ----
X   */
X  creat()
X  {
X! 	register struct a {
X  		char	*fname;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X***************
X*** 262,268 ****
X  	ip->i_nlink++;
X  	ip->i_flag |= ICHG;
X  	iupdat(ip, &time, &time, 1);
X! 	IUNLOCK(ip);
X  	ndp->ni_nameiop = CREATE;
X  	ndp->ni_segflg = UIO_USERSPACE;
X  	ndp->ni_dirp = (caddr_t)uap->linkname;
X--- 288,294 ----
X  	ip->i_nlink++;
X  	ip->i_flag |= ICHG;
X  	iupdat(ip, &time, &time, 1);
X! 	iunlock(ip);
X  	ndp->ni_nameiop = CREATE;
X  	ndp->ni_segflg = UIO_USERSPACE;
X  	ndp->ni_dirp = (caddr_t)uap->linkname;
X***************
X*** 418,424 ****
X   */
X  saccess()
X  {
X! 	register svuid, svgid;
X  	register struct inode *ip;
X  	register struct a {
X  		char	*fname;
X--- 444,451 ----
X   */
X  saccess()
X  {
X! 	uid_t svuid;
X! 	gid_t svgid;
X  	register struct inode *ip;
X  	register struct a {
X  		char	*fname;
X***************
X*** 524,531 ****
X   */
X  chmod()
X  {
X! 	struct inode *ip;
X! 	struct a {
X  		char	*fname;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X--- 551,558 ----
X   */
X  chmod()
X  {
X! 	register struct inode *ip;
X! 	register struct a {
X  		char	*fname;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X***************
X*** 541,557 ****
X   */
X  fchmod()
X  {
X! 	struct a {
X  		int	fd;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X- 	register struct file *fp;
X  
X! 	fp = getinode(uap->fd);
X! 	if (fp == NULL)
X  		return;
X- 	ip = (struct inode *)fp->f_data;
X  	if (u.u_uid != ip->i_uid && !suser())
X  		return;
X  	ILOCK(ip);
X--- 568,581 ----
X   */
X  fchmod()
X  {
X! 	register struct a {
X  		int	fd;
X  		int	fmode;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X  
X! 	if ((ip = getinode(uap->fd)) == NULL)
X  		return;
X  	if (u.u_uid != ip->i_uid && !suser())
X  		return;
X  	ILOCK(ip);
X***************
X*** 589,596 ****
X   */
X  chown()
X  {
X! 	struct inode *ip;
X! 	struct a {
X  		char	*fname;
X  		int	uid;
X  		int	gid;
X--- 613,620 ----
X   */
X  chown()
X  {
X! 	register struct inode *ip;
X! 	register struct a {
X  		char	*fname;
X  		int	uid;
X  		int	gid;
X***************
X*** 612,629 ****
X   */
X  fchown()
X  {
X! 	struct a {
X  		int	fd;
X  		int	uid;
X  		int	gid;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X- 	register struct file *fp;
X  
X! 	fp = getinode(uap->fd);
X! 	if (fp == NULL)
X  		return;
X- 	ip = (struct inode *)fp->f_data;
X  	ILOCK(ip);
X  	u.u_error = chown1(ip, uap->uid, uap->gid);
X  	IUNLOCK(ip);
X--- 636,650 ----
X   */
X  fchown()
X  {
X! 	register struct a {
X  		int	fd;
X  		int	uid;
X  		int	gid;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X  
X! 	if ((ip = getinode(uap->fd)) == NULL)
X  		return;
X  	ILOCK(ip);
X  	u.u_error = chown1(ip, uap->uid, uap->gid);
X  	IUNLOCK(ip);
X***************
X*** 635,641 ****
X   */
X  chown1(ip, uid, gid)
X  	register struct inode *ip;
X! 	int uid, gid;
X  {
X  #ifdef QUOTA
X  	long change;
X--- 656,662 ----
X   */
X  chown1(ip, uid, gid)
X  	register struct inode *ip;
X! 	register int uid, gid;
X  {
X  #ifdef QUOTA
X  	long change;
X***************
X*** 718,724 ****
X   */
X  truncate()
X  {
X! 	struct a {
X  		char	*fname;
X  		off_t	length;
X  	} *uap = (struct a *)u.u_ap;
X--- 739,745 ----
X   */
X  truncate()
X  {
X! 	register struct a {
X  		char	*fname;
X  		off_t	length;
X  	} *uap = (struct a *)u.u_ap;
X***************
X*** 747,770 ****
X   */
X  ftruncate()
X  {
X! 	struct a {
X  		int	fd;
X  		off_t	length;
X  	} *uap = (struct a *)u.u_ap;
X! 	struct inode *ip;
X! 	struct file *fp;
X  
X! 	fp = getinode(uap->fd);
X! 	if (fp == NULL)
X  		return;
X! 	if ((fp->f_flag&FWRITE) == 0) {
X  		u.u_error = EINVAL;
X  		return;
X  	}
X  	ip = (struct inode *)fp->f_data;
X! 	ILOCK(ip);
X  	itrunc(ip, (u_long)uap->length);
X! 	IUNLOCK(ip);
X  }
X  
X  /*
X--- 768,790 ----
X   */
X  ftruncate()
X  {
X! 	register struct a {
X  		int	fd;
X  		off_t	length;
X  	} *uap = (struct a *)u.u_ap;
X! 	register struct inode *ip;
X! 	register struct file *fp;
X  
X! 	if ((fp = getf(uap->fd)) == NULL)
X  		return;
X! 	if (!(fp->f_flag&FWRITE) || (fp->f_type != DTYPE_INODE)) {
X  		u.u_error = EINVAL;
X  		return;
X  	}
X  	ip = (struct inode *)fp->f_data;
X! 	ilock(ip);
X  	itrunc(ip, (u_long)uap->length);
X! 	iunlock(ip);
X  }
X  
X  /*
X***************
X*** 772,790 ****
X   */
X  fsync()
X  {
X! 	struct a {
X  		int	fd;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X- 	register struct file *fp;
X  
X! 	fp = getinode(uap->fd);
X! 	if (fp == NULL)
X  		return;
X! 	ip = (struct inode *)fp->f_data;
X! 	ILOCK(ip);
X  	syncip(ip);
X! 	IUNLOCK(ip);
X  }
X  
X  /*
X--- 792,807 ----
X   */
X  fsync()
X  {
X! 	register struct a {
X  		int	fd;
X  	} *uap = (struct a *)u.u_ap;
X  	register struct inode *ip;
X  
X! 	if ((ip = getinode(uap->fd)) == NULL)
X  		return;
X! 	ilock(ip);
X  	syncip(ip);
X! 	iunlock(ip);
X  }
X  
X  /*
X***************
X*** 1339,1359 ****
X  	iput(ip);
X  }
X  
X! struct file *
X  getinode(fdes)
X  	int fdes;
X  {
X! 	struct file *fp;
X  
X  	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
X  		u.u_error = EBADF;
X! 		return ((struct file *)0);
X  	}
X  	if (fp->f_type != DTYPE_INODE) {
X  		u.u_error = EINVAL;
X! 		return ((struct file *)0);
X  	}
X! 	return (fp);
X  }
X  
X  /*
X--- 1356,1376 ----
X  	iput(ip);
X  }
X  
X! static struct inode *
X  getinode(fdes)
X  	int fdes;
X  {
X! 	register struct file *fp;
X  
X  	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
X  		u.u_error = EBADF;
X! 		return ((struct inode *)0);
X  	}
X  	if (fp->f_type != DTYPE_INODE) {
X  		u.u_error = EINVAL;
X! 		return ((struct inode *)0);
X  	}
X! 	return((struct inode *)fp->f_data);
X  }
X  
X  /*
X*** /usr/src/include/syscall.h.old	Mon Jan 10 21:37:15 1994
X--- /usr/src/include/syscall.h	Thu Apr 21 21:08:59 1994
X***************
X*** 3,9 ****
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscall.h	5.4.1 (2.11BSD GTE) 12/31/93
X   */
X  
X  #define	SYS_exit	1
X--- 3,9 ----
X   * All rights reserved.  The Berkeley software License Agreement
X   * specifies the terms and conditions for redistribution.
X   *
X!  *	@(#)syscall.h	5.4.2 (2.11BSD GTE) 4/21/94
X   */
X  
X  #define	SYS_exit	1
X***************
X*** 18,24 ****
X  #define	SYS_unlink	10
X  #define	SYS_execv	11
X  #define	SYS_chdir	12
X! 				/* 13 is old: time */
X  #define	SYS_mknod	14
X  #define	SYS_chmod	15
X  #define	SYS_chown	16
X--- 18,24 ----
X  #define	SYS_unlink	10
X  #define	SYS_execv	11
X  #define	SYS_chdir	12
X! #define	SYS_fchdir	13
X  #define	SYS_mknod	14
X  #define	SYS_chmod	15
X  #define	SYS_chown	16
X*** /usr/src/lib/libc/pdp/sys/Makefile.old	Sat Apr  9 01:28:03 1994
X--- /usr/src/lib/libc/pdp/sys/Makefile	Thu Apr 21 21:36:25 1994
X***************
X*** 3,14 ****
X  # All rights reserved.  The Berkeley software License Agreement
X  # specifies the terms and conditions for redistribution.
X  #
X! #	@(#)Makefile	5.6.1 (2.11BSD GTE) 4/9/94
X  #
X  SRCS=	_exit.s accept.s access.s acct.s adjtime.s bind.s brk.s chdir.s \
X  	chmod.s chown.s chroot.s close.s connect.s creat.s dup.s dup2.s \
X! 	execl.s execle.s execv.s execve.s fchmod.s fchown.s fcntl.s flock.s \
X! 	fork.s fstat.s fsync.s ftruncate.s getdopt.s getdtablesiz.s \
X  	getegid.s geteuid.s getgid.s getgroups.s gethostid.s gethostname.s \
X  	getitimer.s getpagesize.s getpeername.s getpgrp.s getpid.s getppid.s \
X  	getpriority.s getrlimit.s getrusage.s getsockname.s getsockopt.s \
X--- 3,14 ----
X  # All rights reserved.  The Berkeley software License Agreement
X  # specifies the terms and conditions for redistribution.
X  #
X! #	@(#)Makefile	5.6.2 (2.11BSD GTE) 4/21/94
X  #
X  SRCS=	_exit.s accept.s access.s acct.s adjtime.s bind.s brk.s chdir.s \
X  	chmod.s chown.s chroot.s close.s connect.s creat.s dup.s dup2.s \
X! 	execl.s execle.s execv.s execve.s fchdir.s fchmod.s fchown.s fcntl.s \
X! 	flock.s fork.s fstat.s fsync.s ftruncate.s getdopt.s getdtablesiz.s \
X  	getegid.s geteuid.s getgid.s getgroups.s gethostid.s gethostname.s \
X  	getitimer.s getpagesize.s getpeername.s getpgrp.s getpid.s getppid.s \
X  	getpriority.s getrlimit.s getrusage.s getsockname.s getsockopt.s \
X***************
X*** 24,31 ****
X  	utimes.s vfork.s vhangup.s wait4.s write.s writev.s
X  OBJS=	_exit.o accept.o access.o acct.o adjtime.o bind.o brk.o chdir.o \
X  	chmod.o chown.o chroot.o close.o connect.o creat.o dup.o dup2.o \
X! 	execl.o execle.o execv.o execve.o fchmod.o fchown.o fcntl.o flock.o \
X! 	fork.o fstat.o fsync.o ftruncate.o getdopt.o getdtablesiz.o \
X  	getegid.o geteuid.o getgid.o getgroups.o gethostid.o gethostname.o \
X  	getitimer.o getpagesize.o getpeername.o getpgrp.o getpid.o getppid.o \
X  	getpriority.o getrlimit.o getrusage.o getsockname.o getsockopt.o \
X--- 24,31 ----
X  	utimes.s vfork.s vhangup.s wait4.s write.s writev.s
X  OBJS=	_exit.o accept.o access.o acct.o adjtime.o bind.o brk.o chdir.o \
X  	chmod.o chown.o chroot.o close.o connect.o creat.o dup.o dup2.o \
X! 	execl.o execle.o execv.o execve.o fchdir.o fchmod.o fchown.o fcntl.o \
X! 	flock.o fork.o fstat.o fsync.o ftruncate.o getdopt.o getdtablesiz.o \
X  	getegid.o geteuid.o getgid.o getgroups.o gethostid.o gethostname.o \
X  	getitimer.o getpagesize.o getpeername.o getpgrp.o getpid.o getppid.o \
X  	getpriority.o getrlimit.o getrusage.o getsockname.o getsockopt.o \
X***************
X*** 110,115 ****
X--- 110,116 ----
X  execle.o: execle.s ./SYS.h /usr/include/syscall.h
X  execv.o: execv.s ./SYS.h /usr/include/syscall.h
X  execve.o: execve.s ./SYS.h /usr/include/syscall.h
X+ fchdir.o: fchdir.s ./SYS.h /usr/include/syscall.h
X  fchmod.o: fchmod.s ./SYS.h /usr/include/syscall.h
X  fchown.o: fchown.s ./SYS.h /usr/include/syscall.h
X  fcntl.o: fcntl.s ./SYS.h /usr/include/syscall.h
X*** /usr/src/man/man2/chdir.2.old	Sun Dec 14 15:06:51 1986
X--- /usr/src/man/man2/chdir.2	Thu Apr 21 21:55:28 1994
X***************
X*** 2,28 ****
X  .\" All rights reserved.  The Berkeley software License Agreement
X  .\" specifies the terms and conditions for redistribution.
X  .\"
X! .\"	@(#)chdir.2	6.3 (Berkeley) 8/26/85
X  .\"
X! .TH CHDIR 2 "August 26, 1985"
X  .UC 4
X  .SH NAME
X! chdir \- change current working directory
X  .SH SYNOPSIS
X  .nf
X  .ft B
X  chdir(path)
X  char *path;
X  .ft R
X  .fi
X  .SH DESCRIPTION
X! .I Path
X! is the pathname of a directory.
X! .I Chdir
X! causes this directory
X  to become the current working directory,
X  the starting point for path names not beginning with ``/''.
X  .PP
X  In order for a directory to become the current directory,
X  a process must have execute (search) access to the directory.
X  .SH "RETURN VALUE
X--- 2,42 ----
X  .\" All rights reserved.  The Berkeley software License Agreement
X  .\" specifies the terms and conditions for redistribution.
X  .\"
X! .\"	@(#)chdir.2	6.3.1 (2.11BSD GTE) 4/21/94
X  .\"
X! .TH CHDIR 2 "April 21, 1994"
X  .UC 4
X  .SH NAME
X! chdir, fchdir \- change current working directory
X  .SH SYNOPSIS
X  .nf
X  .ft B
X  chdir(path)
X  char *path;
X+ 
X+ fchdir(fd)
X+ int fd;
X  .ft R
X  .fi
X  .SH DESCRIPTION
X! The
X! .B path
X! argument points to the pathname of a directory.
X! The
X! .B fd
X! argument is a file descriptor which references a directory.
X! The
X! .I chdir
X! function causes this directory
X  to become the current working directory,
X  the starting point for path names not beginning with ``/''.
X  .PP
X+ The
X+ .I fchdir
X+ function causes the directory referenced by \fBfd\fP to become
X+ the current working directory, the starting point for path searches of
X+ pathnames not beginning with a slahs, '/'.
X+ .PP
X  In order for a directory to become the current directory,
X  a process must have execute (search) access to the directory.
X  .SH "RETURN VALUE
X***************
X*** 41,48 ****
X  The pathname contains a character with the high-order bit set.
X  .TP 15
X  [ENAMETOOLONG]
X! A component of a pathname exceeded 255 characters,
X! or an entire path name exceeded 1023 characters.
X  .TP 15
X  [ENOENT]
X  The named directory does not exist.
X--- 55,62 ----
X  The pathname contains a character with the high-order bit set.
X  .TP 15
X  [ENAMETOOLONG]
X! A component of a pathname exceeded 63 characters,
X! or an entire path name exceeded 255 characters.
X  .TP 15
X  [ENOENT]
X  The named directory does not exist.
X***************
X*** 60,64 ****
X--- 74,92 ----
X  .TP 15
X  [EIO]
X  An I/O error occurred while reading from or writing to the file system.
X+ .PP
X+ .I Fchdir
X+ will fail and the current working directory will be unchanged if
X+ one or more of the following are true:
X+ .TP 15
X+ [EACCES]
X+ Search permission is denied for the directory referenced by the
X+ file descriptor.
X+ .TP 15
X+ [ENOTDIR]
X+ The file descriptor \fBfd\fP does not reference a directory.
X+ .TP 15
X+ [EBADF]
X+ The argument \fBfd\fP is not a valid file descriptor.
X  .SH "SEE ALSO"
X  chroot(2)
X*** /usr/src/man/man2/Makefile.old	Wed Jun 16 23:19:27 1993
X--- /usr/src/man/man2/Makefile	Thu Apr 21 23:01:24 1994
X***************
X*** 14,20 ****
X  # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X  # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X  #
X! #	@(#)Makefile	2.1 (2.11BSD GTE) 6/16/93
X  #
X  MDIR=	/usr/man/cat2
X  SRCS=	accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 chmod.2 \
X--- 14,20 ----
X  # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X  # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X  #
X! #	@(#)Makefile	2.2 (2.11BSD GTE) 4/21/94
X  #
X  MDIR=	/usr/man/cat2
X  SRCS=	accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 chmod.2 \
X***************
X*** 84,89 ****
X--- 84,91 ----
X  	ln ${DESTDIR}${MDIR}/wait.0 ${DESTDIR}${MDIR}/wait3.0
X  	ln ${DESTDIR}${MDIR}/wait.0 ${DESTDIR}${MDIR}/wait4.0
X  	ln ${DESTDIR}${MDIR}/wait.0 ${DESTDIR}${MDIR}/waitpid.0
X+ 	rm -f ${DESTDIR}${MDIR}/fchdir.0
X+ 	ln ${DESTDIR}${MDIR}/chmod.0 ${DESTDIR}${MDIR}/fchdir.0
X  	rm -f ${DESTDIR}${MDIR}/fchmod.0
X  	ln ${DESTDIR}${MDIR}/chmod.0 ${DESTDIR}${MDIR}/fchmod.0
X  	rm -f ${DESTDIR}${MDIR}/fchown.0
X*** /usr/lib/lint/llib-lc.old	Sun Jan 16 00:42:08 1994
X--- /usr/lib/lint/llib-lc	Thu Apr 21 22:52:01 1994
X***************
X*** 55,60 ****
X--- 55,61 ----
X  int	dup2( o, n) { return o; }
X  	execve(s, v, e) char *s, *v[], *e[]; {;}
X  	_exit(s) {;}
X+ int	fchdir(f) int f; { return(0); }
X  int	fchmod(f, m) { return(0); }
X  int	fchown(f, u, g) { return(0); }
X  int	fcntl(f, c, a) { return (0); }
X*** /usr/src/usr.bin/find/find.c.old	Mon Jan 10 22:53:30 1994
X--- /usr/src/usr.bin/find/find.c	Thu Apr 21 22:38:47 1994
X***************
X*** 1,8 ****
X  #if	defined(DOSCCS) && !defined(lint)
X! static char *sccsid = "@(#)find.c	4.17.1 (2.11BSD GTE) 1/1/93";
X  #endif
X  
X  #include <stdio.h>
X  #include <sys/param.h>
X  #include <sys/dir.h>
X  #include <sys/stat.h>
X--- 1,9 ----
X  #if	defined(DOSCCS) && !defined(lint)
X! static char *sccsid = "@(#)find.c	4.17.2 (2.11BSD GTE) 4/21/94";
X  #endif
X  
X  #include <stdio.h>
X+ #include <fcntl.h>
X  #include <sys/param.h>
X  #include <sys/dir.h>
X  #include <sys/stat.h>
X***************
X*** 45,51 ****
X  		*e3(),
X  		*mk();
X  char	*nxtarg();
X! char	Home[MAXPATHLEN + 1];
X  long	Blocks;
X  char *rindex();
X  char *sbrk();
X--- 46,52 ----
X  		*e3(),
X  		*mk();
X  char	*nxtarg();
X! int	Home;
X  long	Blocks;
X  char *rindex();
X  char *sbrk();
X***************
X*** 94,110 ****
X  	}
X  #endif
X  	time(&Now);
X! #ifdef	SUID_PWD
X! 	pwd = popen("pwd", "r");
X! 	fgets(Home, sizeof Home, pwd);
X! 	pclose(pwd);
X! 	Home[strlen(Home) - 1] = '\0';
X! #else
X! 	if (getwd(Home) == NULL) {
X! 		fprintf(stderr, "find: Can't get current working directory\n");
X  		exit(1);
X  	}
X- #endif
X  	Argc = argc; Argv = argv;
X  	if(argc<3) {
X  usage:		fprintf(stderr, "Usage: find path-list predicate-list\n");
X--- 95,105 ----
X  	}
X  #endif
X  	time(&Now);
X! 	Home = open(".", O_RDONLY);
X! 	if (Home < 0) {
X! 		fprintf(stderr, "Can't open .\n");
X  		exit(1);
X  	}
X  	Argc = argc; Argv = argv;
X  	if(argc<3) {
X  usage:		fprintf(stderr, "Usage: find path-list predicate-list\n");
X***************
X*** 125,131 ****
X  	}
X  	for(Pi = 1; Pi < paths; ++Pi) {
X  		sp = 0;
X! 		chdir(Home);
X  		strcpy(Pathname, Argv[Pi]);
X  		if(cp = rindex(Pathname, '/')) {
X  			sp = cp + 1;
X--- 120,126 ----
X  	}
X  	for(Pi = 1; Pi < paths; ++Pi) {
X  		sp = 0;
X! 		fchdir(Home);
X  		strcpy(Pathname, Argv[Pi]);
X  		if(cp = rindex(Pathname, '/')) {
X  			sp = cp + 1;
X***************
X*** 571,577 ****
X  		break;
X  
X  	case 0:
X! 		chdir(Home);
X  		execvp(nargv[0], nargv, np);
X  		write(2, "find: Can't execute ", 20);
X  		perror(nargv[0]);
X--- 566,572 ----
X  		break;
X  
X  	case 0:
X! 		fchdir(Home);
X  		execvp(nargv[0], nargv, np);
X  		write(2, "find: Can't execute ", 20);
X  		perror(nargv[0]);
X***************
X*** 666,672 ****
X  		Fname = endofname+1;
X  		if(!descend(name, Fname, exlist)) {
X  			*endofname = '\0';
X! 			chdir(Home);
X  			if(chdir(Pathname) == -1) {
X  				fprintf(stderr, "find: bad directory tree\n");
X  				exit(1);
X--- 661,667 ----
X  		Fname = endofname+1;
X  		if(!descend(name, Fname, exlist)) {
X  			*endofname = '\0';
X! 			fchdir(Home);
X  			if(chdir(Pathname) == -1) {
X  				fprintf(stderr, "find: bad directory tree\n");
X  				exit(1);
SHAR_EOF
chmod 644 '/tmp/187'
fi
if test -f '/usr/src/lib/libc/pdp/sys/fchdir.s'
then
	echo shar: "will not over-write existing file '/usr/src/lib/libc/pdp/sys/fchdir.s'"
else
sed 's/^X//' << \SHAR_EOF > '/usr/src/lib/libc/pdp/sys/fchdir.s'
X/*
X * No Copyright (c).  Placed in the public domain 1994.  Steven Schultz
X * (sms@wlv.iipo.gtegsc.com).
X */
X
X#ifdef SYSLIBC_SCCS
X_sccsid: <@(#)fchdir.s	1.0 (GTE) 4/21/94\0>
X	.even
X#endif SYSLIBC_SCCS
X
X#include "SYS.h"
X
XSYSCALL(fchdir,norm)
SHAR_EOF
chmod 444 '/usr/src/lib/libc/pdp/sys/fchdir.s'
fi
exit 0
#	End of shell archive
