summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2012-06-14 12:43:37 +0000
committerpjd <pjd@FreeBSD.org>2012-06-14 12:43:37 +0000
commit2014b8defb40e6ae0712da32f5a4d8b95447c392 (patch)
tree7c0a29d67f7c36a15cdd8669d9cc6fa81d5d3fa3 /sys/kern/kern_descrip.c
parent6634e42976a701b01eb967c1b46dc3f27ac64ef0 (diff)
downloadFreeBSD-src-2014b8defb40e6ae0712da32f5a4d8b95447c392.zip
FreeBSD-src-2014b8defb40e6ae0712da32f5a4d8b95447c392.tar.gz
Remove code duplication from fdclosexec(), which was the reason of the bug
fixed in r237065. MFC after: 1 month
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c49
1 files changed, 19 insertions, 30 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 09343fa..c38e10a 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -115,7 +115,7 @@ static uma_zone_t file_zone;
#define DUP_FCNTL 0x2 /* fcntl()-style errors */
static int closefp(struct filedesc *fdp, int fd, struct file *fp,
- struct thread *td);
+ struct thread *td, int holdleaders);
static int do_dup(struct thread *td, int flags, int old, int new,
register_t *retval);
static int fd_first_free(struct filedesc *, int, int);
@@ -885,7 +885,7 @@ do_dup(struct thread *td, int flags, int old, int new,
*retval = new;
if (delfp != NULL) {
- (void) closefp(fdp, new, delfp, td);
+ (void) closefp(fdp, new, delfp, td, 1);
/* closefp() drops the FILEDESC lock for us. */
} else {
FILEDESC_XUNLOCK(fdp);
@@ -1117,22 +1117,24 @@ fgetown(sigiop)
* Function drops the filedesc lock on return.
*/
static int
-closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td)
+closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
+ int holdleaders)
{
struct file *fp_object;
- int error, holdleaders;
+ int error;
FILEDESC_XLOCK_ASSERT(fdp);
- if (td->td_proc->p_fdtol != NULL) {
- /*
- * Ask fdfree() to sleep to ensure that all relevant
- * process leaders can be traversed in closef().
- */
- fdp->fd_holdleaderscount++;
- holdleaders = 1;
- } else {
- holdleaders = 0;
+ if (holdleaders) {
+ if (td->td_proc->p_fdtol != NULL) {
+ /*
+ * Ask fdfree() to sleep to ensure that all relevant
+ * process leaders can be traversed in closef().
+ */
+ fdp->fd_holdleaderscount++;
+ } else {
+ holdleaders = 0;
+ }
}
/*
@@ -1207,7 +1209,7 @@ kern_close(td, fd)
fdunused(fdp, fd);
/* closefp() drops the FILEDESC lock for us. */
- return (closefp(fdp, fd, fp, td));
+ return (closefp(fdp, fd, fp, td, 1));
}
/*
@@ -2025,7 +2027,7 @@ void
fdcloseexec(struct thread *td)
{
struct filedesc *fdp;
- struct file *fp, *fp_object;
+ struct file *fp;
int i;
/* Certain daemons might not have file descriptors. */
@@ -2042,24 +2044,11 @@ fdcloseexec(struct thread *td)
fp = fdp->fd_ofiles[i];
if (fp != NULL && (fp->f_type == DTYPE_MQUEUE ||
(fdp->fd_ofileflags[i] & UF_EXCLOSE))) {
- /*
- * NULL-out descriptor prior to close to avoid
- * a race while close blocks.
- */
fdp->fd_ofiles[i] = NULL;
fdp->fd_ofileflags[i] = 0;
fdunused(fdp, i);
- knote_fdclose(td, i);
- /*
- * When we're closing an fd with a capability, we need
- * to notify mqueue if the underlying object is of type
- * mqueue.
- */
- (void)cap_funwrap(fp, 0, &fp_object);
- if (fp_object->f_type == DTYPE_MQUEUE)
- mq_fdclose(td, i, fp_object);
- FILEDESC_XUNLOCK(fdp);
- (void) closef(fp, td);
+ (void) closefp(fdp, i, fp, td, 0);
+ /* closefp() drops the FILEDESC lock. */
FILEDESC_XLOCK(fdp);
}
}
OpenPOWER on IntegriCloud