summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_descrip.c19
-rw-r--r--sys/kern/kern_exec.c11
-rw-r--r--sys/kern/kern_fork.c14
-rw-r--r--sys/sys/filedesc.h1
4 files changed, 23 insertions, 22 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 50902f0..754a3cb 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1415,6 +1415,25 @@ fdshare(struct filedesc *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,
* not catch errors.
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index e21cb00..40e0f0a 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -465,16 +465,7 @@ interpret:
* 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.
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index ae8cce3..3178c10 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -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);
}
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index beae405..00e3df2 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -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);
OpenPOWER on IntegriCloud