Provided by: manpages-ru-dev_4.19.0-7_all bug

ИМЯ

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

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

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

       ssize_t splice(int fd_in, off64_t *_Nullable off_in,
                      int fd_out, off64_t *_Nullable 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 указывает на канал, то это
       означает, что нет данных для передачи и и блокировка не  имела  бы  смысла,  так  как  нет
       писателей, подключённых к пишущему концу канала.

       В  случае  ошибки  splice()  возвращает  -1,  а  errno  устанавливается  в соответствующее
       значение.

ОШИБКИ

       EAGAIN В flags указан SPLICE_F_NONBLOCK или один из файловых дескрипторов был помечен  как
              неблокирующий (O_NONBLOCK), и операция вызвала бы блокировку.

       EBADF  Один  или  оба  файловых  дескриптора  недействительны  или  в  неправильном режиме
              чтения-записи.

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

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

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

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

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

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

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

ВЕРСИИ

       The  splice()   system  call  first appeared in Linux 2.6.17; library support was added in
       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)

ПЕРЕВОД

       Русский    перевод    этой    страницы    руководства   был   сделан   Alexander   Golubev
       <fatzer2@gmail.com>,  Azamat  Hackimov  <azamat.hackimov@gmail.com>,   Hotellook,   Nikita
       <zxcvbnm3230@mail.ru>,       Spiros       Georgaras       <sng@hellug.gr>,       Vladislav
       <ivladislavefimov@gmail.com>,   Yuri   Kozlov   <yuray@komyakino.ru>   и    Иван    Павлов
       <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы  обнаружите  ошибки  в  переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.