diff options
| author | David Malone <dwmalone@FreeBSD.org> | 2003-10-19 20:41:07 +0000 |
|---|---|---|
| committer | David Malone <dwmalone@FreeBSD.org> | 2003-10-19 20:41:07 +0000 |
| commit | e1419c08e2520d267e0a14e1bb10ae3bebbb12ae (patch) | |
| tree | 005101ab125d7c43f5a5366aaad1dafbe9eb3c26 /sys/dev/streams | |
| parent | 48ae2dddac9af3264c7eef87594bd0b0920c8d6f (diff) | |
Notes
Diffstat (limited to 'sys/dev/streams')
| -rw-r--r-- | sys/dev/streams/streams.c | 15 |
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); |
