---
name: "driver_entry"
section: "1"
platform: "linux"
package: "erlang-manpages"
version: "1:10.b.1a-1"
release: "Debian 3.1 (Sarge)"
platforms: ["linux"]
url: "https://new.carta.tech/driver_entry"
---

# driver\_entry(1)

The driver-entry structure used by erlang drivers.

## NAME

driver\_entry -  The driver-entry structure used by erlang drivers.

## DESCRIPTION

The *driver\_entry* structure is a C struct that all erlang drivers defines. It contains entry points for the erlang driver that are called by the erlang emulator when erlang code accesses the driver.

All functions are function pointers. The *driver\_init* function returns a pointer to the *driver\_entry* structure. The name in the structure must correspond to the name of the driver, and the driver library file name (without file extension).

 The *erl\_driver* driver API functions needs a port handle that identifies the driver instance (and the port in the emulator). This is only passed to the *start* function, but not to the other functions. The *start* function returns a driver-defined handle that is passed to the other functions. A common practice is to have the *start* function allocating some application-defined structure and stash the *port* handle in it, to use it later with the driver API functions.

The driver call-back functions are called synchronously from the erlang emulator. If they take too long before completing, they can cause timeouts in the emulator. Use the queue or asynchronous calls if nessecary, since the emulator must be responsive.

## EXPORTS

**int init(void)**\

This is called directly after the driver has been loaded by *erl\_ddll:load\_driver/2*. (Actually when the driver is added to the driver list.) The driver should return 0, or if the driver can't initialize, -1.

**int start(ErlDrvPort port, char\* command)**\

This is called when the driver is instantiated, when *open\_port/2* is called. The driver should return a number \>= 0 or a pointer, or if the driver can't be started, one of three error codes should be returned:

ERL\_DRV\_ERROR\_GENERAL - general error, no error code

ERL\_DRV\_ERROR\_ERRNO - error with error code in erl\_errno

ERL\_DRV\_ERROR\_BADARG - error, badarg

If an error code is returned, the port isn't started.

**void stop(ErlDrvData drv\_data)**\

This is called when the port is closed, with *port\_close/1* or *Port ! {self(), close}*. Note that terminating the port owner process also closes the port.

**void output(ErlDrvData drv\_data, char \*buf, int len)**\

This is called when an erlang process has sent data to the port. The data is pointed to by *buf*, and is *len* bytes. Data is sent to the port with *Port ! {self(), {command, Data}}*, or with *port\_command/2*. Depending on how the port was opened, it should be either a list of integers 0...255 or a binary. See *open\_port/3* and *port\_command/2*.

**void ready\_input(ErlDrvData drv\_data, ErlDrvEvent event)**\
 **void ready\_output(ErlDrvData drv\_data, ErlDrvEvent event)**\

This is called when a driver event (given in the *event* parameter) is signaled. This is used to help asynchronous drivers "wake up" when something happens.

On unix the *event* is a pipe or socket handle (or something that the *select* system call understands).

On Windows the *event* is an Event or Semaphore (or something that the *WaitForMultipleObjects* API function understands). (Some trickery in the emulator allows more than the built-in limit of 64 *Events* to be used.)

To use this with threads and asynchronous routines, create a pipe on unix and an Event on Windows. When the routine completes, write to the pipe (use *SetEvent* on Windows), this will make the emulator call *ready\_input* or *ready\_output*.

**char \*driver\_name**\

This is the name of the driver, it must correspond to the atom used in *open\_port*, and the name of the driver library file (without the extension).

**void finish(void)**\

This function is called by the *erl\_ddll* driver when the driver is unloaded. (It is only called in dynamic drivers.)

The driver is only unloaded as a result of calling *unload\_driver/1*, or when the emulator halts.

**void \*handle**\

This field is not used, it's still around only for historical reasons. It should be *NULL*. Don't use it.

**int control(ErlDrvData drv\_data, unsigned int command, char \*buf, int len, char \*\*rbuf, int rlen)**\

This is a special routine invoked with the erlang function *port\_control/3*. It works a little like an "ioctl" for erlang drivers. The data given to *port\_control/3* arrives in *buf* and *len*. The driver may send data back as a driver binary, using *\*rbuf* and *rlen*.

This is the fastest way of calling a driver and get a response. It won't make any context switch in the erlang emulator, and requires no message passing. It is suitable for calling C function to get faster execution, when erlang is too slow.

If the driver wants to return data, it should return it in *rbuf*. When *control* is called, *rbuf* points to a pointer to a buffer of *rlen* bytes, which can be used to return data. Data is returned depending of the port control flags (those that are set with set\_port\_control\_flags). If the flag is set to *PORT\_CONTROL\_FLAG\_BINARY*, then *rbuf* should point to a driver binary or be NULL. Note that this binary must be freed. If *rbuf* is set to NULL, an empty list will be returned.

If the flag is set to *0*, *rbuf* points to a *char\** containing data, that is returned as a list of integers. Using binaries is faster if more than a few bytes are returned.

The return value is the number of bytes returned in *\*rbuf*.

**void timeout(ErlDrvData drv\_data)**\

This function is called any time after the driver's timer reaches 0. The timer is activeated with *driver\_set\_timer*. There are no priorities or ordering among drivers, so if several drivers time out at the same time, any one of them is called first.

**void outputv(ErlDrvData drv\_data, ErlIOVec \*ev)**\

This function is called whenever the port is written to. If it is *NULL*, the *output* function is called instead. This function is faster than *output*, because it takes an *ErlIOVec* directly, which requires no copying of the data. The port should be in binary mode, see *open\_port/2*.

The *ErlIOVec* contains both a *SysIOVec*, suitable for *writev*, and one or more binaries. If these binaries should be retained, when the driver returns from *outputv*, they can be queued (using driver\_enq\_bin for instance), or if they are kept in a static or global variable, the reference counter can be incremented.

**void ready\_async(ErlDrvData drv\_data, ErlDrvThreadData thread\_data)**\

This function is called after an asynchronous call has completed. The asynchronous call is started with driver\_async. This function is called from the erlang emulator thread, as opposed to the asynchronous function, which is called in some thread (if multithreading is enabled).

**int call(ErlDrvData drv\_data, unsigned int command, char \*buf, int len, char \*\*rbuf, int rlen, unsigned int \*flags)**\

This function is called from *erlang:port\_call/3*. It works a lot like the *control* call-back, but uses the external term format for input and output.

*command* is an integer, obtained from the call from erlang (the second argument to *erlang:port\_call/3*).

*buf* and *len* provide the arguments to the call (the third argument to *erlang:port\_call/3*). They can be decoded using *ei* functions.

*rbuf* points to a return buffer, *rlen* bytes long. The return data should be a valid erlang term in the external (binary) format. This is converted to an erlang term and returned by *erlang:port\_call/3* to the caller. If more space than *rlen* bytes is needed to return data, *\*rbuf* can be set to memory allocated with *driver\_alloc*. This memory will be freed automatically after *call* has returned.

The return value is the number of bytes returned in *\*rbuf*. If *ERL\_DRV\_ERROR\_GENERAL* is returned (or in fact, anything \<= 0), *erlang:port\_call/3* will throw a *BAD\_ARG*.

## See Also

erl\_driver(3), erl\_ddll(3), kernel(3), erlang(3)

## AUTHORS

```
Kenneth Lundin - support@erlang.ericsson.se
Jakob Cederlund - support@erlang.ericsson.se
```
