sendfile(2)

الاسم
sendfile - نقل البيانات بين واصفات الملفات

المكتبة
مكتبة سي المعيارية (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) (أي لا يمكن أن يكون مقبسًا). باستثناء منذ Linux 5.12 وإذا كان out_fd أنبوبًا، ففي هذه الحالة يتحول sendfile() إلى splice(2) وتنطبق قيوده.

قبل Linux 2.6.33، يجب أن يشير out_fd إلى مقبس. منذ Linux 2.6.33 يمكن أن يكون أي ملف. إذا كان قابلاً للبحث، فإن sendfile() يغير إزاحة الملف بشكل مناسب.

قيمة الإرجاع
إذا كان النقل ناجحًا، يتم إرجاع عدد البايتات المكتوبة إلى out_fd. لاحظ أن استدعاء ناجح لـ sendfile() قد يكتب بايتات أقل من المطلوب؛ يجب أن يكون المستدعي مستعدًا لإعادة الاستدعاء إذا كانت هناك بايتات غير مرسلة. انظر أيضًا الملاحظات.

عند الخطأ، تُعاد القيمة -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EAGAIN
    تم تحديد الإدخال/الإخراج غير المحظور باستخدام O_NONBLOCK وستؤدي الكتابة إلى الحظر.

EBADF
    لم يتم فتح ملف الإدخال للقراءة أو لم يتم فتح ملف الإخراج للكتابة.

EFAULT
    عنوان سيء.

EINVAL
    الواصف غير صالح أو مقفل، أو عملية مشابهة لـ mmap(2) غير متاحة لـ in_fd، أو count سالب.

EINVAL
    out_fd لديه العلم O_APPEND مضبوطًا. هذا غير مدعوم حاليًا بواسطة sendfile().

EIO خطأ غير محدد أثناء القراءة من in_fd.

ENOMEM
    ذاكرة غير كافية للقراءة من in_fd.

EOVERFLOW
    count كبير جدًا، ستؤدي العملية إلى تجاوز الحد الأقصى لحجم ملف الإدخال أو ملف الإخراج.

ESPIPE
    offset ليس NULL ولكن ملف الإدخال غير قابل للبحث.

الإصدارات
تنفذ أنظمة UNIX الأخرى sendfile() بدلالات ونماذج أولية مختلفة. لا ينبغي استخدامه في البرامج المحمولة.

المعايير
لا شيء.

التاريخ
Linux 2.2, glibc 2.1.

في Linux 2.4 والإصدارات الأقدم، يمكن أن يشير out_fd أيضًا إلى ملف عادي؛ اختفت هذه الإمكانية في سلسلة نواة Linux 2.6.x، ولكن تمت استعادتها في Linux 2.6.33.

لم يتم تصميم استدعاء النظام الأصلي Linux sendfile() للتعامل مع إزاحات الملفات الكبيرة. وبالتالي، أضاف Linux 2.4 sendfile64()، بنوع أوسع لوسيطة offset. تتعامل دالة الغلاف glibc sendfile() بشكل شفاف مع اختلافات النواة.

ملاحظات
سينقل sendfile() على الأكثر 0x7ffff000 (2,147,479,552) بايت، مع إرجاع عدد البايتات المنقولة فعليًا. (هذا صحيح على كل من الأنظمة 32 بت و64 بت.)

إذا كنت تخطط لاستخدام sendfile() لإرسال الملفات إلى مقبس TCP، ولكنك تحتاج إلى إرسال بعض بيانات الرأس أمام محتويات الملف، فستجد أنه من المفيد استخدام خيار TCP_CORK، الموصوف في tcp(7)، لتقليل عدد الحزم وضبط الأداء.

قد ترغب التطبيقات في الرجوع إلى read(2) و write(2) في حالة فشل sendfile() مع EINVAL أو ENOSYS.

إذا كان out_fd يشير إلى مقبس أو أنبوب مع دعم النسخ الصفري، يجب على المستدعيين ضمان بقاء الأجزاء المنقولة من الملف المشار إليه بواسطة in_fd غير معدلة حتى يستهلك القارئ على الطرف الآخر من out_fd البيانات المنقولة.

استدعاء splice(2) الخاص بـ Linux يدعم نقل البيانات بين واصفات ملفات عشوائية بشرط أن يكون واحد (أو كليهما) منهما أنبوبًا.

انظر أيضًا
copy_file_range(2)، mmap(2)، open(2)، socket(2)، splice(2)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.