SPLICE(2) | Руководство программиста Linux | SPLICE(2) |
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_out и off_out.
Аргумент flags представляет собой битовую маску, которая составляется логическим сложением (OR) следующих значений:
При успешном выполнении splice() возвращает количество байт, которые были записаны или получены из канала.
Возвращаемое значение 0 означает конец ввода. Если fd_in указывает на канал, то это означает, что нет данных для передачи и и блокировка не имела бы смысла, так как нет писателей, подключённых к пишущему концу канала.
В случае ошибки splice() возвращает -1, а errno устанавливается в соответствующее значение.
Системный вызов splice() впервые появился в Linux 2.6.17; поддержка в glibc добавлена в версии 2.5.
Данный вызов есть только в Linux.
Три системных вызова — splice(), vmsplice(2), and tee(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)
2017-09-15 | Linux |