"Todd C. Miller" <todd.mil...@courtesan.com> writes:

> From source inspection, Net and Free appear to allow read(2) of
> dirs to succeed.  However, since Linux, Mac OS X and Solaris have
> the EISDIR behavior I think it is probably safe from a portability
> standpoint.
>
> We're long past the days when opendir(3)/readdir(3) used read(2)...
>
> HP-UX and AIX still allow reads of directories but no one cares
> about them ;-)

So I think that we agree that EISDIR is more useful, and seems safe from
a portability POV.   I've built base and x sets on i386, and ajacoutot
ran the ports bulk builds.  The two offenders in the ports tree were due
to an unrelated glitch in base libtool which has since been fixed.

ok?


Index: lib/libc/sys/read.2
===================================================================
RCS file: /cvs/src/lib/libc/sys/read.2,v
retrieving revision 1.35
diff -u -p -r1.35 read.2
--- lib/libc/sys/read.2 5 Feb 2015 02:33:09 -0000       1.35
+++ lib/libc/sys/read.2 9 Jul 2016 17:20:39 -0000
@@ -152,13 +152,15 @@ is not a valid file or socket descriptor
 Part of
 .Fa buf
 points outside the process's allocated address space.
-.It Bq Er EIO
-An I/O error occurred while reading from the file system.
 .It Bq Er EINTR
 A read from a slow device
 (i.e. one that might block for an arbitrary amount of time)
 was interrupted by the delivery of a signal
 before any data arrived.
+.It Bq Er EIO
+An I/O error occurred while reading from the file system.
+.It Bq Er EISDIR
+The underlying file is a directory.
 .El
 .Pp
 In addition,
Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.85
diff -u -p -r1.85 vfs_vnops.c
--- sys/kern/vfs_vnops.c        19 Jun 2016 11:54:33 -0000      1.85
+++ sys/kern/vfs_vnops.c        9 Jul 2016 17:20:39 -0000
@@ -336,11 +336,13 @@ vn_read(struct file *fp, off_t *poff, st
        if (vp->v_type != VCHR && count > LLONG_MAX - *poff)
                return (EINVAL);
 
+       if (vp->v_type == VDIR)
+               return (EISDIR);
+
        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
        uio->uio_offset = *poff;
-       if (vp->v_type != VDIR)
-               error = VOP_READ(vp, uio,
-                   (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0, cred);
+       error = VOP_READ(vp, uio, (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0,
+           cred);
        *poff += count - uio->uio_resid;
        VOP_UNLOCK(vp, p);
        return (error);


-- 
jca | PGP: 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to