From 16936c956528598a6202cbb0caf1e4fd5e4a290c Mon Sep 17 00:00:00 2001 From: thorpej Date: Fri, 30 Apr 1999 18:42:58 +0000 Subject: [PATCH] Break cdir/rdir/cmask info out of struct filedesc, and put it in a new substructure, `cwdinfo'. Implement optional sharing of this substructure. This is required for clone(2). --- sys/kern/init_main.c | 14 +++++-- sys/kern/kern_descrip.c | 93 ++++++++++++++++++++++++++++++++++------- sys/kern/kern_fork.c | 4 +- sys/kern/kern_sig.c | 4 +- sys/kern/uipc_usrreq.c | 6 +-- sys/kern/vfs_getcwd.c | 20 ++++----- sys/kern/vfs_lookup.c | 10 ++--- sys/kern/vfs_syscalls.c | 82 +++++++++++++++++++----------------- sys/sys/filedesc.h | 20 ++++++--- 9 files changed, 169 insertions(+), 84 deletions(-) diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 5d23e7e12841..70b3f235c9e5 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.147 1999/04/25 02:56:30 simonb Exp $ */ +/* $NetBSD: init_main.c,v 1.148 1999/04/30 18:42:59 thorpej Exp $ */ /* * Copyright (c) 1995 Christopher G. Demetriou. All rights reserved. @@ -115,6 +115,7 @@ struct pgrp pgrp0; struct proc proc0; struct pcred cred0; struct filedesc0 filedesc0; +struct cwdinfo cwdi0; struct plimit limit0; struct vmspace vmspace0; #ifndef curproc @@ -256,6 +257,11 @@ main() p->p_fd = &filedesc0.fd_fd; fdinit1(&filedesc0); + /* Create the CWD info. */ + p->p_cwdi = &cwdi0; + cwdi0.cwdi_cmask = cmask; + cwdi0.cwdi_refcnt = 1; + /* Create the limits structures. */ p->p_limit = &limit0; for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++) @@ -375,10 +381,10 @@ main() */ if (VFS_ROOT(mountlist.cqh_first, &rootvnode)) panic("cannot find root vnode"); - filedesc0.fd_fd.fd_cdir = rootvnode; - VREF(filedesc0.fd_fd.fd_cdir); + cwdi0.cwdi_cdir = rootvnode; + VREF(cwdi0.cwdi_cdir); VOP_UNLOCK(rootvnode, 0); - filedesc0.fd_fd.fd_rdir = NULL; + cwdi0.cwdi_rdir = NULL; uvm_swap_init(); /* diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 9e74b4eac563..ca5869612f30 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_descrip.c,v 1.57 1999/03/24 05:51:22 mrg Exp $ */ +/* $NetBSD: kern_descrip.c,v 1.58 1999/04/30 18:42:59 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -70,6 +70,7 @@ struct filelist filehead; /* head of list of open files */ int nfiles; /* actual number of open files */ struct pool file_pool; /* memory pool for file structures */ +struct pool cwdi_pool; /* memory pool for cwdinfo structures */ static __inline void fd_used __P((struct filedesc *, int)); static __inline void fd_unused __P((struct filedesc *, int)); @@ -576,6 +577,8 @@ finit() pool_init(&file_pool, sizeof(struct file), 0, 0, 0, "filepl", 0, pool_page_alloc_nointr, pool_page_free_nointr, M_FILE); + pool_init(&cwdi_pool, sizeof(struct cwdinfo), 0, 0, 0, "cwdipl", + 0, pool_page_alloc_nointr, pool_page_free_nointr, M_FILEDESC); } /* @@ -638,6 +641,80 @@ ffree(fp) pool_put(&file_pool, fp); } +/* + * Create an initial cwdinfo structure, using the same current and root + * directories as p. + */ +struct cwdinfo * +cwdinit(p) + struct proc *p; +{ + struct cwdinfo *cwdi; + extern int cmask; + + cwdi = pool_get(&cwdi_pool, PR_WAITOK); + + cwdi->cwdi_cdir = p->p_cwdi->cwdi_cdir; + VREF(cwdi->cwdi_cdir); + cwdi->cwdi_rdir = p->p_cwdi->cwdi_rdir; + if (cwdi->cwdi_rdir) + VREF(cwdi->cwdi_rdir); + cwdi->cwdi_cmask = cmask; + cwdi->cwdi_refcnt = 1; + + return (cwdi); +} + +/* + * Make p2 share p1's cwdinfo. + */ +void +cwdshare(p1, p2) + struct proc *p1, *p2; +{ + + p2->p_cwdi = p1->p_cwdi; + p1->p_cwdi->cwdi_refcnt++; +} + +/* + * Make this process not share its cwdinfo structure, maintaining + * all cwdinfo state. + */ +void +cwdunshare(p) + struct proc *p; +{ + struct cwdinfo *newcwdi; + + if (p->p_cwdi->cwdi_refcnt == 1) + return; + + newcwdi = cwdinit(p); + cwdfree(p); + p->p_cwdi = newcwdi; +} + +/* + * Release a cwdinfo structure. + */ +void +cwdfree(p) + struct proc *p; +{ + struct cwdinfo *cwdi = p->p_cwdi; + + if (--cwdi->cwdi_refcnt > 0) + return; + + p->p_cwdi = NULL; + + vrele(cwdi->cwdi_cdir); + if (cwdi->cwdi_rdir) + vrele(cwdi->cwdi_rdir); + pool_put(&cwdi_pool, cwdi); +} + /* * Create an initial filedesc structure, using the same current and root * directories as p. @@ -647,16 +724,10 @@ fdinit(p) struct proc *p; { struct filedesc0 *newfdp; - struct filedesc *fdp = p->p_fd; MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0), M_FILEDESC, M_WAITOK); memset(newfdp, 0, sizeof(struct filedesc0)); - newfdp->fd_fd.fd_cdir = fdp->fd_cdir; - VREF(newfdp->fd_fd.fd_cdir); - newfdp->fd_fd.fd_rdir = fdp->fd_rdir; - if (newfdp->fd_fd.fd_rdir) - VREF(newfdp->fd_fd.fd_rdir); fdinit1(newfdp); @@ -670,10 +741,8 @@ void fdinit1(newfdp) struct filedesc0 *newfdp; { - extern int cmask; /* init_main.c */ newfdp->fd_fd.fd_refcnt = 1; - newfdp->fd_fd.fd_cmask = cmask; newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; newfdp->fd_fd.fd_nfiles = NDFILE; @@ -737,9 +806,6 @@ fdcopy(p) MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), M_FILEDESC, M_WAITOK); memcpy(newfdp, fdp, sizeof(struct filedesc)); - VREF(newfdp->fd_cdir); - if (newfdp->fd_rdir) - VREF(newfdp->fd_rdir); newfdp->fd_refcnt = 1; /* @@ -800,9 +866,6 @@ fdfree(p) p->p_fd = NULL; if (fdp->fd_nfiles > NDFILE) FREE(fdp->fd_ofiles, M_FILEDESC); - vrele(fdp->fd_cdir); - if (fdp->fd_rdir) - vrele(fdp->fd_rdir); FREE(fdp, M_FILEDESC); } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1d5683ea2d87..e4311b049c04 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_fork.c,v 1.54 1999/03/24 05:51:23 mrg Exp $ */ +/* $NetBSD: kern_fork.c,v 1.55 1999/04/30 18:42:59 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -276,6 +276,8 @@ again: VREF(p2->p_textvp); p2->p_fd = fdcopy(p1); + p2->p_cwdi = cwdinit(p1); + /* * If p_limit is still copy-on-write, bump refcnt, * otherwise get a copy that won't be modified. diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 5b489d496723..f56a0d165cd5 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sig.c,v 1.87 1999/03/24 05:51:23 mrg Exp $ */ +/* $NetBSD: kern_sig.c,v 1.88 1999/04/30 18:43:00 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -1205,7 +1205,7 @@ coredump(p) * sure that the directory is still there and that the mount flags * allow us to write core dumps there. */ - vp = p->p_fd->fd_cdir; + vp = p->p_cwdi->cwdi_cdir; if (vp->v_mount == NULL || (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0) return (EPERM); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 43fefc49e160..cfeb086c4e44 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_usrreq.c,v 1.41 1999/04/21 02:37:07 mrg Exp $ */ +/* $NetBSD: uipc_usrreq.c,v 1.42 1999/04/30 18:43:00 thorpej Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -810,7 +810,7 @@ unp_externalize(rights) int f, error = 0; /* Make sure the recipient should be able to see the descriptors.. */ - if (p->p_fd->fd_rdir != NULL) { + if (p->p_cwdi->cwdi_rdir != NULL) { rp = (struct file **)ALIGN(cm + 1); for (i = 0; i < nfds; i++) { fp = *rp++; @@ -823,7 +823,7 @@ unp_externalize(rights) if (fp->f_type == DTYPE_VNODE) { struct vnode *vp = (struct vnode *)fp->f_data; if ((vp->v_type == VDIR) && - !vn_isunder(vp, p->p_fd->fd_rdir, p)) { + !vn_isunder(vp, p->p_cwdi->cwdi_rdir, p)) { error = EPERM; break; } diff --git a/sys/kern/vfs_getcwd.c b/sys/kern/vfs_getcwd.c index 9400ee5c565e..f1557b5fe6b2 100644 --- a/sys/kern/vfs_getcwd.c +++ b/sys/kern/vfs_getcwd.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_getcwd.c,v 1.5 1999/04/26 20:33:18 is Exp $ */ +/* $NetBSD: vfs_getcwd.c,v 1.6 1999/04/30 18:43:00 thorpej Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -320,13 +320,13 @@ static int getcwd_common (dvp, rvp, bpp, bufp, limit, flags, p) int flags; struct proc *p; { - struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; struct vnode *pvp = NULL; char *bp = NULL; int error; if (rvp == NULL) { - rvp = fdp->fd_rdir; + rvp = cwdi->cwdi_rdir; if (rvp == NULL) rvp = rootvnode; } @@ -470,9 +470,9 @@ int proc_isunder (p1, p2) struct proc *p1; struct proc *p2; { - struct vnode *r1 = p1->p_fd->fd_rdir; - struct vnode *r2 = p2->p_fd->fd_rdir; - + struct vnode *r1 = p1->p_cwdi->cwdi_rdir; + struct vnode *r2 = p2->p_cwdi->cwdi_rdir; + if (r1 == NULL) return (r2 == NULL); else if (r2 == NULL) @@ -509,7 +509,7 @@ int sys___getcwd(p, v, retval) bend = bp; *(--bp) = '\0'; - error = getcwd_common (p->p_fd->fd_cdir, NULL, &bp, path, len/2, + error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2, GETCWD_CHECK_ACCESS, p); if (error) @@ -552,7 +552,7 @@ sys___getcwd(p, v, retval) syscallarg(size_t) length; } */ *uap = v; - struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; struct vnode *cvp = NULL, *pvp = NULL, *rootvp = NULL; int error; char *path; @@ -571,11 +571,11 @@ sys___getcwd(p, v, retval) bend = bp; *(--bp) = '\0'; - rootvp = fdp->fd_rdir; + rootvp = cwdi->cwdi_rdir; if (rootvp == NULL) rootvp = rootvnode; - cvp = fdp->fd_cdir; + cvp = cwdi->cwdi_cdir; VREF(rootvp); VREF(cvp); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index b44eda8df15e..a71764868bad 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_lookup.c,v 1.29 1999/04/07 05:47:37 wrstuden Exp $ */ +/* $NetBSD: vfs_lookup.c,v 1.30 1999/04/30 18:43:00 thorpej Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -82,7 +82,7 @@ int namei(ndp) register struct nameidata *ndp; { - register struct filedesc *fdp; /* pointer to file descriptor state */ + struct cwdinfo *cwdi; /* pointer to cwd state */ register char *cp; /* pointer into pathname argument */ register struct vnode *dp; /* the directory we are searching */ struct iovec aiov; /* uio for reading symbolic links */ @@ -99,7 +99,7 @@ namei(ndp) if (cnp->cn_flags & OPMASK) panic ("namei: flags contaminated with nameiops"); #endif - fdp = cnp->cn_proc->p_fd; + cwdi = cnp->cn_proc->p_cwdi; /* * Get a buffer for the name to be translated, and copy the @@ -135,7 +135,7 @@ namei(ndp) /* * Get starting point for the translation. */ - if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL) + if ((ndp->ni_rootdir = cwdi->cwdi_rdir) == NULL) ndp->ni_rootdir = rootvnode; /* * Check if starting from root directory or current directory. @@ -144,7 +144,7 @@ namei(ndp) dp = ndp->ni_rootdir; VREF(dp); } else { - dp = fdp->fd_cdir; + dp = cwdi->cwdi_cdir; VREF(dp); } for (;;) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 8a902a1170e8..5da952c1df58 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.133 1999/03/31 19:18:45 mycroft Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.134 1999/04/30 18:43:01 thorpej Exp $ */ /* * Copyright (c) 1989, 1993 @@ -353,7 +353,7 @@ void checkdirs(olddp) struct vnode *olddp; { - struct filedesc *fdp; + struct cwdinfo *cwdi; struct vnode *newdp; struct proc *p; @@ -362,16 +362,16 @@ checkdirs(olddp) if (VFS_ROOT(olddp->v_mountedhere, &newdp)) panic("mount: lost mount"); for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { - fdp = p->p_fd; - if (fdp->fd_cdir == olddp) { - vrele(fdp->fd_cdir); + cwdi = p->p_cwdi; + if (cwdi->cwdi_cdir == olddp) { + vrele(cwdi->cwdi_cdir); VREF(newdp); - fdp->fd_cdir = newdp; + cwdi->cwdi_cdir = newdp; } - if (fdp->fd_rdir == olddp) { - vrele(fdp->fd_rdir); + if (cwdi->cwdi_rdir == olddp) { + vrele(cwdi->cwdi_rdir); VREF(newdp); - fdp->fd_rdir = newdp; + cwdi->cwdi_rdir = newdp; } } if (rootvnode == olddp) { @@ -703,7 +703,8 @@ sys_fchdir(p, v, retval) struct sys_fchdir_args /* { syscallarg(int) fd; } */ *uap = v; - register struct filedesc *fdp = p->p_fd; + struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; struct vnode *vp, *tdp; struct mount *mp; struct file *fp; @@ -739,14 +740,14 @@ sys_fchdir(p, v, retval) * Disallow changing to a directory not under the process's * current root directory (if there is one). */ - if (fdp->fd_rdir && + if (cwdi->cwdi_rdir && !vn_isunder(vp, NULL, p)) { vrele(vp); return EPERM; /* operation not permitted */ } - vrele(fdp->fd_cdir); - fdp->fd_cdir = vp; + vrele(cwdi->cwdi_cdir); + cwdi->cwdi_cdir = vp; return (0); } @@ -761,7 +762,8 @@ sys_fchroot(p, v, retval) register_t *retval; { struct sys_fchroot_args *uap = v; - struct filedesc *fdp = p->p_fd; + struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; struct vnode *vp; struct file *fp; int error; @@ -786,19 +788,19 @@ sys_fchroot(p, v, retval) * the working directory. Silently chdir to / if we aren't * already there. */ - if (!vn_isunder(fdp->fd_cdir, vp, p)) { + if (!vn_isunder(cwdi->cwdi_cdir, vp, p)) { /* * XXX would be more failsafe to change directory to a * deadfs node here instead */ - vrele(fdp->fd_cdir); + vrele(cwdi->cwdi_cdir); VREF(vp); - fdp->fd_cdir = vp; + cwdi->cwdi_cdir = vp; } - if (fdp->fd_rdir != NULL) - vrele(fdp->fd_rdir); - fdp->fd_rdir = vp; + if (cwdi->cwdi_rdir != NULL) + vrele(cwdi->cwdi_rdir); + cwdi->cwdi_rdir = vp; return 0; } @@ -817,7 +819,7 @@ sys_chdir(p, v, retval) struct sys_chdir_args /* { syscallarg(const char *) path; } */ *uap = v; - register struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; int error; struct nameidata nd; @@ -825,8 +827,8 @@ sys_chdir(p, v, retval) SCARG(uap, path), p); if ((error = change_dir(&nd, p)) != 0) return (error); - vrele(fdp->fd_cdir); - fdp->fd_cdir = nd.ni_vp; + vrele(cwdi->cwdi_cdir); + cwdi->cwdi_cdir = nd.ni_vp; return (0); } @@ -843,7 +845,7 @@ sys_chroot(p, v, retval) struct sys_chroot_args /* { syscallarg(const char *) path; } */ *uap = v; - register struct filedesc *fdp = p->p_fd; + struct cwdinfo *cwdi = p->p_cwdi; struct vnode *vp; int error; struct nameidata nd; @@ -854,24 +856,24 @@ sys_chroot(p, v, retval) SCARG(uap, path), p); if ((error = change_dir(&nd, p)) != 0) return (error); - if (fdp->fd_rdir != NULL) - vrele(fdp->fd_rdir); + if (cwdi->cwdi_rdir != NULL) + vrele(cwdi->cwdi_rdir); vp = nd.ni_vp; - fdp->fd_rdir = vp; + cwdi->cwdi_rdir = vp; /* * Prevent escaping from chroot by putting the root under * the working directory. Silently chdir to / if we aren't * already there. */ - if (!vn_isunder(fdp->fd_cdir, vp, p)) { + if (!vn_isunder(cwdi->cwdi_cdir, vp, p)) { /* * XXX would be more failsafe to change directory to a * deadfs node here instead */ - vrele(fdp->fd_cdir); + vrele(cwdi->cwdi_cdir); VREF(vp); - fdp->fd_cdir = vp; + cwdi->cwdi_cdir = vp; } return (0); @@ -918,6 +920,7 @@ sys_open(p, v, retval) syscallarg(int) flags; syscallarg(int) mode; } */ *uap = v; + struct cwdinfo *cwdi = p->p_cwdi; register struct filedesc *fdp = p->p_fd; register struct file *fp; register struct vnode *vp; @@ -934,7 +937,7 @@ sys_open(p, v, retval) if ((error = falloc(p, &nfp, &indx)) != 0) return (error); fp = nfp; - cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; + cmode = ((SCARG(uap, mode) &~ cwdi->cwdi_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); p->p_dupfd = -indx - 1; /* XXX check for fdopen */ if ((error = vn_open(&nd, flags, cmode)) != 0) { @@ -1016,7 +1019,7 @@ sys_mknod(p, v, retval) else { VATTR_NULL(&vattr); vattr.va_mode = - (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; + (SCARG(uap, mode) & ALLPERMS) &~ p->p_cwdi->cwdi_cmask; vattr.va_rdev = SCARG(uap, dev); whiteout = 0; @@ -1093,7 +1096,7 @@ sys_mkfifo(p, v, retval) } VATTR_NULL(&vattr); vattr.va_type = VFIFO; - vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; + vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_cwdi->cwdi_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr)); } @@ -1178,7 +1181,7 @@ sys_symlink(p, v, retval) goto out; } VATTR_NULL(&vattr); - vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; + vattr.va_mode = ACCESSPERMS &~ p->p_cwdi->cwdi_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path); out: @@ -2472,7 +2475,8 @@ sys_mkdir(p, v, retval) } VATTR_NULL(&vattr); vattr.va_type = VDIR; - vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; + vattr.va_mode = + (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_cwdi->cwdi_cmask; VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE); error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); if (!error) @@ -2573,11 +2577,11 @@ sys_umask(p, v, retval) struct sys_umask_args /* { syscallarg(mode_t) newmask; } */ *uap = v; - register struct filedesc *fdp; + struct cwdinfo *cwdi; - fdp = p->p_fd; - *retval = fdp->fd_cmask; - fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS; + cwdi = p->p_cwdi; + *retval = cwdi->cwdi_cmask; + cwdi->cwdi_cmask = SCARG(uap, newmask) & ALLPERMS; return (0); } diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 2bfa494694f5..53c4beedf6b8 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -1,4 +1,4 @@ -/* $NetBSD: filedesc.h,v 1.16 1998/01/05 04:51:15 thorpej Exp $ */ +/* $NetBSD: filedesc.h,v 1.17 1999/04/30 18:42:58 thorpej Exp $ */ /* * Copyright (c) 1990, 1993 @@ -58,15 +58,20 @@ struct filedesc { struct file **fd_ofiles; /* file structures for open files */ char *fd_ofileflags; /* per-process open file flags */ - struct vnode *fd_cdir; /* current directory */ - struct vnode *fd_rdir; /* root directory */ int fd_nfiles; /* number of open files allocated */ int fd_lastfile; /* high-water mark of fd_ofiles */ int fd_freefile; /* approx. next free file */ - u_short fd_cmask; /* mask for file creation */ - u_short fd_refcnt; /* reference count */ + int fd_refcnt; /* reference count */ }; +struct cwdinfo { + struct vnode *cwdi_cdir; /* current directory */ + struct vnode *cwdi_rdir; /* root directory */ + u_short cwdi_cmask; /* mask for file creation */ + u_short cwdi_refcnt; /* reference count */ +}; + + /* * Basic allocation of descriptors: * one of the above, plus arrays for NDFILE descriptors. @@ -112,6 +117,11 @@ void fdfree __P((struct proc *p)); int fdrelease __P((struct proc *p, int)); void fdcloseexec __P((struct proc *)); +struct cwdinfo *cwdinit __P((struct proc *)); +void cwdshare __P((struct proc *, struct proc *)); +void cwdunshare __P((struct proc *)); +void cwdfree __P((struct proc *)); + int closef __P((struct file *, struct proc *)); int getsock __P((struct filedesc *, int, struct file **)); #endif /* _KERNEL */