Is there any way to open a terminal device file in erlang ?
I am on Solaris and I am trying the following::
Erlang (BEAM) emulator version 5.6 [source] [64-bit] [async-threads:0] [kernel-poll:false] /xlcabpuser1/xlc/abp/arunmu/Dolphin/ebin Eshell V5.6 (abort with ^G) 1> file:open("/dev/pts/2",[write]). {error,eisdir} 2> file:open("/dev/null",[write]). {ok,} 3>
As can be seen above the erlang file driver has no problem in opening a null fle but does not open a terminal device file!!
Unable to come to a conclusion as the file driver is able to open a null file.
Is there any other way to open terminal device files ?
Thanks
Update: I was able to work around the limitation described below using a port. For example, here is a sample program that prints "hello world" to /dev/stdout
:
-module(test).
-export([main/1]).
main(X) ->
P = open_port({spawn, "/bin/cat >/dev/stdout"}, [out]),
P ! {self(), {command, "hello world"}}.
This is a bit inconvenient because a port doesn't act like a regular file, but at least it's one way to get the job done.
In efile_openfile()
(in erts/emulator/drivers/unix/unix_efile.c
) there is the following code:
if (stat(name, &statbuf) >= 0 && !ISREG(statbuf)) {
#if !defined(VXWORKS) && !defined(OSE)
/*
* For UNIX only, here is some ugly code to allow
* /dev/null to be opened as a file.
*
* Assumption: The i-node number for /dev/null cannot be zero.
*/
static ino_t dev_null_ino = 0;
if (dev_null_ino == 0) {
struct stat nullstatbuf;
if (stat("/dev/null", &nullstatbuf) >= 0) {
dev_null_ino = nullstatbuf.st_ino;
}
}
if (!(dev_null_ino && statbuf.st_ino == dev_null_ino)) {
#endif
errno = EISDIR;
return check_error(-1, errInfo);
#if !defined(VXWORKS) && !defined(OSE)
}
#endif
}
This code (confusingly) returns the EISDIR
error if the file is not a regular file (which is the ISREG(statbuf)
check), unless the file specifically is /dev/null
. The file(3)
documentation states:
eisdir :
The named file is not a regular file. It may be a directory, a
fifo, or a device.
so it's actually documented to do that. I'm not sure why that restriction exists, though—perhaps it's got something to do with performance because device drivers might block for more time than an ordinary file generally will.