diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2010-03-16 19:59:14 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2010-03-16 19:59:14 +0000 |
commit | d04be5775f40d50a4ee8f51f5e7b1ad6982a8f46 (patch) | |
tree | fc2abd8c96b6e6b8ec367740d8cdf7d9cfa34fab /sys/fs | |
parent | 6b533b5ddbb33c6221f1a1ac413953c76141bd8c (diff) | |
download | src-d04be5775f40d50a4ee8f51f5e7b1ad6982a8f46.tar.gz src-d04be5775f40d50a4ee8f51f5e7b1ad6982a8f46.zip |
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
Notes
Notes:
svn path=/head/; revision=205223
Diffstat (limited to 'sys/fs')
-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 07b2547b1757..43cf65efb1a1 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++; } |