sendfile -
производит
обмен
данными
между
дескрипторами
файлов
Standard C library (
libc,
-lc)
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *_Nullable offset,
size_t count);
Вызов
sendfile()
копирует
данные из
одного
файлового
дескриптора
в другой.
Так как
копирование
производится
в ядре,
использование
sendfile() более
эффективно
чем
комбинация
read(2) и
write(2), в
которой
требуется
скопировать
данные в и
из
пользовательского
пространства.
В
in_fd должен
указываться
файловый
дескриптор,
открытый
для чтения,
а в
out_fd
должен
указываться
файловый
дескриптор,
открытый
для записи.
Если
значение
offset
не равно NULL,
то оно
указывает
на
переменную,
содержащую
файловое
смещение с
которого
sendfile() начнёт
чтение
данных из
in_fd. При
завершении
sendfile()
значение
этой
переменной
будет
содержать
смещение
следующего
байта
после
последнего
прочитанного.
Если
значение
offset
не равно NULL,
то
sendfile() не
изменяет
файловое
смещение
in_fd;
иначе
файловое
смещение
изменяется
для
отражения
количества
прочитанных
из
in_fd байт.
Если
значение
offset
равно NULL, то
данные
будут
прочитаны
из
in_fd
начиная с
файлового
смещения, и
по
окончании
работы
вызова
файловое
смещение
будет
обновлено.
В
count
содержится
количество
байт,
копируемых
между
файловыми
дескрипторами.
Значение
in_fd
должно
описывать
файл,
который
поддерживает
операции
типа
mmap(2) (т.е.,
не сокет).
Before Linux 2.6.33,
out_fd must refer to a socket. Since Linux 2.6.33 it
can be any file. If it is a regular file, then
sendfile() changes the
file offset appropriately.
Если
пересылка
прошла
успешно, то
возвращается
количество
записанных
в
out_fd байт.
Заметим,
что при
успешном
выполнении
вызов
sendfile()
может
записать
меньше
байт, чем
запрашивалось;
вызывающий
должен
быть готов
повторить
вызов, если
останутся
не
отправленные
байты.
Также
смотрите
ЗАМЕЧАНИЯ.
В случае
ошибки
возвращается
-1, а
errno
устанавливается
в значение
ошибки.
- EAGAIN
- Был
выбран
неблокирующий
ввод-вывод
с помощью
O_NONBLOCK, но
запись
привела бы
блокировке.
- EBADF
- Входной
файл не
открыт для
чтения или
выходной
файл не
открыт для
записи.
- EFAULT
- Неправильный
адрес.
- EINVAL
- Неправильный
или
заблокированный
дескриптор,
или для in_fd
недоступна
операция
типа mmap(2) или
значение
count
отрицательно.
- EINVAL
- У out_fd
установлен
флаг O_APPEND.
Пока это не
поддерживается
в sendfile().
- EIO
- Неизвестная
ошибка при
чтении in_fd.
- ENOMEM
- Не
хватает
памяти для
чтения in_fd.
- EOVERFLOW
- Значение
count слишком
велико,
операция
вернула бы
результат,
превышающий
максимальный
размер
входного
или
выходного
файла.
- ESPIPE
-
offset is not NULL but the input file is not
seekable.
Вызов
sendfile()
впервые
появился в
Linux 2.2. Файл
заголовков
<sys/sendfile.h>
появился в
glibc 2.1.
Отсутствует
в POSIX.1-2001 и
других
стандартах.
В других
системах UNIX
вызов
sendfile()
реализован
с другими
семантиками
и
прототипами.
Не должен
использоваться
в
переносимых
программах.
Вызов
sendfile()
передаст
не больше 0x7ffff000
(2 147 479 552) байт,
возвращая
число байт,
переданных
на самом
деле (это
утверждение
справедливо
как к
32-битным, так
и к 64-битным
системам).
Если вы
планируете
использовать
sendfile() для
отправки
файлов
через
сокет TCP и вам
нужно
послать
некоторые
заголовочные
данные
перед
содержимым
файла, то
обратите
внимание
на
параметр
TCP_CORK,
описанный
в
tcp(7), он
поможет
минимизировать
количество
пакетов и
оптимизировать
производительность.
В Linux 2.4 и более
ранних,
значение
out_fd
может
также
указывать
на обычный
файл; эта
возможность
была
удалена в
ядрах Linux 2.6.x, но
возвращена
в 2.6.33.
Первоначальная
версия Linux
sendfile()
не была
приспособлена
для работы
с большими
файловыми
смещениями.
В
последствии
в Linux 2.4 был
добавлен
вызов
sendfile64() с
более
широким
диапазоном
значений
аргумента
offset. В glibc
sendfile()
представляет
собой
обёрточную
функцию,
которая
делает
незаметным
разницу
между
версиями
ядер.
Applications may wish to fall back to
read(2) and
write(2) in the
case where
sendfile() fails with
EINVAL or
ENOSYS.
Если
out_fd
ссылается
на сокет
или канал с
поддержкой
нулевого
копирования,
то
вызывающие
должны
гарантировать,
что
переданные
части
файла,
указываемого
in_fd,
останутся
неизменёнными
до тех пор,
пока
читающий
на другом
конце
out_fd не
закончит
обрабатывать
переданные
данные.
Специальный
вызов Linux
splice(2)
поддерживает
пересылку
данных
между
произвольными
файловыми
дескрипторами,
представляющими
сокеты
(один или
оба).
copy_file_range(2),
mmap(2),
open(2),
socket(2),
splice(2)
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]