aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/streams
diff options
context:
space:
mode:
authorDavid Malone <dwmalone@FreeBSD.org>2003-10-19 20:41:07 +0000
committerDavid Malone <dwmalone@FreeBSD.org>2003-10-19 20:41:07 +0000
commite1419c08e2520d267e0a14e1bb10ae3bebbb12ae (patch)
tree005101ab125d7c43f5a5366aaad1dafbe9eb3c26 /sys/dev/streams
parent48ae2dddac9af3264c7eef87594bd0b0920c8d6f (diff)
Notes
Diffstat (limited to 'sys/dev/streams')
-rw-r--r--sys/dev/streams/streams.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/dev/streams/streams.c b/sys/dev/streams/streams.c
index 838f295d5b66..cc50c3b8e854 100644
--- a/sys/dev/streams/streams.c
+++ b/sys/dev/streams/streams.c
@@ -189,7 +189,7 @@ static int
streamsopen(dev_t dev, int oflags, int devtype, struct thread *td)
{
int type, protocol;
- int fd;
+ int fd, extraref;
struct file *fp;
struct socket *so;
int error;
@@ -251,13 +251,21 @@ streamsopen(dev_t dev, int oflags, int devtype, struct thread *td)
if ((error = falloc(td, &fp, &fd)) != 0)
return error;
+ /* An extra reference on `fp' has been held for us by falloc(). */
if ((error = socreate(family, &so, type, protocol,
td->td_ucred, td)) != 0) {
FILEDESC_LOCK(p->p_fd);
- p->p_fd->fd_ofiles[fd] = 0;
+ /* Check the fd table entry hasn't changed since we made it. */
+ extraref = 0;
+ if (p->p_fd->fd_ofiles[fd] == fp) {
+ p->p_fd->fd_ofiles[fd] = NULL;
+ extraref = 1;
+ }
FILEDESC_UNLOCK(p->p_fd);
- ffree(fp);
+ if (extraref)
+ fdrop(fp, td);
+ fdrop(fp, td);
return error;
}
@@ -269,6 +277,7 @@ streamsopen(dev_t dev, int oflags, int devtype, struct thread *td)
FILEDESC_UNLOCK(p->p_fd);
(void)svr4_stream_get(fp);
+ fdrop(fp, td);
PROC_LOCK(p);
td->td_dupfd = fd;
PROC_UNLOCK(p);