## umockdev-ioctl

umockdev-ioctl — Emulate ioctl and read/write calls for devices.

## Functions

UMockdevIoctlBase * | umockdev_ioctl_base_new ()
UMockdevIoctlData * | umockdev_ioctl_data_ref ()
void | umockdev_ioctl_data_unref ()
UMockdevIoctlData * | umockdev_ioctl_data_resolve ()
gboolean | umockdev_ioctl_data_set_ptr ()
gboolean | umockdev_ioctl_data_reload ()
void | umockdev_ioctl_client_complete ()
void | umockdev_ioctl_client_abort ()
gint | umockdev_ioctl_client_execute ()
UMockdevIoctlData * | umockdev_ioctl_client_get_arg ()
gboolean | umockdev_ioctl_client_get_connected ()
const gchar * | umockdev_ioctl_client_get_devnode ()
gulong | umockdev_ioctl_client_get_request ()

## Properties

UMockdevIoctlData * | arg | Read
gboolean | connected | Read
char * | devnode | Read
gulong | request | Read

## Signals

void | client-connected | Run Last
void | client-vanished | Run Last
gboolean | handle-ioctl | Run Last
gboolean | handle-read | Run Last
gboolean | handle-write | Run Last
gboolean | handle-ioctl | Run Last
gboolean | handle-read | Run Last
gboolean | handle-write | Run Last

## Types and Values

struct | UMockdevIoctlBase
struct | UMockdevIoctlBaseClass
struct | UMockdevIoctlData
struct | UMockdevIoctlClient

## Object Hierarchy

        GObject
        ├── UMockdevIoctlBase
        ├── UMockdevIoctlClient
        ╰── UMockdevIoctlData

## Description

These classes permit emulation of ioctl and read/write calls including fully customizing the behaviour by creating an UMockdevIoctlBase instance or subclass instance and attaching it using `umockdev_testbed_attach_ioctl()`.

## Functions

### umockdev_ioctl_base_new ()

    UMockdevIoctlBase *
    umockdev_ioctl_base_new (void);

### umockdev_ioctl_data_ref ()

    UMockdevIoctlData *
    umockdev_ioctl_data_ref (UMockdevIoctlData *self);

Deprecated, same as `g_object_ref()`.

#### Parameters

self | A UMockdevIoctlData |

### umockdev_ioctl_data_unref ()

    void
    umockdev_ioctl_data_unref (UMockdevIoctlData *self);

Deprecated, same as `g_object_unref()`.

#### Parameters

self | A UMockdevIoctlData |

### umockdev_ioctl_data_resolve ()

    UMockdevIoctlData *
    umockdev_ioctl_data_resolve (UMockdevIoctlData *self,
                                 gsize offset,
                                 gsize len,
                                 GError **error);

Resolve an address inside the data. After this operation, the pointer inside data points to a local copy of the memory. Any local modifications will be synced back by `umockdev_ioctl_client_complete()` and `umockdev_ioctl_client_execute()`.

You may call this multiple times on the same pointer in order to fetch the existing information.

#### Parameters

self | A UMockdevIoctlData |
offset | Byte offset of pointer inside data |
len | Length of the to be resolved data |
error | return location for a GError, or `NULL` |

#### Returns

UMockdevIoctlData, or NULL on error

Since: 0.16

### umockdev_ioctl_data_set_ptr ()

    gboolean
    umockdev_ioctl_data_set_ptr (UMockdevIoctlData *self,
                                 gsize offset,
                                 UMockdevIoctlData *child);

Basically the reverse operation of `umockdev_ioctl_data_resolve()`. It sets the pointer at `offset` to point to the data from `child` in a way that can be synchronised back to the client.

Use of this is rare, but e.g. required to reap USB URBs.

The function will only work correctly for pointer elements that have not been resolved before.

#### Parameters

self | A UMockdevIoctlData |
offset | Byte offset of pointer inside data |
child | Memory block that the pointer should point to |
error | return location for a GError, or `NULL` |

#### Returns

`TRUE` on success, `FALSE`

Since: 0.16

### umockdev_ioctl_data_reload ()

    gboolean
    umockdev_ioctl_data_reload (UMockdevIoctlData *self,
                                GError **error);

This function allows reloading the data from the client side in case you expect client modifications to have happened in the meantime (e.g. between two separate ioctl's). It is very unlikely that such an explicit reload is needed.

Doing this unresolves any resolved pointers. Take care to re-resolve them and use the newly resolved UMockdevIoctlData in case you need to access the data.

#### Parameters

self | A UMockdevIoctlData |
error | return location for a GError, or `NULL` |

#### Returns

TRUE on success, FALSE otherwise

Since: 0.16

### umockdev_ioctl_client_complete ()

    void
    umockdev_ioctl_client_complete (UMockdevIoctlClient *self,
                                    glong res,
                                    gint errno_);

Asynchronously completes the ioctl invocation of the client. This is equivalent to calling `umockdev_ioctl_client_complete()` with the invocation.

This call is thread-safe.

#### Parameters

self | A UMockdevIoctlClient |
res | Return value of ioctl |
errno_ | errno of ioctl |

Since: 0.16

### umockdev_ioctl_client_abort ()

    void
    umockdev_ioctl_client_abort (UMockdevIoctlClient *self);

Asynchronously terminates the child by asking it to execute exit(1).

This call is thread-safe.

#### Parameters

self | A UMockdevIoctlClient |

Since: 0.16

### umockdev_ioctl_client_execute ()

    gint
    umockdev_ioctl_client_execute (UMockdevIoctlClient *self,
                                   gint *errno_,
                                   GError **error);

This function is not generally useful. It exists for umockdev itself in order to implement recording.

Execute the ioctl on the client side. Note that this flushes any modifications of the ioctl data. As such, pointers that were already resolved (including the initial ioctl argument itself) need to be resolved again.

It is only valid to call this while an uncompleted command is being processed.

This call is thread-safe.

#### Parameters

self | A UMockdevIoctlClient |
errno_ | Return location for errno |
error | return location for a GError, or `NULL` |

#### Returns

The client side result of the ioctl call

Since: 0.16

### umockdev_ioctl_client_get_arg ()

    UMockdevIoctlData *
    umockdev_ioctl_client_get_arg (UMockdevIoctlClient *self);

### umockdev_ioctl_client_get_connected ()

    gboolean
    umockdev_ioctl_client_get_connected (UMockdevIoctlClient *self);

### umockdev_ioctl_client_get_devnode ()

    const gchar *
    umockdev_ioctl_client_get_devnode (UMockdevIoctlClient *self);

### umockdev_ioctl_client_get_request ()

    gulong
    umockdev_ioctl_client_get_request (UMockdevIoctlClient *self);

## Types and Values

### struct UMockdevIoctlBase

    struct UMockdevIoctlBase;

The UMockdevIoctlBase class is a base class to emulate and record ioctl operations of a client. It can be attached to an emulated device in the testbed and will then be used.

Since: 0.16

### struct UMockdevIoctlBaseClass

    struct UMockdevIoctlBaseClass {
    	GObjectClass parent_class;
    	gboolean (*handle_ioctl) (UMockdevIoctlBase* self, UMockdevIoctlClient* client);
    	gboolean (*handle_read) (UMockdevIoctlBase* self, UMockdevIoctlClient* client);
    	gboolean (*handle_write) (UMockdevIoctlBase* self, UMockdevIoctlClient* client);
    	void (*client_connected) (UMockdevIoctlBase* self, UMockdevIoctlClient* client);
    	void (*client_vanished) (UMockdevIoctlBase* self, UMockdevIoctlClient* client);
    };

The base class for an device ioctl and read/write handling. You can either override the corresponding vfuncs or connect to the signals to customize the emulation.

#### Members

`handle_ioctl` () | Override ioctl emulation |
`handle_read` () | Override read emulation |
`handle_write` () | Override write_emulation |
`client_connected` () | A device was opened |
`client_vanished` () | A device was closed |

Since: 0.16

### struct UMockdevIoctlData

    struct UMockdevIoctlData;

The UMockdevIoctlData struct is a container designed to read and write memory from the client process.

After memory has been resolved, the corresponding pointer will point to local memory that can be used normally. The memory will automatically be synced back by `umockdev_ioctl_client_complete()`.

Since: 0.16

### struct UMockdevIoctlClient

    struct UMockdevIoctlClient;

The UMockdevIoctlClient struct represents an opened client side FD in order to emulate ioctl calls on this device.

Since: 0.16

## Property Details

### The `“arg”` property

      “arg”                      UMockdevIoctlData *

The ioctl argument, for read/write the passed buffer.

Owner: UMockdevIoctlClient

Flags: Read

### The `“connected”` property

      “connected”                gboolean

Whether the client is still connected.

Owner: UMockdevIoctlClient

Flags: Read

Default value: FALSE

### The `“devnode”` property

      “devnode”                  char *

The device node the client opened.

Owner: UMockdevIoctlClient

Flags: Read

Default value: NULL

### The `“request”` property

      “request”                  gulong

The current ioctl request.

Owner: UMockdevIoctlClient

Flags: Read

## Signal Details

### The `“client-connected”` signal

    void
    user_function (UMockdevIoctlBase   *umockdevioctlbase,
                   UMockdevIoctlClient *arg1,
                   gpointer             user_data)

Flags: Run Last

### The `“client-vanished”` signal

    void
    user_function (UMockdevIoctlBase   *umockdevioctlbase,
                   UMockdevIoctlClient *arg1,
                   gpointer             user_data)

Flags: Run Last

### The `“handle-ioctl”` signal

    gboolean
    user_function (UMockdevIoctlBase   *handler,
                   UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when an ioctl is requested by the client.

Access the “arg” property of `client` to retrieve the argument of the ioctl. This is a pointer sized buffer initially with the original argument passed to the ioctl. If this is pointing to a struct, use `umockdev_ioctl_data_resolve()` to retrieve the underlying memory and update the pointer. Resolve any further pointers in the structure in the same way.

After resolving the memory, you can access it as if it was local. The memory will be synced back to the client automatically if it has been modified locally.

Once processing is done, use `umockdev_ioctl_client_complete()` to let the client continue with the result of the emulation. You can also use `umockdev_ioctl_client_abort()` to kill the client. Note that this handling does not need to be immediate. It is valid to immediately return TRUE from this function and call `umockdev_ioctl_client_complete()` at a later point.

Note that this function will be called from a worker thread with a private GMainContext for the UMockdevTestbed. Do not block this context for longer periods. The complete handler may be called from a different thread.

#### Parameters

handler | A UMockdevIoctlBase |
client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

#### Returns

TRUE if the request is being handled, FALSE otherwise.

Flags: Run Last

Since: 0.16

### The `“handle-read”` signal

    gboolean
    user_function (UMockdevIoctlBase   *handler,
                   UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when a read is requested by the client.

The result buffer is represented by “arg” of `client` . Retrieve its length to find out the requested read length. The content of the buffer has already been retrieved, and you can freely use and update it.

See “handle-ioctl” for some more information.

#### Parameters

handler | A UMockdevIoctlBase |
client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

#### Returns

TRUE if the request is being handled, FALSE otherwise.

Flags: Run Last

Since: 0.16

### The `“handle-write”` signal

    gboolean
    user_function (UMockdevIoctlBase   *handler,
                   UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when a write is requested by the client.

The written buffer is represented by “arg” of `client` . Retrieve its length to find out the requested write length. The content of the buffer has already been retrieved, and you can freely use it.

See “handle-ioctl” for some more information.

#### Parameters

handler | A UMockdevIoctlBase |
client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

#### Returns

TRUE if the request is being handled, FALSE otherwise.

Flags: Run Last

Since: 0.16

### The `“handle-ioctl”` signal

    gboolean
    user_function (UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when an ioctl is requested by the client.

This is the per-client signal. See “handle-ioctl” on UMockdevIoctlBase.

#### Parameters

client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

Flags: Run Last

Since: 0.16

### The `“handle-read”` signal

    gboolean
    user_function (UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when a read is requested by the client.

This is the per-client signal. See “handle-read” on UMockdevIoctlBase.

#### Parameters

client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

Flags: Run Last

Since: 0.16

### The `“handle-write”` signal

    gboolean
    user_function (UMockdevIoctlClient *client,
                   gpointer             user_data)

Called when a write is requested by the client.

This is the per-client signal. See “handle-write” on UMockdevIoctlBase.

#### Parameters

client | A UMockdevIoctlClient |
user_data | user data set when the signal handler was connected. |

Flags: Run Last

Since: 0.16