From Erights

Jump to: navigation, search
This object type is currently only implemented in E-on-CL.

An FDRef is an object which wraps the operating system's file descriptors or similar objects. On platforms which have file descriptors, i.e. small integers naming open files, the primary purpose of FDRef objects is to ensure that a file descriptor is closed after, and not before, there are no users of it (that is, when the FDRef is garbage collected). Therefore, all interfaces to system calls which take file descriptors should either take FDRefs or be methods of FDRef.

FDRefs are a low-level interface; they reveal nondeterminism, and may be used to directly perform potentially blocking system calls. They should always be wrapped by higher-level facilities, and exist only to be a useful implementation abstraction and to allow writing said wrappers in E.

Since file descriptors may be explicitly closed, it is possible to have a FDRef which is invalid — having no associated file descriptor.



When a method is applicable to only certain types of open files (e.g. shutdown only applies to sockets), it may be absent from that particular FDRef object. Note: Due to limitations caused by the implementation platform, it may be the case that a FDRef does not have all of the methods it should for its file type if it was obtained in some “generic” way, or it may have methods which are not applicable. XXX Should we obligate implementing __respondsTo/2 to detect the type of file?

XXX finish documenting/specifying. Add all the socket-specific methods from EoCL

XXX Write a single page documenting system call error code conversions to exceptions.


Signature: close(ejector :ExitFunc) :void

Performs the close() system call, exiting according to ejector if it fails, and marks this FDRef invalid.

XXX What should happen to the state of the FDRef in the event of failure? Is it possible for the FD to not have been deallocated.


Signature: getFD() :int

Returns the file descriptor, throwing if this FDRef is invalid. Clients should be extremely careful to retain the FDRef until they are done using the file descriptor, and must rely on other clients of this FDRef not to close it.


Signature: shutdown(direction :XXX, ejector :ExitFunc) :void

Performs the shutdown() system call, exiting according to ejector if it fails. XXX Explain direction argument. In current impl, it is a CL symbol.


Signature: write(data :ConstList, ejector :ExitFunc, start :int, length :nullOK[int]) :void

Performs the write() system call, exiting according to ejector if it fails. Any resulting SIGPIPE is ignored.

If length is null, then the length of data is used. XXX Better length-start?


Signature: read(maxOctets :int ≥ 0, errorEjector :ExitFunc, eofEjector :ExitFunc) :ConstList

Performs the read() system call.

  • If read() returns a positive number, the octets read are returned in a ConstList.
  • If read() returns 0 (end of file), eofEjector is invoked. XXX specify argument to ejector
  • If read() returns -1,
    • If the error is EWOULDBLOCK, [] is returned.
    • Otherwise errorEjector is invoked.

The return value is the list of octets read.

Personal tools
more tools