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 X #include X #include X #include 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 X+ #include X #include X #include X #include 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