Add new function fdunshare() which encapsulates the necessary light magic

for ensuring that a process' filedesc is not shared with anybody.

Use it in the two places which previously had private implmentations.

This collects all fd_refcnt handling in kern_descrip.c
This commit is contained in:
Poul-Henning Kamp 2004-12-14 07:20:03 +00:00
parent b96aca53dc
commit c113083c5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138832
4 changed files with 23 additions and 22 deletions

View File

@ -1414,6 +1414,25 @@ fdshare(struct filedesc *fdp)
return (fdp);
}
/*
* Unshare a filedesc structure, if necessary by making a copy
*/
void
fdunshare(struct proc *p, struct thread *td)
{
FILEDESC_LOCK_FAST(p->p_fd);
if (p->p_fd->fd_refcnt > 1) {
struct filedesc *tmp;
FILEDESC_UNLOCK_FAST(p->p_fd);
tmp = fdcopy(p->p_fd);
fdfree(td);
p->p_fd = tmp;
} else
FILEDESC_UNLOCK_FAST(p->p_fd);
}
/*
* Copy a filedesc structure.
* A NULL pointer in returns a NULL reference, this is to ease callers,

View File

@ -465,16 +465,7 @@ do_execve(td, fname, argv, envv, mac_p)
* For security and other reasons, the file descriptor table cannot
* be shared after an exec.
*/
FILEDESC_LOCK_FAST(p->p_fd);
if (p->p_fd->fd_refcnt > 1) {
struct filedesc *tmp;
FILEDESC_UNLOCK_FAST(p->p_fd);
tmp = fdcopy(p->p_fd);
fdfree(td);
p->p_fd = tmp;
} else
FILEDESC_UNLOCK_FAST(p->p_fd);
fdunshare(p, td);
/*
* Malloc things before we need locks.

View File

@ -233,18 +233,8 @@ fork1(td, flags, pages, procp)
/*
* Unshare file descriptors (from parent).
*/
if (flags & RFFDG) {
FILEDESC_LOCK_FAST(p1->p_fd);
if (p1->p_fd->fd_refcnt > 1) {
struct filedesc *newfd;
FILEDESC_UNLOCK_FAST(p1->p_fd);
newfd = fdcopy(p1->p_fd);
fdfree(td);
p1->p_fd = newfd;
} else
FILEDESC_UNLOCK_FAST(p1->p_fd);
}
if (flags & RFFDG)
fdunshare(p1, td);
*procp = NULL;
return (0);
}

View File

@ -163,6 +163,7 @@ int fdcheckstd(struct thread *td);
void fdclose(struct filedesc *fdp, struct file *fp, int idx, struct thread *td);
void fdcloseexec(struct thread *td);
struct filedesc *fdcopy(struct filedesc *fdp);
void fdunshare(struct proc *p, struct thread *td);
void fdfree(struct thread *td);
struct filedesc *fdinit(struct filedesc *fdp);
struct filedesc *fdshare(struct filedesc *fdp);