---
name: "io_uring_prep_splice"
section: "3"
platform: "linux"
package: "liburing"
version: "2.15-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/io_uring_prep_splice"
---

# io\_uring\_prep\_splice(3)

prepare an splice request

## NAME

io\_uring\_prep\_splice - prepare an splice request

## SYNOPSIS

```
#include <fcntl.h>
#include <liburing.h>
```

**void io\_uring\_prep\_splice(struct io\_uring\_sqe \****sqe***,**                           **int** *fd\_in***,**                           **int64\_t** *off\_in***,**                           **int** *fd\_out***,**                           **int64\_t** *off\_out***,**                           **unsigned int** *nbytes***,**                           **unsigned int** *splice\_flags***);**

## DESCRIPTION

The [**io\_uring\_prep\_splice**(3)](/io_uring_prep_splice/3.md) function prepares a splice request. The submission queue entry *sqe* is setup to use as input the file descriptor *fd\_in* at offset *off\_in*, splicing data to the file descriptor at *fd\_out* and at offset *off\_out*. *nbytes* bytes of data should be spliced between the two descriptors. *splice\_flags* are modifier flags for the operation. See [**splice**(2)](/splice/2.md) for the generic splice flags.

If *fd\_out* is a direct descriptor, **IOSQE\_FIXED\_FILE** can be set in the SQE to indicate that. For the input file, the io\_uring specific **SPLICE\_F\_FD\_IN\_FIXED** can be set in *splice\_flags* and *fd\_in* given as a registered file descriptor offset.

If *fd\_in* refers to a pipe, *off\_in* is ignored and must be set to -1.

If *fd\_in* does not refer to a pipe and *off\_in* is -1, then *nbytes* are read from *fd\_in* starting from the file offset, which is incremented by the number of bytes read.

If *fd\_in* does not refer to a pipe and *off\_in* is not -1, then the starting offset of *fd\_in* will be *off\_in*.

The same rules apply to *fd\_out* and *off\_out*.

This function prepares an async [**splice**(2)](/splice/2.md) request. See that man page for details.

## RETURN VALUE

None

## ERRORS

The CQE *res* field will contain the result of the operation. See the related man page for details on possible values. Note that where synchronous system calls will return **-1** on failure and set *errno* to the actual error value, io\_uring never uses *errno*. Instead it returns the negated *errno* directly in the CQE *res* field.

## SEE ALSO

[**io\_uring\_get\_sqe**(3)](/io_uring_get_sqe/3.md), [**io\_uring\_submit**(3)](/io_uring_submit/3.md), [**io\_uring\_register**(2)](/io_uring_register/2.md), [**splice**(2)](/splice/2.md)

## NOTES

Note that even if *fd\_in* or *fd\_out* refers to a pipe, the splice operation can still fail with **EINVAL** if one of the fd doesn't explicitly support splice operation, e.g. reading from terminal is unsupported from kernel 5.7 to 5.11.

Despite accepting an unsigned number of bytes, this function can transfer at most INT\_MAX bytes per call (the maximum for the underlying syscall interface). In practice, limits as low as 65536 have been observed (just like with [**splice**(2)](/splice/2.md) itself).
