Efile_drv and non-regular files

Patrik Nyblom <>
Thu Mar 2 08:12:55 CET 2000


You are correct in that the error return value is misleading, there is
however a very good reason not to allow opening of other files than
regular ones; The efile driver expects the file to be regular in the
sense that operations won't block (i.e. a "fast" device). If one could
open e.g a tape drive and write to it, the whole erlang machine will
block for several seconds/minutes/hours, which is not especially nice.
If one wants to operate on special files, one have to either write a
"port program" (which will spin in a separate process) or write a
loadable driver, which uses threads or the io multiplexing mechanisms to
avoid hanging the emulator.

Note that the reason why the efile driver is written in this way is that
one cannot io multiplex (i.e. use select/poll) on regular files in a
meaningful way on lots of u*x'es. Using threads is inefficient and hard
to port, so that idea is also dropped (regarding regular files). Of
course one could allow opening of "fast" devices through the efile
driver, but I know of no portable way of desciding if a file represents
a "fast" device.

Maybe an alternative "any-type-of-file-driver" which uses
threads/separate processes would be nice though.


Daniel Neri wrote:

>         Hi,
> I just happened to try the following, while playing around in the
> shell:
> ,----
> | Erlang (BEAM) emulator version 4.9.1 [source]
> |
> | Eshell V4.9.1  (abort with ^G)
> | 1> {ok, F} = file:open("/dev/null", [read]).
> | ** exited: {{badmatch,{error,eisdir}},[{erl_eval,expr,3}]} **
> `----
> It turns out efile_drv tries to protect the user a wee bit too hard
> IMO, by making "open" on *any* non-regular file fail with
> "eisdir". Wouldn't it be better to leave the "protection business" to
> the underlying OS? Opening a special file might be valid in some
> cases.
> I propose removing the "regular file" check in efile_openfile (see
> patch below), thus allowing for:
> ,----
> | 8> {ok, F} = file:open("/dev/urandom", [read]).
> | {ok,<0.38.0>}
> | 9> file:read(F, 10).
> | {ok,[133,127,43,164,72,146,120,246,240,80]}
> `----
> But still not letting through the obvious error (which I assume was
> the reason for this check):
> ,----
> | 10> {ok, T} = file:open("/tmp", [write]).
> | ** exited: {{badmatch,{error,eisdir}},[{erl_eval,expr,3}]} **
> `----
> At the least, use a less misleading error identifier...
> Best wishes,
> /Daniel
> --
> Daniel Neri

More information about the erlang-questions mailing list