flock(2)

الاسم
flock - تطبيق أو إزالة قفل استشاري على ملف مفتوح

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

موجز
#include <sys/file.h>

int flock(int fd, int op);

الوصف
تطبيق أو إزالة قفل استشاري على الملف المفتوح المحدد بواسطة fd. الوسيط op هو أحد التالي:

    LOCK_SH
        وضع قفل مشترك. يمكن لأكثر من عملية الاحتفاظ بقفل مشترك لملف معين في وقت معين.

    LOCK_EX
        وضع قفل حصري. يمكن لعملية واحدة فقط الاحتفاظ بقفل حصري لملف معين في وقت معين.

    LOCK_UN
        إزالة قفل موجود تحتفظ به هذه العملية.

قد يحجب استدعاء flock() إذا كان قفل غير متوافق محتجز من قبل عملية أخرى. لتقديم طلب غير محجب، قم بتضمين LOCK_NB (عن طريق OR) مع أي من العمليات أعلاه.

لا يمكن لملف واحد أن يحتوي في نفس الوقت على أقفال مشتركة وحصرية معًا.

ترتبط الأقفال التي أنشأها flock() بوصف ملف مفتوح (انظر open(2)). يعني هذا أن واصفات الملفات المكررة (المنشأة، على سبيل المثال، بواسطة fork(2) أو dup(2)) تشير إلى نفس القفل، ويمكن تعديل هذا القفل أو تحريره باستخدام أي من واصفات الملفات هذه. علاوة على ذلك، يتم تحرير القفل إما عن طريق عملية LOCK_UN صريحة على أي من واصفات الملفات المكررة هذه، أو عند إغلاق جميع واصفات الملفات هذه.

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

يمكن للعملية الاحتفاظ بنوع واحد فقط من القفل (مشترك أو حصري) على ملف. ستقوم استدعاءات flock() اللاحقة على ملف مقفل بالفعل بتحويل القفل الموجود إلى وضع القفل الجديد.

يتم الحفاظ على الأقفال التي أنشأها flock() عبر execve(2).

يمكن وضع قفل مشترك أو حصري على ملف بغض النظر عن الوضع الذي تم فتح الملف به.

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

الأخطاء

EBADF
    fd ليس واصف ملف مفتوح.

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

EINVAL
    op غير صالح.

ENOLCK
    نفدت ذاكرة النواة لتخصيص سجلات القفل.

EWOULDBLOCK
    الملف مقفل وتم تحديد العلم LOCK_NB.

الإصدارات
منذ Linux 2.0، تم تنفيذ flock() كاستدعاء نظام بحد ذاته بدلاً من محاكاته في مكتبة GNU C كاستدعاء لـ fcntl(2). مع هذا التنفيذ، لا يوجد تفاعل بين أنواع القفل التي يضعها flock() و fcntl(2)، ولا يكتشف flock() حالة الجمود. (لاحظ، مع ذلك، أنه على بعض الأنظمة، مثل BSDs الحديثة، تتفاعل أقفال flock() و fcntl(2) مع بعضها البعض.)

  تفاصيل CIFS
حتى Linux 5.4، لا يتم نشر flock() عبر SMB. لن يظهر ملف بهذه الأقفال كمقفل للعملاء البعيدين.

منذ Linux 5.5، يتم محاكاة أقفال flock() بأقفال نطاق بايت SMB على الملف بأكمله. على غرار NFS، يعني هذا أن أقفال fcntl(2) و flock() تتفاعل مع بعضها البعض. تأثير جانبي مهم آخر هو أن الأقفال لم تعد استشارية: أي إدخال/إخراج على ملف مقفل سيفشل دائمًا مع EACCES عند القيام به من واصف ملف منفصل. ينشأ هذا الاختلاف من تصميم الأقفال في بروتوكول SMB، الذي يوفر دلالات قفل إلزامية.

قد تختلف دلالات القفل عن بعد والإلزامي مع بروتوكول SMB وخيارات الوصل ونوع الخادم. انظر mount.cifs(8) للحصول على معلومات إضافية.

المعايير
BSD.

التاريخ
4.4BSD (ظهر استدعاء flock() لأول مرة في 4.2BSD). تظهر نسخة من flock()، ربما تم تنفيذها بدلالة fcntl(2)، على معظم أنظمة UNIX.

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

منذ Linux 2.6.12، تدعم عملاء NFS أقفال flock() عن طريق محاكاتها كأقفال نطاق بايت fcntl(2) على الملف بأكمله. يعني هذا أن أقفال fcntl(2) و flock() تتفاعل مع بعضها البعض عبر NFS. يعني أيضًا أنه لوضع قفل حصري، يجب فتح الملف للكتابة.

منذ Linux 2.6.37، تدعم النواة وضع توافق يسمح بمعالجة أقفال flock() (وكذلك أقفال منطقة البايت fcntl(2)) كمحلية؛ انظر مناقشة خيار local_lock في nfs(5).

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

أقفال flock() و fcntl(2) لها دلالات مختلفة فيما يتعلق بالعمليات المتفرعة و dup(2). على الأنظمة التي تنفذ flock() باستخدام fcntl(2)، ستكون دلالات flock() مختلفة عن تلك الموصوفة في صفحة الدليل هذه.

تحويل القفل (من مشترك إلى حصري، أو العكس) ليس مضمونًا أن يكون ذريًا: يُزال القفل الموجود أولاً، ثم يُنشأ قفل جديد. بين هاتين الخطوتين، قد يُمنح طلب قفل معلق من عملية أخرى، مما يؤدي إلى أن التحويل إما أن يُحجب أو يفشل إذا تم تحديد LOCK_NB. (هذا هو سلوك BSD الأصلي، ويحدث في العديد من التطبيقات الأخرى.)

تحرير القفل عند إغلاق واصف ملف ليس متسلسلاً بعد جميع التأثيرات الملحوظة لـ close(2). على سبيل المثال، إذا كتبت عملية ملفًا أثناء حملها لقفل حصري، ثم أغلقت ذلك الملف، وحجبت عملية أخرى وضع قفل مشترك على ذلك الملف لانتظار إغلاقه، فقد تلاحظ أن execve(2) لاحقًا لذلك الملف يفشل مع ETXTBSY، وأن umount(2) لنظام الملفات الأساسي الخاص به يفشل مع EBUSY، كما لو كان الملف لا يزال مفتوحًا في العملية الأولى.

انظر أيضًا
flock(1)، close(2)، dup(2)، execve(2)، fcntl(2)، fork(2)، open(2)، lockf(3)، lslocks(8)

Documentation/filesystems/locks.rst في شجرة مصدر نواة لينكس

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

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

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