open(2)

الاسم
open، openat، creat - فتح ملف وربما إنشاؤه

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

موجز
#include <fcntl.h>

int open(const char *المسار, int الأعلام, ...
           /* mode_t الوضع */ );

int creat(const char *المسار, mode_t الوضع);

int openat(int واصف_دليل, const char *المسار, int الأعلام, ...
           /* mode_t الوضع */ );

/* وُثقت منفصلة في openat2(2):
 */
int openat2(int واصف_دليل, const char *المسار,
           const struct open_how *الكيفية, size_t الحجم);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

openat():
    منذ glibc 2.10:
        _POSIX_C_SOURCE >= 200809L
    قبل glibc 2.10:
        _ATFILE_SOURCE

الوصف
يفتح استدعاء النظام open() الملف المحدد بواسطة المسار. إذا كان الملف المحدد غير موجود، فيمكن اختيارياً (إذا حُدد O_CREAT في الأعلام) أن يُنشأ بواسطة open().

قيمة الإرجاع لـ open() هي واصف ملف، وهو عدد صحيح صغير غير سالب يمثل فهرساً لمدخل في جدول واصفات الملفات المفتوحة للعملية. يُستخدم واصف الملف في استدعاءات النظام اللاحقة (read(2)، write(2)، lseek(2)، fcntl(2)، إلخ) للإشارة إلى الملف المفتوح. سيكون واصف الملف الذي يعيده استدعاء ناجح هو واصف الملف ذو الرقم الأقل غير المفتوح حالياً للعملية.

افتراضياً، يُضبط واصف الملف الجديد ليظل مفتوحاً عبر execve(2) (أي أن علم واصف الملف FD_CLOEXEC الموصوف في fcntl(2) يكون معطلاً في البداية)؛ يمكن استخدام العلم O_CLOEXEC، الموصوف أدناه، لتغيير هذا المبدأ. يُضبط إزاحة الملف على بداية الملف (انظر lseek(2)).

يؤدي استدعاء open() إلى إنشاء وصف ملف مفتوح جديد، وهو مدخل في الجدول العام للملفات المفتوحة على مستوى النظام. يسجل وصف الملف المفتوح إزاحة الملف وأعلام حالة الملف (انظر أدناه). واصف الملف هو مرجع لوصف ملف مفتوح؛ ولا يتأثر هذا المرجع إذا حُذف المسار لاحقًا أو عُدل ليشير إلى ملف مختلف. لمزيد من التفاصيل حول أوصاف الملفات المفتوحة، انظر الملاحظات (NOTES).

يجب أن يتضمن المعامل الأعلام أحد أوضاع الوصول التالية: O_RDONLY أو O_WRONLY أو O_RDWR. تطلب هذه الأوضاع فتح الملف للقراءة فقط، أو للكتابة فقط، أو للقراءة والكتابة، على التوالي.

بالإضافة إلى ذلك، يمكن إجراء عملية OR بتية لصفر أو أكثر من أعلام إنشاء الملف وأعلام حالة الملف في الأعلام. أعلام إنشاء الملف هي O_CLOEXEC و O_CREAT و O_DIRECTORY و O_EXCL و O_NOCTTY و O_NOFOLLOW و O_TMPFILE و O_TRUNC. أعلام حالة الملف هي جميع الأعلام المتبقية المدرجة أدناه. الفرق بين هاتين المجموعتين من الأعلام هو أن أعلام إنشاء الملف تؤثر على دلالات عملية الفتح نفسها، بينما تؤثر أعلام حالة الملف على دلالات عمليات الإدخال/الإخراج اللاحقة. يمكن استرداد أعلام حالة الملف وتعديلها (في بعض الحالات)؛ انظر fcntl(2) للتفاصيل.

القائمة الكاملة لأعلام إنشاء الملف وأعلام حالة الملف هي كما يلي:

O_APPEND
    يُفتح الملف في وضع الإلحاق. قبل كل عملية write(2)، يتم وضع إزاحة الملف عند نهاية الملف، كما هو الحال مع lseek(2). يتم تنفيذ تعديل إزاحة الملف وعملية الكتابة كخطوة ذرية واحدة.

    قد يؤدي O_APPEND إلى ملفات تالفة على أنظمة ملفات NFS إذا قامت أكثر من عملية بإلحاق بيانات بملف في وقت واحد. هذا لأن NFS لا يدعم الإلحاق بملف، لذا يتعين على نواة العميل محاكاته، وهو ما لا يمكن القيام به دون حالة تسابق.

O_ASYNC
    تمكين الإدخال/الإخراج المدفوع بالإشارات: توليد إشارة (SIGIO افتراضياً، ولكن يمكن تغيير ذلك عبر fcntl(2)) عندما يصبح الإدخال أو الإخراج ممكناً على واصف الملف هذا. هذه الميزة متاحة فقط للأطراف، والأطراف الوهمية، والمقابس، و(منذ لينكس 2.6) الأنابيب و FIFOs. انظر fcntl(2) لمزيد من التفاصيل. انظر أيضًا العلل (BUGS) أدناه.

O_CLOEXEC (منذ لينكس 2.6.23)
    تمكين علم الغلق-عند-التنفيذ (close-on-exec) لواصف الملف الجديد. يسمح تحديد هذا العلم للبرنامج بتجنب عمليات fcntl(2) F_SETFD إضافية لضبط علم FD_CLOEXEC.

    لاحظ أن استخدام هذا العلم ضروري في بعض البرامج متعددة الخيوط، لأن استخدام عملية fcntl(2) F_SETFD منفصلة لضبط علم FD_CLOEXEC لا يكفي لتجنب حالات التسابق حيث يفتح أحد الخيوط واصف ملف ويحاول ضبط علم الغلق-عند-التنفيذ الخاص به باستخدام fcntl(2) في نفس الوقت الذي يقوم فيه خيط آخر بعمل fork(2) بالإضافة إلى execve(2). اعتماداً على ترتيب التنفيذ، قد يؤدي التسابق إلى تسريب واصف الملف الذي أعاده open() عن غير قصد إلى البرنامج الذي تنفذه العملية الابن التي أنشأها fork(2). (هذا النوع من التسابق ممكن من حيث المبدأ لأي استدعاء نظام ينشئ واصف ملف يجب ضبط علم الغلق-عند-التنفيذ الخاص به، وتوفر العديد من استدعاءات نظام لينكس الأخرى مقابلاً لعلم O_CLOEXEC للتعامل مع هذه المشكلة).

O_CREAT
    إذا كان المسار غير موجود، فيُنشأ كملف عادي.

    يُضبط مالك (معرف المستخدم) الملف الجديد على معرف المستخدم الفعلي للعملية.

    يُضبط مالك المجموعة (معرف المجموعة) للملف الجديد إما على معرف المجموعة الفعلي للعملية (دلالات System V) أو على معرف المجموعة للدليل الأب (دلالات BSD). على لينكس، يعتمد السلوك على ما إذا كانت بتة وضع set-group-ID مضبوطة على الدليل الأب: إذا كانت تلك البتة مضبوطة، فستُطبق دلالات BSD؛ وإلا فتُطبق دلالات System V. بالنسبة لبعض أنظمة الملفات، يعتمد السلوك أيضًا على خيارات الوصل bsdgroups و sysvgroups الموصوفة في mount(8).

    يحدد المعامل الوضع بتات وضع الملف التي ستُطبق عند إنشاء ملف جديد. إذا لم يُحدد O_CREAT ولا O_TMPFILE في الأعلام، فيتم تجاهل الوضع (وبالتالي يمكن تحديده كـ 0، أو حذفه ببساطة). يجب توفير المعامل الوضع إذا حُدد O_CREAT أو O_TMPFILE في الأعلام؛ وإذا لم يتم توفيره، فستُطبق بعض البايتات العشوائية من المكدس كوضع للملف.

    يُعدل الوضع الفعلي بواسطة umask للعملية بالطريقة المعتادة: في حالة عدم وجود ACL مبدئي، يكون وضع الملف المنشأ هو (الوضع & ~umask).

    لاحظ أن الوضع ينطبق فقط على الوصول المستقبلي للملف المنشأ حديثاً؛ قد يعيد استدعاء open() الذي ينشئ ملفاً للقراءة فقط واصف ملف للقراءة والكتابة.

    تتوفر الثوابت الرمزية التالية لـ الوضع:

    S_IRWXU
        00700 يمتلك المستخدم (مالك الملف) أذونات القراءة والكتابة والتنفيذ

    S_IRUSR
        00400 يمتلك المستخدم إذن القراءة

    S_IWUSR
        00200 يمتلك المستخدم إذن الكتابة

    S_IXUSR
        00100 يمتلك المستخدم إذن التنفيذ

    S_IRWXG
        00070 تمتلك المجموعة أذونات القراءة والكتابة والتنفيذ

    S_IRGRP
        00040 تمتلك المجموعة إذن القراءة

    S_IWGRP
        00020 تمتلك المجموعة إذن الكتابة

    S_IXGRP
        00010 تمتلك المجموعة إذن التنفيذ

    S_IRWXO
        00007 يمتلك الآخرون أذونات القراءة والكتابة والتنفيذ

    S_IROTH
        00004 يمتلك الآخرون إذن القراءة

    S_IWOTH
        00002 يمتلك الآخرون إذن الكتابة

    S_IXOTH
        00001 يمتلك الآخرون إذن التنفيذ

    وفقاً لـ POSIX، يكون التأثير عند ضبط بتات أخرى في الوضع غير محدد. على لينكس، تُحترم أيضًا البتات التالية في الوضع:

    S_ISUID
        0004000 بتة set-user-ID

    S_ISGID
        0002000 بتة set-group-ID (انظر inode(7)).

    S_ISVTX
        0001000 البتة اللاصقة (sticky bit) (انظر inode(7)).

O_DIRECT (منذ لينكس 2.4.10)
    محاولة تقليل آثار الخبيئة للإدخال/الإخراج من وإلى هذا الملف. بشكل عام، سيؤدي ذلك إلى تدهور الأداء، ولكنه مفيد في حالات خاصة، مثل عندما تقوم التطبيقات بعمليات التخبئة الخاصة بها. يتم الإدخال/الإخراج للملف مباشرة من/إلى مخازن مساحة المستخدم. يبذل العلم O_DIRECT بمفرده جهداً لنقل البيانات بشكل متزامن، ولكنه لا يعطي ضمانات العلم O_SYNC بأن البيانات والبيانات الوصفية اللازمة قد نُقلت. لضمان إدخال/إخراج متزامن، يجب استخدام O_SYNC بالإضافة إلى O_DIRECT. انظر الملاحظات (NOTES) أدناه لمزيد من النقاش.

    وُصفت واجهة مشابهة دلالياً (ولكنها مهجورة) للأجهزة الكتلية في raw(8).

O_DIRECTORY
    إذا لم يكن المسار دليلاً، فسيؤدي ذلك إلى فشل open(). أُضيف هذا العلم في لينكس 2.1.126، لتجنب مشاكل الحرمان من الخدمة إذا استُدعي opendir(3) على FIFO أو جهاز شريط.

O_DSYNC
    ستكتمل عمليات الكتابة على الملف وفقاً لمتطلبات اكتمال سلامة بيانات الإدخال/الإخراج المتزامنة.

    بحلول وقت عودة write(2) (وما شابه)، تكون بيانات المخرج قد نُقلت إلى العتاد الأساسي، إلى جانب أي بيانات وصفية للملف قد تكون مطلوبة لاسترداد تلك البيانات (أي كما لو أن كل عملية write(2) تبعها استدعاء لـ fdatasync(2)). انظر الإصدارات (VERSIONS).

O_EXCL
    التأكد من أن هذا الاستدعاء ينشئ الملف: إذا حُدد هذا العلم بالاقتران مع O_CREAT، وكان المسار موجوداً بالفعل، فسيَفشل open() مع الخطأ EEXIST.

    عند تحديد هذين العلمين، لا تُتبع الروابط الرمزية: إذا كان المسار رابطاً رمزياً، فسيَفشل open() بغض النظر عن المكان الذي يشير إليه الرابط الرمزي.

    بشكل عام، يكون سلوك O_EXCL غير محدد إذا استُخدم بدون O_CREAT. هناك استثناء واحد: في لينكس 2.6 وما بعده، يمكن استخدام O_EXCL بدون O_CREAT إذا كان المسار يشير إلى جهاز كتلي. إذا كان الجهاز الكتلي قيد الاستخدام من قبل النظام (مثلاً، موصول)، فسيَفشل open() مع الخطأ EBUSY.

    على NFS، يُدعم O_EXCL فقط عند استخدام NFSv3 أو أحدث على نواة 2.6 أو أحدث. في بيئات NFS حيث لا يتوفر دعم O_EXCL، فإن البرامج التي تعتمد عليه لأداء مهام القفل ستحتوي على حالة تسابق. يمكن للبرامج المنقولة التي تريد إجراء قفل ملف ذري باستخدام ملف قفل، وتحتاج إلى تجنب الاعتماد على دعم NFS لـ O_EXCL، أن تنشئ ملفاً فريداً على نفس نظام الملفات (مثلاً، بدمج اسم المضيف ومعرف العملية)، واستخدام link(2) لعمل رابط لملف القفل. إذا أعاد link(2) القيمة 0، فقد نجح القفل. وإلا، فاستخدم stat(2) على الملف الفريد للتحقق مما إذا كان عدد روابطه قد زاد إلى 2، وفي هذه الحالة يكون القفل قد نجح أيضًا.

O_LARGEFILE
    (LFS) السماح بفتح الملفات التي لا يمكن تمثيل أحجامها في off_t (ولكن يمكن تمثيلها في off64_t). يجب تعريف ماكرو _LARGEFILE64_SOURCE (قبل تضمين أي ملفات ترويسة) للحصول على هذا التعريف. إن ضبط ماكرو اختبار الميزات _FILE_OFFSET_BITS على 64 (بدلاً من استخدام O_LARGEFILE) هو الطريقة المفضلة للوصول إلى الملفات الكبيرة على الأنظمة ذات 32 بت (انظر feature_test_macros(7)).

O_NOATIME (منذ لينكس 2.6.8)
    عدم تحديث وقت آخر وصول للملف (st_atime في inode) عندما يُقرأ الملف بواسطة read(2).

    يمكن توظيف هذا العلم فقط إذا تحقق أحد الشروط التالية:

    •   معرف المستخدم الفعلي للعملية يطابق معرف المستخدم لمالك الملف.

    •   العملية المستدعِية تمتلك قدرة CAP_FOWNER في فضاء أسماء المستخدم الخاص بها ومعرف المستخدم لمالك الملف لديه تعيين (mapping) في فضاء الأسماء.

    هذا العلم مخصص للاستخدام من قبل برامج الفهرسة أو النسخ الاحتياطي، حيث يمكن لاستخدامه أن يقلل بشكل كبير من مقدار نشاط القرص. قد لا يكون هذا العلم فعالاً على جميع أنظمة الملفات. أحد الأمثلة هو NFS، حيث يحتفظ الخادم بوقت الوصول.

O_NOCTTY
    إذا كان المسار يشير إلى جهاز طرفي—انظر tty(4)—فلن يصبح الطرفية المتحكمة في العملية حتى لو لم يكن للعملية واحدة.

O_NOFOLLOW
    إذا كان المكون الأخير (أي الاسم الأساسي) لـ المسار رابطاً رمزياً، فسيَفشل الفتح مع الخطأ ELOOP. ستظل الروابط الرمزية في المكونات السابقة لاسم المسار تُتتبع. (لاحظ أن خطأ ELOOP الذي يمكن أن يحدث في هذه الحالة لا يمكن تمييزه عن الحالة التي يفشل فيها الفتح لوجود عدد كبير جداً من الروابط الرمزية أثناء حل المكونات في بادئة المسار لاسم المسار).

    هذا العلم هو امتداد لـ FreeBSD، أُضيف في لينكس 2.1.126، ووُحد لاحقًا في POSIX.1-2008.

    انظر أيضًا O_PATH أدناه.

O_NONBLOCK أو O_NDELAY
    يُفتح الملف في وضع غير مانع (nonblocking) كلما أمكن ذلك. لن يتسبب استدعاء open() ولا أي عمليات إدخال/إخراج لاحقة على واصف الملف المعاد في جعل عملية الاستدعاء تنتظر.

    لاحظ أن ضبط هذه العلامة ليس له أي تأثير على عمل poll(2) و select(2) و epoll(7) وما شابهها، بما أن تلك الواجهات تكتفي بإبلاغ المستدعِي بما إذا كان واصف الملف "جاهزًا"، وهو ما يعني أن عملية إدخال/إخراج تُجرى على واصف الملف مع مسح علامة O_NONBLOCK لن تمنع (block).

    لاحظ أن هذه العلامة ليس لها أي تأثير على الملفات العادية والأجهزة الكتلية؛ أي أن عمليات الإدخال/الإخراج ستُمنع (لفترة وجيزة) عندما يتطلب الأمر نشاطًا للجهاز، بغض النظر عما إذا كان قد ضُبطت O_NONBLOCK. بما أن دلالات O_NONBLOCK قد تُطبق في نهاية المطاف، فلا ينبغي للتطبيقات أن تعتمد على سلوك المنع عند تحديد هذه العلامة للملفات العادية والأجهزة الكتلية.

    للتعامل مع الأنابيب المسماة (FIFOs)، انظر أيضًا fifo(7). لمناقشة تأثير O_NONBLOCK بالاقتران مع أقفال الملفات الإلزامية وعقود إيجار الملفات، انظر fcntl(2).

O_PATH (منذ لينكس 2.6.39)
    الحصول على واصف ملف يمكن استخدامه لغرضين: للإشارة إلى موقع في شجرة نظام الملفات، ولإجراء عمليات تعمل فقط على مستوى واصف الملف. لا يُفتح الملف نفسه، وتفشل عمليات الملف الأخرى (مثل read(2) و write(2) و fchmod(2) و fchown(2) و fgetxattr(2) و ioctl(2) و mmap(2)) بالخطأ EBADF.

    العمليات التالية يمكن إجراؤها على واصف الملف الناتج:

    •   close(2).

    •   fchdir(2)، إذا كان واصف الملف يشير إلى دليل (منذ لينكس 3.5).

    •   fstat(2) (منذ لينكس 3.6).

    •   fstatfs(2) (منذ لينكس 3.12).

    •   مضاعفة واصف الملف (dup(2)، fcntl(2) F_DUPFD، وما إلى ذلك).

    •   جلب وضبط علامات واصف الملف (fcntl(2) F_GETFD و F_SETFD).

    •   استرجاع علامات حالة الملف المفتوح باستخدام عملية fcntl(2) F_GETFL: ستتضمن العلامات المعادة البت O_PATH.

    •   تمرير واصف الملف كمعامل dirfd لـ openat() واستدعاءات النظام الأخرى "*at()". يتضمن ذلك linkat(2) مع AT_EMPTY_PATH (أو عبر procfs باستخدام AT_SYMLINK_FOLLOW) حتى لو لم يكن الملف دليلاً.

    •   تمرير واصف الملف إلى عملية أخرى عبر مقبس نطاق يونكس (انظر SCM_RIGHTS في unix(7)).

    عند تحديد O_PATH في flags، تُتجاهل بتات العلامات الأخرى باستثناء O_CLOEXEC و O_DIRECTORY و O_NOFOLLOW.

    فتح ملف أو دليل باستخدام العلامة O_PATH لا يتطلب أي أذونات على الكائن نفسه (ولكنه يتطلب إذن التنفيذ على الأدلة في بادئة المسار). اعتمادًا على العملية اللاحقة، قد يُجرى فحص لأذونات الملف المناسبة (على سبيل المثال، يتطلب fchdir(2) إذن التنفيذ على الدليل المشار إليه بواسطة معامل واصف الملف الخاص به). في المقابل، يتطلب الحصول على مرجع لكائن نظام ملفات عن طريق فتحه بالعلامة O_RDONLY أن يكون لدى المستدعِي إذن القراءة على الكائن، حتى عندما لا تتطلب العملية اللاحقة (مثل fchdir(2) و fstat(2)) إذن القراءة على الكائن.

    إذا كان path وصلة رمزية وحُددت أيضًا العلامة O_NOFOLLOW، فحينئذٍ يعيد الاستدعاء واصف ملف يشير إلى الوصلة الرمزية. يمكن استخدام واصف الملف هذا كمعامل dirfd في استدعاءات fchownat(2) و fstatat(2) و linkat(2) و readlinkat(2) مع مسار فارغ لجعل الاستدعاءات تعمل على الوصلة الرمزية.

    إذا كان path يشير إلى نقطة وصل آلي لم تُحفز بعد، بحيث لا يوجد نظام ملفات آخر موصول عليها، فإن الاستدعاء يعيد واصف ملف يشير إلى دليل الوصل الآلي دون تحفيز عملية وصل. يمكن بعد ذلك استخدام fstatfs(2) لتحديد ما إذا كانت في الواقع نقطة وصل آلي غير محفزة (.f_type == AUTOFS_SUPER_MAGIC).

    أحد استخدامات O_PATH للملفات العادية هو توفير ما يعادل وظيفة O_EXEC في POSIX.1. يسمح لنا ذلك بفتح ملف نملك إذن تنفيذه ولكن ليس لدينا إذن قراءته، ثم تنفيذ ذلك الملف بخطوات تشبه ما يلي:

        char buf[PATH_MAX];
        fd = open("some_prog", O_PATH);
        snprintf(buf, PATH_MAX, "/proc/self/fd/%d", fd);
        execl(buf, "some_prog", (char *) NULL);

    يمكن أيضًا تمرير واصف ملف O_PATH كمعامل لـ fexecve(3).

O_SYNC
    ستكتمل عمليات الكتابة على الملف وفقًا لمتطلبات إكمال سلامة ملف الإدخال/الإخراج المتزامن (على عكس إكمال سلامة بيانات الإدخال/الإخراج المتزامن الذي توفره O_DSYNC.)

    بحلول وقت عودة write(2) (أو ما شابه)، تكون بيانات الإخراج والبيانات الوصفية للملف المرتبطة بها قد نُقلت إلى العتاد الأساسي (أي كما لو أن كل write(2) تُبع باستدعاء لـ fsync(2)). انظر VERSIONS.

O_TMPFILE (منذ لينكس 3.11)
    إنشاء ملف عادي مؤقت غير مسمى. يحدد معامل path دليلاً؛ وستُنشأ عقدة فهارس (inode) غير مسماة في نظام ملفات ذلك الدليل. أي شيء يُكتب في الملف الناتج سيُفقد عند إغلاق آخر واصف ملف، ما لم يُعطَ الملف اسمًا.

    يجب تحديد O_TMPFILE مع أحد O_RDWR أو O_WRONLY و O_EXCL اختياريًا. إذا لم تُحدد O_EXCL، فيمكن استخدام linkat(2) لربط الملف المؤقت بنظام الملفات، مما يجعله دائمًا، باستخدام كود مثل التالي:

        char path[PATH_MAX];
        fd = open("/path/to/dir", O_TMPFILE | O_RDWR,
                                S_IRUSR | S_IWUSR);

        /* إدخال/إخراج ملف على 'fd'...  */

        linkat(fd, "", AT_FDCWD, "/path/for/file", AT_EMPTY_PATH);

        /* إذا لم يكن لدى المستدعِي إمكانية CAP_DAC_READ_SEARCH
           (المطلوبة لاستخدام AT_EMPTY_PATH مع linkat(2))،
           وكان هناك نظام ملفات proc(5) موصول، فيمكن استبدال
           استدعاء linkat(2) أعلاه بـ:

        snprintf(path, PATH_MAX,  "/proc/self/fd/%d", fd);
        linkat(AT_FDCWD, path, AT_FDCWD, "/path/for/file",
                                AT_SYMLINK_FOLLOW);
        */

    في هذه الحالة، يحدد معامل open() mode وضع أذونات الملف، كما هو الحال مع O_CREAT.

    تحديد O_EXCL بالاقتران مع O_TMPFILE يمنع ربط ملف مؤقت بنظام الملفات بالطريقة المذكورة أعلاه. (لاحظ أن معنى O_EXCL في هذه الحالة يختلف عن معنى O_EXCL في حالات أخرى).

    هناك حالتا استخدام رئيستان لـ O_TMPFILE:

    •   وظيفة tmpfile(3) محسنة: إنشاء ملفات مؤقتة خالية من حالات السباق (race-free) بحيث: (1) تُحذف آليًا عند إغلاقها؛ (2) لا يمكن الوصول إليها أبدًا عبر أي مسار؛ (3) لا تخضع لهجمات الوصلات الرمزية؛ (4) لا تتطلب من المستدعِي ابتكار أسماء فريدة.

    •   إنشاء ملف غير مرئي في البداية، ثم ملؤه بالبيانات وتعديله للحصول على سمات نظام ملفات مناسبة (fchown(2) و fchmod(2) و fsetxattr(2) وما إلى ذلك) قبل ربطه ذريًا بنظام الملفات في حالة كاملة التكوين (باستخدام linkat(2) كما هو موضح أعلاه).

    يتطلب O_TMPFILE دعمًا من نظام الملفات الأساسي؛ توفر مجموعة فرعية فقط من أنظمة ملفات لينكس ذلك الدعم. في التنفيذ الأولي، وُفر الدعم في أنظمة ملفات ext2 و ext3 و ext4 و UDF و Minix و tmpfs. أُضيف الدعم لأنظمة ملفات أخرى لاحقًا كما يلي: XFS (لينكس 3.15)؛ Btrfs (لينكس 3.16)؛ F2FS (لينكس 3.16)؛ و ubifs (لينكس 4.9)

O_TRUNC
    إذا كان الملف موجودًا بالفعل وكان ملفًا عاديًا وكان وضع الوصول يسمح بالكتابة (أي O_RDWR أو O_WRONLY) فسيُبتر إلى الطول 0. إذا كان الملف عبارة عن FIFO أو ملف جهاز طرفي، فسيُتجاهل العلم O_TRUNC. بخلاف ذلك، يكون تأثير O_TRUNC غير محدد.

  creat()
استدعاء creat() يعادل استدعاء open() بـ flags تساوي O_CREAT|O_WRONLY|O_TRUNC.

  openat()
يعمل استدعاء النظام openat() بنفس طريقة open() تمامًا، باستثناء الاختلافات الموضحة هنا.

يُستخدم معامل dirfd بالاقتران مع معامل path كما يلي:

•   إذا كان اسم المسار المعطى في path مطلقًا، فسيُتجاهل dirfd.

•   إذا كان اسم المسار المعطى في path نسبيًا وكان dirfd هو القيمة الخاصة AT_FDCWD، فسيُفسر path بالنسبة لدليل العمل الحالي للعملية المستدعية (مثل open()).

•   إذا كان اسم المسار المعطى في path نسبيًا، فسيُفسر بالنسبة للدليل المشار إليه بواسطة واصف الملف dirfd (بدلاً من تفسيره بالنسبة لدليل العمل الحالي للعملية المستدعية، كما يفعل open() للمسار النسبي). في هذه الحالة، يجب أن يكون dirfd دليلاً فُتح للقراءة (O_RDONLY) أو باستخدام العلامة O_PATH.

إذا كان اسم المسار المعطى في path نسبيًا، ولم يكن dirfd واصف ملف صالحًا، فسينتج خطأ (EBADF). (يمكن استخدام تحديد رقم واصف ملف غير صالح في dirfd كوسيلة لضمان أن path مطلق).

  openat2(2)
استدعاء النظام openat2(2) هو امتداد لـ openat()، ويوفر مجموعة فوقية من ميزات openat(). وثّق بشكل منفصل في openat2(2).

قيمة الإرجاع
عند النجاح، تعيد open() و openat() و creat() واصف الملف الجديد (عدد صحيح غير سالب). عند الخطأ، يعاد -1 وتُضبط errno للإشارة إلى الخطأ.

الأخطاء
يمكن أن تفشل open() و openat() و creat() بالأخطاء التالية:

EACCES
    الوصول المطلوب للملف غير مسموح به، أو أُرفض إذن البحث لأحد الأدلة في بادئة مسار path، أو الملف لم يكن موجودًا بعد والوصول للكتابة إلى الدليل الأب غير مسموح به. (انظر أيضًا path_resolution(7).)

EACCES
    عند تحديد O_CREAT، وتمكين protected_fifos أو protected_regular في sysctl، والملف موجود بالفعل وهو FIFO أو ملف عادي، ومالك الملف ليس المستخدم الحالي ولا مالك الدليل المحتوي، والدليل المحتوي قابل للكتابة من قبل العالم أو المجموعة وله سمة الالتصاق (sticky). للتفاصيل، انظر أوصاف /proc/sys/fs/protected_fifos و /proc/sys/fs/protected_regular في proc_sys_fs(5).

EBADF
    (openat()) المسار path نسبي ولكن dirfd ليس AT_FDCWD ولا واصف ملف صالحًا.

EBUSY
    حُددت O_EXCL في flags ويشير path إلى جهاز كتلي قيد الاستخدام من قبل النظام (على سبيل المثال، هو موصول).

EDQUOT
    عند تحديد O_CREAT، والملف غير موجود، وتجاوزت حصة (quota) المستخدم من كتل القرص أو عقد الفهارس (inodes) على نظام الملفات.

EEXIST
    المسار path موجود بالفعل واستُخدمت O_CREAT و O_EXCL.

EFAULT
    المسار path يشير إلى خارج مساحة العناوين التي يمكن الوصول إليها.

EFBIG
    انظر EOVERFLOW.

EINTR
    أثناء المنع لانتظار اكتمال فتح جهاز بطيء (مثل FIFO؛ انظر fifo(7))، قاطع الاستدعاء بواسطة معالج إشارة؛ انظر signal(7).

EINVAL
    نظام الملفات لا يدعم العلامة O_DIRECT. انظر NOTES لمزيد من المعلومات.

EINVAL
    قيمة غير صالحة في flags.

EINVAL
    حُددت O_TMPFILE في flags، ولكن لم يحدد أي من O_WRONLY أو O_RDWR.

EINVAL
    حُدد كل من O_CREAT و O_DIRECTORY في flags، وإصدار نواة لينكس هو 6.4 أو أحدث. (كانت النوى السابقة غير متسقة في هذا المجال، ولا يحدد POSIX هذا السلوك).

EINVAL
    حُددت O_CREAT في flags والمكون الأخير ("basename") لـ path الملف الجديد غير صالح (على سبيل المثال، يحتوي على محارف غير مسموح بها في نظام الملفات الأساسي).

EINVAL
    المكون الأخير ("basename") لـ path غير صالح (على سبيل المثال، يحتوي على محارف غير مسموح بها في نظام الملفات الأساسي).

EISDIR
    يشير path إلى دليل والوصول المطلوب تضمن الكتابة (أي ضُبطت O_WRONLY أو O_RDWR).

EISDIR
    يشير path إلى دليل موجود، وحُددت O_TMPFILE وأحد O_WRONLY أو O_RDWR في flags، ولكن إصدار النواة هذا لا يوفر وظيفة O_TMPFILE.

ELOOP
    وُجد عدد كبير جدًا من الوصلات الرمزية أثناء تحليل path.

ELOOP
    كان path وصلة رمزية، وحددت flags القيمة O_NOFOLLOW ولكن ليس O_PATH.

EMFILE
    وُصل إلى الحد الأقصى لعدد واصفات الملفات المفتوحة لكل عملية (انظر وصف RLIMIT_NOFILE في getrlimit(2)).

ENAMETOOLONG
    المسار path كان طويلاً جداً.

ENFILE
    وُصل إلى الحد الأقصى لإجمالي عدد الملفات المفتوحة على مستوى النظام.

ENODEV
    يشير path إلى ملف جهاز خاص ولا يوجد جهاز مقابل له. (هذا خطأ في نواة لينكس؛ في هذه الحالة يجب إعادة ENXIO).

ENOENT
    لم تضبط O_CREAT والملف المسمى غير موجود.

ENOENT
    مكون الدليل في path غير موجود أو أنه وصلة رمزية معلقة.

ENOENT
    يشير path إلى دليل غير موجود، وحُددت O_TMPFILE وأحد O_WRONLY أو O_RDWR في flags، ولكن إصدار النواة هذا لا يوفر وظيفة O_TMPFILE.

ENOMEM
    الملف المسمى هو FIFO، ولكن تعذر تخصيص ذاكرة لخبيئة FIFO لأن الحد الأقصى الصارم لكل مستخدم لتخصيص الذاكرة للأنابيب قد وُصل إليه و المستدعِي لا يملك صلاحيات؛ انظر pipe(7).

ENOMEM
    ذاكرة النواة المتوفرة غير كافية.

ENOSPC
    كان من المفترض إنشاء path ولكن الجهاز الذي يحتوي على path لا يملك مساحة للملف الجديد.

ENOTDIR
    أحد المكونات المستخدمة كدليل في path ليس دليلاً في الواقع، أو حُدد O_DIRECTORY ولم يكن path دليلاً.

ENOTDIR
    (openat()) يكون path مساراً نسبياً و dirfd واصف ملف يشير إلى ملف آخر غير الدليل.

ENXIO
    عُين O_NONBLOCK | O_WRONLY، والملف المسمى هو FIFO، ولا توجد عملية فتحت FIFO للقراءة.

ENXIO
    الملف هو ملف جهاز خاص ولا يوجد جهاز مطابق له.

ENXIO
    الملف هو مقبس نطاق UNIX.

EOPNOTSUPP
    نظام ملفات الذي يحتوي على path لا يدعم O_TMPFILE.

EOVERFLOW
    يشير path إلى ملف عادي كبير جداً لدرجة لا يمكن فتحه. السيناريو المعتاد هنا هو أن تطبيقاً جُمّع على منصة 32 بت بدون -D_FILE_OFFSET_BITS=64 حاول فتح ملف يتجاوز حجمه (1<<31)-1 بايت؛ انظر أيضًا O_LARGEFILE أعلاه. هذا هو الخطأ المحدد بواسطة POSIX.1؛ قبل لينكس 2.6.24، كان لينكس يعطي الخطأ EFBIG لهذه الحالة.

EPERM
    حُددت الراية O_NOATIME، ولكن معرف المستخدم الفعلي لـ المستدعِي لم يطابق مالك الملف ولم يكن المستدعِي ذا صلاحيات.

EPERM
    مُنعت العملية بواسطة ختم ملف؛ انظر fcntl(2).

EROFS
    يشير path إلى ملف على نظام ملفات للقراءة فقط وطُلب وصول للكتابة.

ETXTBSY
    يشير path إلى صورة تنفيذية تُنفذ حالياً وطُلب وصول للكتابة.

ETXTBSY
    يشير path إلى ملف مُستخدم حالياً كملف تبديل، وحُددت الراية O_TRUNC.

ETXTBSY
    يشير path إلى ملف يُقرأ حالياً بواسطة نواة (مثلاً، لتحميل وحدة/برمجية ثابتة)، وطُلب وصول للكتابة.

EWOULDBLOCK
    حُددت الراية O_NONBLOCK، وكان هناك عقد إيجار غير متوافق للملف (انظر fcntl(2)).

الإصدارات
يختلف التأثير (غير المحدد) لـ O_RDONLY | O_TRUNC باختلاف التطبيقات. في عديد من الأنظمة، يُقتطع الملف بالفعل.

  المدخلات/المخرجات المتزامنة
يحدد خيار "المدخلات/المخرجات المتزامنة" في POSIX.1-2008 أنواعاً مختلفة من المدخلات/المخرجات المتزامنة، ويحدد رايات open()‏ O_SYNC و O_DSYNC و O_RSYNC للتحكم في السلوك. وبغض النظر عما إذا كان التطبيق يدعم هذا الخيار، يجب أن يدعم على الأقل استخدام O_SYNC للملفات العادية.

ينفذ لينكس O_SYNC و O_DSYNC، ولكن ليس O_RSYNC. وبشكل غير دقيق إلى حد ما، تعرّف glibc‏ O_RSYNC لتكون لها نفس قيمة O_SYNC. (عُرّفت O_RSYNC في ملف ترويسة لينكس <asm/fcntl.h> على HP PA-RISC، ولكنها غير مستخدمة.)

يوفر O_SYNC إكمال سلامة ملف المدخلات/المخرجات المتزامن، مما يعني أن عمليات الكتابة ستدفع البيانات وجميع البيانات الوصفية المرتبطة بها إلى العتاد الأساسي. يوفر O_DSYNC إكمال سلامة بيانات المدخلات/المخرجات المتزامن، مما يعني أن عمليات الكتابة ستدفع البيانات إلى العتاد الأساسي، ولكنها ستدفع فقط تحديثات البيانات الوصفية المطلوبة للسماح لعملية قراءة لاحقة بالاكتمال بنجاح. يمكن أن يقلل إكمال سلامة البيانات من عدد عمليات القرص المطلوبة للتطبيقات التي لا تحتاج إلى ضمانات إكمال سلامة الملف.

لفهم الفرق بين نوعي الإكمال، تأمل في قطعتين من البيانات الوصفية للملف: طابع وقت آخر تعديل للملف (st_mtime) وطول الملف. ستعمل جميع عمليات الكتابة على تحديث طابع وقت آخر تعديل للملف، ولكن الكتابات التي تضيف بيانات إلى نهاية الملف فقط هي التي ستغير طول الملف. طابع وقت آخر تعديل ليس مطلوباً لضمان اكتمال القراءة بنجاح، ولكن طول الملف مطلوب. وبذلك، يضمن O_DSYNC فقط دفع تحديثات البيانات الوصفية لطول الملف (بينما سيدفع O_SYNC دائماً أيضًا البيانات الوصفية لطابع وقت آخر تعديل).

قبل لينكس 2.6.33، نفذ لينكس فقط الراية O_SYNC لـ open(). ومع ذلك، عند تحديد هذه الراية، كانت معظم أنظمة الملفات توفر فعلياً ما يعادل إكمال سلامة بيانات المدخلات/المخرجات المتزامن (أي أن O_SYNC نُفذت فعلياً بما يعادل O_DSYNC).

منذ لينكس 2.6.33، دُعم O_SYNC بشكل صحيح. ومع ذلك، لضمان التوافق الثنائي التراجعي، عُرّفت O_DSYNC بنفس قيمة O_SYNC التاريخية، وعُرّفت O_SYNC كقيمة راية جديدة (بتّين) تتضمن قيمة راية O_DSYNC. يضمن هذا حصول التطبيقات التي جُمّعت باستخدام الترويسات الجديدة على الأقل على دلالات O_DSYNC قبل لينكس 2.6.33.

  الاختلافات بين مكتبة C والنواة
منذ glibc 2.26، توظف دالة الغلاف glibc لـ open() استدعاء النظام openat()، بدلاً من استدعاء النظام open() الخاص بالنواة. بالنسبة لمعماريات معينة، ينطبق هذا أيضًا قبل glibc 2.26.

  POSIX
يحدد POSIX.1-2024‏ O_CLOFORK، لكن لينكس لا يدعمه.

المعايير

open()
creat()
openat()
    POSIX.1-2024.

openat2(2)
    لينكس.

O_DIRECT
O_NOATIME
O_PATH
O_TMPFILE
    لينكس.

التاريخ

open()
creat()
    SVr4، 4.3BSD، POSIX.1-2001.

openat()
    POSIX.1-2008. لينكس 2.6.16،‏ glibc 2.4.

O_CLOEXEC
O_DIRECTORY
O_NOFOLLOW
    POSIX.1-2008.

ملاحظات
تحت نظام لينكس، تُستخدم الراية O_NONBLOCK أحياناً في الحالات التي يُراد فيها الفتح ولكن ليس بالضرورة نية القراءة أو الكتابة. على سبيل المثال، قد يُستخدم هذا لفتح جهاز من أجل الحصول على واصف ملف لاستخدامه مع ioctl(2).

لاحظ أن open() يمكنه فتح ملفات الأجهزة الخاصة، لكن creat() لا يمكنه إنشاءها؛ استخدم mknod(2) بدلاً من ذلك.

إذا أُنشئ الملف حديثاً، تُعين حقول st_atime و st_ctime و st_mtime الخاصة به (على التوالي، وقت آخر وصول، ووقت آخر تغيير للحالة، ووقت آخر تعديل؛ انظر stat(2)) إلى الوقت الحالي، وكذلك حقول st_ctime و st_mtime للدليل الأصل. وإلا، إذا عُدل الملف بسبب الراية O_TRUNC، تُعين حقول st_ctime و st_mtime الخاصة به إلى الوقت الحالي.

تُظهر الملفات الموجودة في دليل /proc/pid/fd واصفات الملفات المفتوحة للعملية ذات المعرف pid. تُظهر الملفات في دليل /proc/pid/fdinfo معلومات أكثر عن واصفات الملفات هذه. انظر proc(5) لمزيد من التفاصيل حول كلا الدليلين.

لا يعرف ملف ترويسة لينكس <asm/fcntl.h>‏ O_ASYNC؛ بل عُرّف المرادف FASYNC (المشتق من BSD) بدلاً منه.

  أوصاف الملفات المفتوحة
مصطلح وصف الملف المفتوح هو المصطلح الذي يستخدمه POSIX للإشارة إلى المدخلات في جدول الملفات المفتوحة على مستوى النظام. في سياقات أخرى، يُسمى هذا الكائن أيضًا بأسماء متنوعة مثل "كائن ملف مفتوح"، أو "مقبض ملف"، أو "مدخل جدول ملفات مفتوحة"، أو—بلغة مطوري النواة—‏ struct file.

عند مضاعفة واصف ملف (باستخدام dup(2) أو ما شابه)، تشير النسخة المكررة إلى نفس وصف الملف المفتوح الذي يشير إليه واصف الملف الأصلي، وبالتالي يتشارك واصفا الملف في إزاحة الملف ورايات حالة الملف. يمكن أن يحدث هذا التشارك أيضًا بين العمليات: ترث العملية الابنة المنشأة عبر fork(2) نسخاً مكررة من واصفات ملفات والدها، وتشير تلك النسخ إلى نفس أوصاف الملفات المفتوحة.

كل open() لملف ينشئ وصف ملف مفتوحاً جديداً؛ وبالتالي، قد يكون هناك عدة أوصاف ملفات مفتوحة تقابل ملفاً واحداً (inode).

في لينكس، يمكن استخدام عملية KCMP_FILE في kcmp(2) لاختبار ما إذا كان واصفا ملف (في نفس العملية أو في عمليتين مختلفتين) يشيران إلى نفس وصف الملف المفتوح.

  NFS
هناك العديد من العيوب في البروتوكول الأساسي لـ NFS، مما يؤثر من بين أمور أخرى على O_SYNC و O_NDELAY.

في أنظمة ملفات NFS مع تفعيل تخطيط UID، قد يعيد open() واصف ملف ولكن، على سبيل المثال، تُرفض طلبات read(2) مع الخطأ EACCES. هذا لأن العميل ينفذ open() عبر التحقق من الأذونات، ولكن تخطيط UID ينفذه الخادم عند طلبات القراءة والكتابة.

  FIFOs
يؤدي فتح طرف القراءة أو الكتابة لـ FIFO إلى الحظر حتى يُفتح الطرف الآخر أيضًا (بواسطة عملية أو خيط آخر). انظر fifo(7) لمزيد من التفاصيل.

  وضع الوصول للملف
على عكس القيم الأخرى التي يمكن تحديدها في flags، فإن قيم access mode‏ O_RDONLY و O_WRONLY و O_RDWR لا تحدد بتاتاً فردية. بدلاً من ذلك، فإنها تعرف البتّين الأدنى في flags، وتعرف على التوالي كـ 0 و 1 و 2. بمعنى آخر، الجمع O_RDONLY | O_WRONLY هو خطأ منطقي، وبالتأكيد ليس له نفس معنى O_RDWR.

يحتفظ لينكس بوضع الوصول الخاص غير المعياري 3 (ثنائي 11) في flags ليعني: التحقق من إذن القراءة والكتابة على الملف وإعادة واصف ملف لا يمكن استخدامه للقراءة أو الكتابة. يُستخدم وضع الوصول غير المعياري هذا بواسطة بعض برامج قيادة لينكس لإعادة واصف ملف ليُستخدم فقط لعمليات ioctl(2) الخاصة بالجهاز.

  الأساس المنطقي لـ openat() وواجهات برمجة تطبيقات واصف ملف الدليل الأخرى
تعالج openat() واستدعاءات النظام الأخرى ودوال المكتبة التي تأخذ وسيط واصف ملف الدليل (مثل execveat(2) و faccessat(2) و fanotify_mark(2) و fchmodat(2) و fchownat(2) و fspick(2) و fstatat(2) و futimesat(2) و linkat(2) و mkdirat(2) و mknodat(2) و mount_setattr(2) و move_mount(2) و name_to_handle_at(2) و open_tree(2) و openat2(2) و readlinkat(2) و renameat(2) و renameat2(2) و statx(2) و symlinkat(2) و unlinkat(2) و utimensat(2) و mkfifoat(3) و scandirat(3)) مشكلتين في الواجهات الأقدم التي سبقتها. التفسير هنا بمصطلحات استدعاء openat()، لكن الأساس المنطقي مماثل للواجهات الأخرى.

أولاً، تسمح openat() للتطبيق بتجنب حالات السباق التي قد تحدث عند استخدام open() لفتح ملفات في أدلة غير دليل العمل الحالي. تنتج حالات السباق هذه عن حقيقة أن بعض مكونات بادئة الدليل المعطاة لـ open() يمكن تغييرها بالتوازي مع استدعاء open(). لنفترض، على سبيل المثال، أننا نرغب في إنشاء الملف dir1/dir2/xxx.dep إذا كان الملف dir1/dir2/xxx موجوداً. المشكلة هي أنه بين التحقق من الوجود وخطوة إنشاء الملف، يمكن تعديل dir1 أو dir2 (والتي قد تكون وصلات رمزية) لتشير إلى موقع مختلف. يمكن تجنب مثل هذه السباقات بفتح واصف ملف للدليل المستهدف، ثم تحديد واصف الملف هذا كوسيط dirfd لـ (مثلاً) fstatat(2) و openat(). لاستخدام واصف الملف dirfd فوائد أخرى أيضًا:

•   واصف الملف هو مرجع مستقر للدليل، حتى لو أُعيدت تسمية الدليل؛ و

•   واصف الملف المفتوح يمنع نظام ملفات الأساسي من أن يُفصل، تماماً كما لو كان للعملية دليل عمل حالي على نظام ملفات.

ثانياً، تسمح openat() بتنفيذ "دليل عمل حالي" لكل خيط، عبر واصف(ات) ملفات يصونها التطبيق. (يمكن أيضًا الحصول على هذه الوظيفة من خلال حيل تعتمد على استخدام /proc/self/fd/dirfd، ولكن بكفاءة أقل).

يمكن الحصول على الوسيط dirfd لواجهات برمجة التطبيقات هذه باستخدام open() أو openat() لفتح دليل (بإحدى الرايتين O_RDONLY أو O_PATH). بدلاً من ذلك، يمكن الحصول على واصف ملف كهذا بتطبيق dirfd(3) على دفق دليل أُنشئ باستخدام opendir(3).

عندما تُعطى واجهات برمجة التطبيقات هذه الوسيط dirfd كـ AT_FDCWD أو يكون المسار المحدد مطلقاً، فإنها تتعامل مع وسيط المسار بنفس الطريقة التي تتعامل بها واجهات برمجة التطبيقات التقليدية المقابلة. ومع ذلك، في هذه الحالة، تملك العديد من واجهات برمجة التطبيقات وسيط flags يوفر وصولاً إلى وظائف غير متوفرة في الواجهات التقليدية المقابلة.

  O_DIRECT
قد تفرض الراية O_DIRECT قيود محاذاة على طول وعناوين مخازن مساحة المستخدم وإزاحة الملف للمدخلات/المخرجات. في لينكس تختلف قيود المحاذاة حسب نظام ملفات وإصدار نواة وقد تغيب تماماً. يختلف التعامل مع المدخلات/المخرجات O_DIRECT غير المحاذية أيضًا؛ فيمكن أن تفشل مع EINVAL أو تتراجع إلى المدخلات/المخرجات المخزنة (buffered).

منذ لينكس 6.1، يمكن الاستعلام عن دعم O_DIRECT وقيود المحاذاة لملف باستخدام statx(2)، وباستخدام الراية STATX_DIOALIGN. يختلف دعم STATX_DIOALIGN حسب نظام ملفات؛ انظر statx(2).

توفر بعض أنظمة الملفات واجهات خاصة بها للاستعلام عن قيود محاذاة O_DIRECT، على سبيل المثال عملية XFS_IOC_DIOINFO في xfsctl(3). يجب استخدام STATX_DIOALIGN بدلاً منها عندما تكون متاحة.

إذا لم يتوفر أي مما سبق، فلا يمكن افتراض دعم المدخلات/المخرجات المباشرة وقيود المحاذاة إلا من الخصائص المعروفة لـ نظام ملفات، والملف الفردي، وجهاز (أجهزة) التخزين الأساسية، وإصدار النواة. في لينكس 2.4، تتطلب معظم أنظمة الملفات القائمة على أجهزة كتلية أن تكون إزاحة الملف وطول وعنوان الذاكرة لجميع أجزاء المدخلات/المخرجات مضاعفات لحجم كتلة نظام ملفات (عادة 4096 بايت). في لينكس 2.6.0، خُفف هذا إلى حجم الكتلة المنطقية لـ جهاز كتلي (عادة 512 بايت). يمكن تحديد حجم الكتلة المنطقية لـ جهاز كتلي باستخدام عملية ioctl(2) BLKSSZGET أو من صدفة باستخدام الأمر:

    blockdev --getss

يجب عدم تشغيل مدخلات/مخرجات O_DIRECT بالتزامن مع استدعاء النظام fork(2)، إذا كان مخزن الذاكرة تخطيطاً خاصاً (أي أي تخطيط أُنشئ باستخدام راية mmap(2) MAP_PRIVATE؛ وهذا يشمل الذاكرة المخصصة على الكومة والمخازن المخصصة سكونياً). أي مدخلات/مخرجات كهذه، سواء أُرسلت عبر واجهة مدخلات/مخرجات غير متزامنة أو من خيط آخر في العملية، يجب أن تكتمل قبل استدعاء fork(2). الفشل في القيام بذلك قد يؤدي إلى تلف البيانات وسلوك غير محدد في العمليات الوالدة والابنة. لا ينطبق هذا القيد عندما يكون مخزن الذاكرة لـ مدخلات/مخرجات O_DIRECT قد أُنشئ باستخدام shmat(2) أو mmap(2) مع راية MAP_SHARED. ولا ينطبق هذا القيد أيضًا عندما يُنصح مخزن الذاكرة كـ MADV_DONTFORK باستخدام madvise(2)، مما يضمن عدم توفره للابن بعد fork(2).

قُدمت الراية O_DIRECT في SGI IRIX، حيث تملك قيود محاذاة مماثلة لقيود لينكس 2.4. تملك IRIX أيضًا استدعاء fcntl(2) للاستعلام عن المحاذات والأحجام المناسبة. قدم FreeBSD 4.x راية بنفس الاسم، ولكن بدون قيود محاذاة.

أُضيف دعم O_DIRECT في لينكس 2.4.10. نوى لينكس الأقدم تتجاهل هذه الراية ببساطة. قد لا تنفذ بعض أنظمة الملفات هذه الراية، وفي هذه الحالة يفشل open() مع الخطأ EINVAL إذا استُخدمت.

يجب على التطبيقات تجنب خلط O_DIRECT والمدخلات/المخرجات العادية لنفس الملف، وخاصة لمناطق البايتات المتداخلة في نفس الملف. حتى عندما يتعامل نظام ملفات بشكل صحيح مع قضايا التماسك في هذه الحالة، فمن المرجح أن تكون الإنتاجية الإجمالية للمدخلات/المخرجات أبطأ من استخدام أي من الوضعين وحده. وبالمثل، يجب على التطبيقات تجنب خلط mmap(2) للملفات مع المدخلات/المخرجات المباشرة لنفس الملفات.

سوف يختلف سلوك O_DIRECT مع NFS عن أنظمة الملفات المحلية. قد لا تدعم النوى الأقدم، أو النوى التي ضُبطت بطرق معينة، هذا المزيج. لا يدعم بروتوكول NFS تمرير الراية إلى الخادم، لذا ستتجاوز مدخلات/مخرجات O_DIRECT خبيئة الصفحة في العميل فقط؛ وقد يظل الخادم يخبئ المدخلات/المخرجات. يطلب العميل من الخادم جعل المدخلات/المخرجات متزامنة للحفاظ على الدلالات المتزامنة لـ O_DIRECT. ستعمل بعض الخوادم بشكل سيئ في هذه الظروف، خاصة إذا كان حجم المدخلات/المخرجات صغيراً. قد تُضبط بعض الخوادم أيضًا لتكذب على العملاء بشأن وصول المدخلات/المخرجات إلى وحدة التخزين المستقرة؛ سيؤدي ذلك إلى تجنب عقوبة الأداء مع وجود بعض المخاطر على سلامة البيانات في حالة انقطاع طاقة الخادم. لا يضع عميل Linux NFS أي قيود محاذاة على مدخلات/مخرجات O_DIRECT.

باختصار، O_DIRECT هي أداة قوية محتملة يجب استخدامها بحذر. يوصى بأن تعامل التطبيقات استخدام O_DIRECT كخيار أداء يكون معطلاً بشكل مبدئي.

العلل
حالياً، لا يمكن تمكين المدخلات/المخرجات المدفوعة بالإشارة عبر تحديد O_ASYNC عند استدعاء open()؛ استخدم fcntl(2) لتمكين هذه الراية.

يجب التحقق من رمزي خطأ مختلفين، EISDIR و ENOENT، عند محاولة تحديد ما إذا كانت النواة تدعم وظيفة O_TMPFILE.

انظر أيضًا
chmod(2), chown(2), close(2), dup(2), fcntl(2), link(2), lseek(2), mknod(2), mmap(2), mount(2), open_by_handle_at(2), openat2(2), read(2), socket(2), stat(2), umask(2), unlink(2), write(2), fopen(3), acl(5), fifo(7), inode(7), path_resolution(7), symlink(7)

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

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

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