Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

read(2) on directories

3 views
Skip to first unread message

Jeremie Courreges-Anglas

unread,
Jul 12, 2016, 3:15:55 PM7/12/16
to

Sending this now to get opinions, but I do not plan any change for 6.0.

Since I started to use OpenBSD I've always found confusing that

cat /directory/

doesn't error out. I initially assumed that it was historical behavior,
but, as hinted by Theo, in rev. 1.1 the behavior was actually to return
the raw directory entry.

Both behaviors match POSIX, which allows a third possibility as an XSI
extension: fail with EISDIR. I think this is the most useful behavior;
dumping binary junk is useless, and returning en empty read can hide
errors.

I haven't performed extensive testing but if base/xenocara/ports bulk
builds show errors I can fix them. The question is, is it worth it?

Comments / objections?


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

Todd C. Miller

unread,
Jul 12, 2016, 3:20:41 PM7/12/16
to
Do you know what other systems return EISDIR for read(2) of a
directory?

- todd

Mark Kettenis

unread,
Jul 12, 2016, 3:24:27 PM7/12/16
to
> From: j...@wxcvbn.org (Jeremie Courreges-Anglas)
> Date: Tue, 12 Jul 2016 21:10:37 +0200
>
> Sending this now to get opinions, but I do not plan any change for 6.0.
>
> Since I started to use OpenBSD I've always found confusing that
>
> cat /directory/
>
> doesn't error out. I initially assumed that it was historical behavior,
> but, as hinted by Theo, in rev. 1.1 the behavior was actually to return
> the raw directory entry.
>
> Both behaviors match POSIX, which allows a third possibility as an XSI
> extension: fail with EISDIR. I think this is the most useful behavior;
> dumping binary junk is useless, and returning en empty read can hide
> errors.
>
> I haven't performed extensive testing but if base/xenocara/ports bulk
> builds show errors I can fix them. The question is, is it worth it?
>
> Comments / objections?

What do other BSDs (including Mac OS X) do?

Tim Newsham

unread,
Jul 12, 2016, 3:25:22 PM7/12/16
to
On Tue, Jul 12, 2016 at 9:19 AM, Todd C. Miller <Todd....@courtesan.com>
wrote:

> Do you know what other systems return EISDIR for read(2) of a
> directory?
>

Linux:
>>> os.open("/", 0)
3
>>> os.read(3, 1024)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 21] Is a directory


>
> - todd
>
>


--
Tim Newsham | www.thenewsh.com/~newsham | @newshtwit | thenewsh.blogspot.com

Todd C. Miller

unread,
Jul 12, 2016, 3:28:08 PM7/12/16
to
On Tue, 12 Jul 2016 21:23:51 +0200, Mark Kettenis wrote:

> What do other BSDs (including Mac OS X) do?

Mac OS X returns EISDIR.

- todd

Todd C. Miller

unread,
Jul 12, 2016, 3:42:34 PM7/12/16
to
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 ;-)

- todd

Chris Cappuccio

unread,
Jul 12, 2016, 3:48:27 PM7/12/16
to
Todd C. Miller [Todd....@courtesan.com] wrote:
I've personally always liked being able to cat / read() a directory
since it gives you a peek behind the curtain and reflects the
reality of how the filesystem is constructed.

Todd C. Miller

unread,
Jul 12, 2016, 4:04:43 PM7/12/16
to
On Tue, 12 Jul 2016 12:47:46 -0700, Chris Cappuccio wrote:

> I've personally always liked being able to cat / read() a directory
> since it gives you a peek behind the curtain and reflects the
> reality of how the filesystem is constructed.

You haven't been able to do that on OpenBSD for a very long time.

- todd

Chris Cappuccio

unread,
Jul 12, 2016, 4:15:13 PM7/12/16
to
Todd C. Miller [Todd....@courtesan.com] wrote:
I've been in a deep depression ever since :)

Jeremie Courreges-Anglas

unread,
Aug 2, 2016, 12:44:24 PM8/2/16
to
"Todd C. Miller" <Todd....@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?

Todd C. Miller

unread,
Aug 2, 2016, 12:45:52 PM8/2/16
to
On Tue, 02 Aug 2016 18:42:43 +0200, Jeremie Courreges-Anglas wrote:

> 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 millert@

- todd

0 new messages