Scroll to navigation

copy_file_range(2) System Calls Manual copy_file_range(2)

الاسم

copy_file_range - نسخ نطاق من البيانات من ملف إلى آخر

المكتبة

مكتبة سي المعيارية (libc، -lc)

موجز

#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
ssize_t copy_file_range(int fd_in, off_t *_Nullable off_in,
                        int fd_out, off_t *_Nullable off_out,
                        size_t size, unsigned int flags);

الوصف

استدعاء النظام copy_file_range() ينفذ نسخًا داخل النواة بين واصفي ملفين دون التكلفة الإضافية لنقل البيانات من النواة إلى مساحة المستخدم ثم العودة إلى النواة. ينسخ حتى size بايت من البيانات من واصف الملف المصدر fd_in إلى واصف الملف الهدف fd_out، مع استبدال أي بيانات موجودة ضمن النطاق المطلوب من الملف الهدف.

تنطبق الدلالات التالية على off_in، وتنطبق عبارات مماثلة على off_out:

إذا كان off_in فارغًا (NULL)، تُقرأ البايتات من fd_in بدءًا من إزاحة الملف، ويُضبط إزاحة الملف بعدد البايتات المنسوخة.
إذا لم يكن off_in فارغًا (NULL)، يجب أن يشير off_in إلى مخزن مؤقت يحدد إزاحة البداية حيث ستُقرأ البايتات من fd_in. لا تتغير إزاحة ملف fd_in، لكن يُضبط off_in بشكل مناسب.

يمكن أن يشير fd_in و fd_out إلى نفس الملف. إذا كانا يشيران إلى نفس الملف، فلا يُسمح بتداخل نطاقي المصدر والهدف.

وُفر المعامل flags للسماح بالتوسعات المستقبلية ويجب ضبطه حاليًا على 0.

قيمة الإرجاع

عند الإكمال بنجاح، يُرجع copy_file_range() عدد البايتات المنسوخة بين الملفات. قد يكون هذا أقل من الحجم المطلوب أصلاً. إذا كانت إزاحة ملف fd_in عند نهاية الملف أو بعدها، لا تُنسخ أي بايتات، ويُرجع copy_file_range() صفرًا.

عند الخطأ، يُرجع copy_file_range() -1 ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

واصف ملف واحد أو أكثر غير صالح.
fd_in غير مفتوح للقراءة؛ أو fd_out غير مفتوح للكتابة.
عُيّنت علامة O_APPEND لوصف الملف المفتوح (انظر open(2)) المشار إليه بواصف الملف fd_out.
جرت محاولة للكتابة في موضع يتجاوز أقصى إزاحة ملف تدعمها النواة.
جرت محاولة لكتابة نطاق يتجاوز الحد الأقصى المسموح به لحجم الملف. يختلف الحد الأقصى لحجم الملف بين تطبيقات نظام الملفات ويمكن أن يكون مختلفًا عن أقصى إزاحة ملف مسموح بها.
جرت محاولة للكتابة تتجاوز حد مورد حجم ملف العملية. قد يؤدي هذا أيضًا إلى استلام العملية إشارة SIGXFSZ.
وسيطة flags ليست 0.
يشير fd_in و fd_out إلى نفس الملف وتتداخل نطاقات المصدر والهدف.
إما fd_in أو fd_out ليس ملفًا عاديًا.
حدث خطأ إدخال/إخراج منخفض المستوى أثناء النسخ.
إما fd_in أو fd_out يشير إلى دليل.
نفدت الذاكرة.
لا توجد مساحة كافية على نظام الملفات الهدف لإكمال النسخ.
نظام الملفات لا يدعم هذه العملية.
نطاق المصدر أو الوجهة المطلوب كبير جدًا بحيث لا يمكن تمثيله في أنواع البيانات المحددة.
fd_out يشير إلى ملف غير قابل للتغيير.
إما fd_in أو fd_out يشير إلى ملف مبادلة نشط.
الملفات المشار إليها بواسطة fd_in و fd_out ليست على نفس نظام الملفات.
الملفات المشار إليها بواسطة fd_in و fd_out ليست على نفس نظام الملفات، وأنظمة الملفات المصدر والهدف ليست من نفس النوع، أو لا تدعم النسخ عبر أنظمة الملفات.

الإصدارات

حدثت إعادة صياغة رئيسية لتنفيذ النواة في لينكس 5.3. تم توضيح مجالات واجهة برمجة التطبيقات التي لم تكن محددة بوضوح، ويتم فحص حدود واجهة برمجة التطبيقات بشكل أكثر صرامة من النوى السابقة.

منذ لينكس 5.19، يمكن تحقيق النسخ عبر أنظمة الملفات عندما يكون كلا نظامي الملفات من نفس النوع، وينفذ نظام الملفات ذلك الدعم. انظر BUGS للسلوك قبل لينكس 5.19.

يجب أن تستهدف التطبيقات سلوك ومتطلبات لينكس 5.19، والتي تم أيضًا نقلها إلى النوى المستقرة السابقة.

المعايير

لينكس، جنو.

التاريخ

لينكس 4.5.

قبل glibc 2.30، بدءًا من glibc 2.27، وفرت دالة الغلاف glibc تنفيذًا احتياطيًا في مساحة المستخدم عندما لم تنفذ النواة استدعاء النظام هذا. منذ glibc 2.30، تمت إزالة ذلك الاحتياطي؛ تفشل الدالة الآن مع ENOSYS إذا كانت النواة تفتقر إلى دعم .BR copy_file_range ().

ملاحظات

إذا كان fd_in ملفًا متناثرًا، فقد يقوم copy_file_range() بتوسيع أي ثغرات موجودة في النطاق المطلوب. قد يستفيد المستخدمون من استدعاء copy_file_range() في حلقة، واستخدام عمليات lseek(2) SEEK_DATA و SEEK_HOLE للعثور على مواقع مقاطع البيانات.

يمنح copy_file_range() أنظمة الملفات فرصة لتنفيذ تقنيات "تسريع النسخ"، مثل استخدام إعادة الروابط (أي اثنين أو أكثر من العقد التي تشترك في مؤشرات لنفس كتل القرص القابلة للنسخ عند الكتابة) أو النسخ من جانب الخادم (في حالة NFS).

يجب تعريف _FILE_OFFSET_BITS على أنه 64 في الكود الذي يستخدم off_in أو off_out غير فارغ أو الذي يأخذ عنوان copy_file_range، إذا كان الكود مخصصًا ليكون محمولاً إلى منصات x86 و ARM التقليدية 32 بت حيث يكون عرض off_t مبدئيًا 32 بت.

العلل

في لينكس 5.3 إلى لينكس 5.18، تم تنفيذ النسخ عبر أنظمة الملفات بواسطة النواة، إذا لم تكن العملية مدعومة من قبل أنظمة الملفات الفردية. ومع ذلك، في بعض أنظمة الملفات الافتراضية، فشل الاستدعاء في النسخ، مع الإبلاغ عن النجاح.

أمثلة

#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{

int fd_in, fd_out;
off_t size, ret;
struct stat stat;
if (argc != 3) {
fprintf(stderr, "الاستخدام: %s <المصدر> <الوجهة>\n", argv[0]);
exit(EXIT_FAILURE);
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in == -1) {
perror("open (argv[1])");
exit(EXIT_FAILURE);
}
if (fstat(fd_in, &stat) == -1) {
perror("fstat");
exit(EXIT_FAILURE);
}
size = stat.st_size;
fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd_out == -1) {
perror("open (argv[2])");
exit(EXIT_FAILURE);
}
do {
ret = copy_file_range(fd_in, NULL, fd_out, NULL, size, 0);
if (ret == -1) {
perror("copy_file_range");
exit(EXIT_FAILURE);
}
size -= ret;
} while (size > 0 && ret > 0);
close(fd_in);
close(fd_out);
exit(EXIT_SUCCESS); }

انظر أيضًا

lseek(2), sendfile(2), splice(2)

ترجمة

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

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

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

8 فبراير 2026 صفحات دليل لينكس 6.18