Главная » 2017 » Ноябрь » 24 » man 2 splice
05:31
man 2 splice

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


splice - подключает данные к каналу/выбирает данные из канала



ОБЗОР


#define _GNU_SOURCE /* см. feature_test_macros(7) */
#include <fcntl.h>

ssize_t splice(int fd_in, loff_t *off_in, int fd_out,
loff_t *off_out, size_t len, unsigned int flags);



ОПИСАНИЕ


Вызов splice() перемещает данные между двумя файловыми дескрипторами не выполняя при этом
копирование между адресным пространством пользователя и ядра. Он пересылает до len байт
данных из файлового дескриптора fd_in в файловый дескриптор fd_out, где один из файловых
дескрипторов должен ссылаться на канал.

К fd_in и off_in применяются следующие правила:

* Если fd_in указывает на канал, то значение off_in должно быть NULL.

* Если fd_in не указывает на канал и off_in равно NULL, то из fd_in читаются байты начиная
с смещения файла и это смещение соответственно изменяется.

* Если fd_in не указывает на канал и off_in не равно NULL, то off_in должен указывать на
буфер, в котором задаётся начальное смещение для чтения байтов из fd_in; в этом случае
файловое смещение fd_in не изменяется.

Аналогичные правила относятся и к fd_out и off_out.

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

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

SPLICE_F_NONBLOCK Не блокировать при вводе-выводе. Это делает операции соединения с каналом
неблокируемыми, но splice(), тем не менее, может заблокироваться, так как
файловые дескрипторы, с которыми ведётся работа, могут блокироваться
(если у них не установлен флаг O_NONBLOCK).

SPLICE_F_MORE В следующем подключении будут дополнительные данные. Полезно указывать,
когда fd_out ссылается на сокет (смотрите также описание MSG_MORE в
send(2) и описание TCP_CORK в tcp(7)).

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



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ


При успешном выполнении splice() возвращает количество байт, которые были записаны или
получены из канала.

Возвращаемое значение 0 означает конец ввода. Если fd_in указывает на канал, то это
означает, что нет данных для передачи и и блокировка не имела бы смысла, так как нет

EINVAL Целевая файловая система не поддерживает подключение данных (splicing).

EINVAL Файл назначения открыт в режиме добавления.

EINVAL Ни один из файловых дескрипторов не ссылается на канал.

EINVAL Указано смещение для устройства этого не поддерживающего (например, канала).

EINVAL Значение fd_in и fd_out указывают на один и тот же канал.

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

ESPIPE Значение off_in или off_out не равно NULL, но соответствующий файловый дескриптор
ссылается на канал.



ВЕРСИИ


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



СООТВЕТСТВИЕ СТАНДАРТАМ


Данный вызов есть только в Linux.



ЗАМЕЧАНИЯ


Три системных вызова — splice(), vmsplice(2), and tee(2), предоставляют пользовательским
программам полный контроль над произвольным буфером ядра; они реализованы в ядре на базе
того же типа буферов, который используется для канала. Эти системные вызовы выполняют
следующие задачи:

splice() перемещает данные из буфера в произвольный файловый дескриптор или наоборот, и
из одного буфера в другой.

tee(2) «копирует» данные из одного буфера в другой.

vmsplice(2) «копирует» данные из пользовательского пространства в буфер.

Хотя мы говорим о копировании, на самом деле копирования, обычно, не происходит. Ядро
реализует канальный буфер как набор указателей со счётчиком ссылок на страницы памяти ядра.
Ядро создаёт «копии» страниц в буфере посредством создания новых указателей (для выходного
буфера), указывающих на страницы, и увеличивает счётчики ссылок страниц: копируются только
указатели, а не страницы буфера.

В Linux 2.6.30 и старее, только один из fd_in и fd_out должен быть каналом. Начиная с Linux
2.6.31 оба параметра должны быть каналами.



ПРИМЕР


См. tee(2).



СМОТРИТЕ ТАКЖЕ


copy_file_range(2), sendfile(2), tee(2), vmsplice(2), pipe(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 450 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar