VMSPLICE(2)

ИМЯ
vmsplice - соединяет пользовательские страницы памяти с каналом

ОБЗОР
#define _GNU_SOURCE         /* см. feature_test_macros(7) */
#include <fcntl.h>
#include <sys/uio.h>

ssize_t vmsplice(int fd, const struct iovec *iov,
                 unsigned long nr_segs, unsigned int flags);

ОПИСАНИЕ
Если fd открыт для записи, то системный вызов vmsplice() отображает nr_segs областей пользовательской памяти, описанных iov, в канал. Если fd открыт для чтения, то системный вызов vmsplice() заполняет nr_segs областей пользовательской памяти, описанных iov, из канала. Файловый дескриптор fd должен указывать на канал.

Указатель iov указывает на массив структур iovec, определённых в <sys/uio.h>:

    struct iovec {
        void  *iov_base;        /* начальный адрес */
        size_t iov_len;         /* количество байт */
    };

Аргумент flags представляет собой битовую маску, которая составляется логическим сложением (OR) следующих значений:

SPLICE_F_MOVE
    Не используется в vmsplice(); см. splice(2).

SPLICE_F_NONBLOCK
    Не блокировать ввод-вывод; подробности в splice(2).

SPLICE_F_MORE
    В данный момент никак не влияет при указании в vmsplice(), но это может измениться; см. splice(2).

SPLICE_F_GIFT
    Предоставить ядру пользовательские страницы. Приложение, возможно, не изменяло эту память, иначе страничный кэш и данные на диске будут различны. Передача страниц ядру означает, что последующий вызов splice(2) с флагом SPLICE_F_MOVE сможет переместить страницы; если этот флаг не указан, то последующий splice(2) с флагом SPLICE_F_MOVE должен скопировать страницы. Также, данные должны быть выровнены по странице: по адресам памяти и размеру.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении vmsplice() возвращается количество байт, переданных в канал. При ошибке vmsplice() возвращает -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EAGAIN
    В указан flags SPLICE_F_NONBLOCK, и операция вызвала бы блокировку.

EBADF
    Неправильное значение fd или оно не указывает на канал.

EINVAL
    Значение nr_segs больше IOV_MAX; или, если задан SPLICE_F_GIFT, не выровнена память.

ENOMEM
    Не хватает памяти.

ВЕРСИИ
Системный вызов vmsplice() впервые появился в Linux 2.6.17; поддержка в glibc добавлена в версии 2.5.

СООТВЕТСТВИЕ СТАНДАРТАМ
Данный вызов есть только в Linux.

ЗАМЕЧАНИЯ
Вызов vmsplice() следует другим функциям векторизованного чтения/записи при возникновении ограничений на количество передаваемых сегментов. Это ограничение равно IOV_MAX, определяемое в <limits.h>. Сейчас это значение равно 1024.

Настоящую стыковку vmsplice() поддерживает только для отображения пользовательской памяти в канал. В обратном направлении, в действительности, он просто копирует данные в пользовательское пространство. Но это делает интерфейс приятным и симметричным, и позволяет людям строить на vmsplice() с пространством будущего улучшения производительности.

СМОТРИТЕ ТАКЖЕ
splice(2), tee(2), pipe(7)