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).
This commit is contained in:
parent
c7ca008189
commit
16936c9565
@ -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();
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 (;;) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user