---
name: "io_getevents"
section: "3"
platform: "linux"
package: "libaio"
version: "0.3.113-5"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/io_getevents/3"
---

# io\_getevents(3)

Read resulting events from io requests

## NAME

io\_getevents, aio\_pgetevents - Read resulting events from io requests

## SYNOPSIS

```
#include <errno.h>

#include <libaio.h>

struct iocb {
	void		*data;
	unsigned	key;
	short		aio_lio_opcode;
	short		aio_reqprio;
	int		aio_fildes;
};

struct io_event {
        unsigned        PADDED(data, __pad1);
        unsigned        PADDED(obj,  __pad2);
        unsigned        PADDED(res,  __pad3);
        unsigned        PADDED(res2, __pad4);
};

int io_getevents(io_context_t ctx, long nr, struct io_event *events[], struct timespec *timeout);
int io_pgetevents(io_context_t ctx, long nr, struct io_event *events[], struct timespec *timeout, sigset_t *sigmask);
```

## DESCRIPTION

Attempts to read up to *nr* events from the completion queue for the aio\_context specified by *ctx*.

## RETURN VALUES

May return **0** if no events are available and the timeout specified by when has elapsed, where *when* == NULL specifies an infinite timeout.  Note that the timeout pointed to by when is relative and will be updated if not NULL and the operation blocks.  Will fail with **ENOSYS** if not implemented.

### io\_pgetevents()

The relationship between **io\_getevents**() and **io\_pgetevents**() is analogous to the relationship between [**select**(2)](/select/2.md) and [**pselect**(2)](/pselect/2.md): similar to [**pselect**(2)](/pselect/2.md), **pgetevents**() allows an application to safely wait until either an aio completion event happens or until a signal is caught.

The following **io\_pgetevents**() call:

```
ret = io_pgetevents(ctx, min_nr, nr, events, timeout, sigmask);
```

is equivalent to *atomically* executing the following calls:

```
sigset_t origmask;
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ret = io_getevents(ctx, min_nr, nr, events, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
```

See the description of [**pselect**(2)](/pselect/2.md) for an explanation of why **io\_pgetevents**() is necessary.

If the *sigmask* argument is specified as NULL, then no signal mask manipulation is performed (and thus **io\_pgetevents**() behaves the same as **io\_getevents()**).

## ERRORS

- **EINVAL**

  If *ctx* is invalid, if *min\_nr* is out of range, if *nr* is out of range, if *when* is out of range.

- **EFAULT**

  If any of the memory specified to is invalid.

## SEE ALSO

[**io**(3)](/io/3.md), [**io\_cancel**(3)](/io_cancel/3.md), [**io\_fsync**(3)](/io_fsync/3.md), [**io\_prep\_fsync**(3)](/io_prep_fsync/3.md), [**io\_prep\_pread**(3)](/io_prep_pread/3.md), [**io\_prep\_pwrite**(3)](/io_prep_pwrite/3.md), [**io\_queue\_init**(3)](/io_queue_init/3.md), [**io\_queue\_release**(3)](/io_queue_release/3.md), [**io\_queue\_run**(3)](/io_queue_run/3.md), [**io\_queue\_wait**(3)](/io_queue_wait/3.md), [**io\_set\_callback**(3)](/io_set_callback/3.md), [**io\_submit**(3)](/io_submit/3.md), [**errno**(3)](/errno/3.md), [**pselect**(2)](/pselect/2.md).
