开发者

Opening a device file using erlang

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 开发者_如何学C?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜