diff options
author | jkim <jkim@FreeBSD.org> | 2010-03-16 19:59:14 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2010-03-16 19:59:14 +0000 |
commit | f82b4fd4810a89e14ca2e3dba6ffdb0debbdf784 (patch) | |
tree | fc2abd8c96b6e6b8ec367740d8cdf7d9cfa34fab | |
parent | 4ff4954e4e9b86c057c52b9d83cd9b7ba9517e0c (diff) | |
download | FreeBSD-src-f82b4fd4810a89e14ca2e3dba6ffdb0debbdf784.zip FreeBSD-src-f82b4fd4810a89e14ca2e3dba6ffdb0debbdf784.tar.gz |
Fix a long standing regression of readdir(3) in fdescfs(5) introduced
in r1.48. We were stopping at the first null pointer when multiple file
descriptors were opened and one in the middle was closed. This restores
traditional behaviour of fdescfs.
MFC after: 3 days
-rw-r--r-- | sys/fs/fdescfs/fdesc_vnops.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 07b2547..43cf65e 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -522,11 +522,10 @@ fdesc_readdir(ap) FILEDESC_SLOCK(fdp); while (i < fdp->fd_nfiles + 2 && uio->uio_resid >= UIO_MX) { + bzero((caddr_t)dp, UIO_MX); switch (i) { case 0: /* `.' */ case 1: /* `..' */ - bzero((caddr_t)dp, UIO_MX); - dp->d_fileno = i + FD_ROOT; dp->d_namlen = i + 1; dp->d_reclen = UIO_MX; @@ -535,26 +534,24 @@ fdesc_readdir(ap) dp->d_type = DT_DIR; break; default: - if (fdp->fd_ofiles[fcnt] == NULL) { - FILEDESC_SUNLOCK(fdp); - goto done; - } - - bzero((caddr_t) dp, UIO_MX); + if (fdp->fd_ofiles[fcnt] == NULL) + break; dp->d_namlen = sprintf(dp->d_name, "%d", fcnt); dp->d_reclen = UIO_MX; dp->d_type = DT_UNKNOWN; dp->d_fileno = i + FD_DESC; break; } - /* - * And ship to userland - */ - FILEDESC_SUNLOCK(fdp); - error = uiomove(dp, UIO_MX, uio); - if (error) - goto done; - FILEDESC_SLOCK(fdp); + if (dp->d_namlen != 0) { + /* + * And ship to userland + */ + FILEDESC_SUNLOCK(fdp); + error = uiomove(dp, UIO_MX, uio); + if (error) + goto done; + FILEDESC_SLOCK(fdp); + } i++; fcnt++; } |