.\" -*- coding: UTF-8 -*- .\" Copyright 2006-2014, Michael Kerrisk .\" Copyright, the authors of the Linux man-pages project .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH inotify 7 "14 فبراير 2026" "صفحات دليل لينكس 6.18" .SH الاسم inotify \- مراقبة أحداث نظام الملفات .SH الوصف توفر واجهة برمجة التطبيقات \fIinotify\fP آلية لمراقبة أحداث نظام الملفات. يمكن استخدام inotify لمراقبة ملفات فردية، أو لمراقبة أدلة. عند مراقبة دليل، يُرجع inotify أحداثًا للدليل نفسه، وللملفات داخل الدليل. .P تُستخدم استدعاءات النظام التالية مع واجهة برمجة التطبيقات هذه: .IP \[bu] 3 ينشئ \fBinotify_init\fP(2) مثيل inotify ويُعيد واصف ملف يشير إلى مثيل inotify. الإصدار الأحدث \fBinotify_init1\fP(2) مشابه لـ \fBinotify_init\fP(2)، لكنه يحتوي على وسيط \fIflags\fP يوفر الوصول إلى بعض الوظائف الإضافية. .IP \[bu] يتلاعب \fBinotify_add_watch\fP(2) بقائمة المراقبة المرتبطة بمثيل inotify. يحدد كل عنصر ("مراقبة") في قائمة المراقبة اسم مسار ملف أو دليل، بالإضافة إلى مجموعة من الأحداث التي يجب على النواة مراقبتها للملف المشار إليه بواسطة اسم المسار ذلك. إما أن ينشئ \fBinotify_add_watch\fP(2) عنصر مراقبة جديد، أو يعدل مراقبة موجودة. لكل مراقبة "واصف مراقبة" فريد، وهو عدد صحيح يُعاد بواسطة \fBinotify_add_watch\fP(2) عند إنشاء المراقبة. .IP \[bu] عند حدوث أحداث للملفات والأدلة المراقبة، تُتاح تلك الأحداث للتطبيق كبيانات منظمة يمكن قراءتها من واصف ملف inotify باستخدام \fBread\fP(2) (انظر أدناه). .IP \[bu] يزيل \fBinotify_rm_watch\fP(2) عنصرًا من قائمة مراقبة inotify. .IP \[bu] عند إغلاق جميع واصفات الملفات التي تشير إلى مثيل inotify (باستخدام \fBclose\fP(2))، يُحرر الكائن الأساسي وموارده لإعادة الاستخدام بواسطة النواة؛ تُحرر جميع المراقبات المرتبطة آليًا. .P مع البرمجة الدقيقة، يمكن للتطبيق استخدام inotify لمراقبة وتخزين حالة مجموعة من كائنات نظام الملفات بكفاءة. ومع ذلك، يجب على التطبيقات القوية أن تأخذ في الاعتبار حقيقة أن الأخطاء في منطق المراقبة أو حالات السباق من النوع الموصوف أدناه قد تترك الخبيئة غير متسقة مع حالة نظام الملفات. من الحكمة على الأرجح إجراء بعض التحقق من الاتساق، وإعادة بناء الخبيئة عند اكتشاف حالات عدم الاتساق. .SS "قراءة الأحداث من واصف ملف inotify" لتحديد الأحداث التي حدثت، يقرأ التطبيق \fBread\fP(2) من واصف ملف inotify. إذا لم تحدث أي أحداث حتى الآن، فبافتراض واصف ملف محظور، سيحظر \fBread\fP(2) حتى يحدث حدث واحد على الأقل (ما لم يُقاطع بإشارة، وفي هذه الحالة يفشل الاستدعاء مع الخطأ \fBEINTR\fP؛ انظر \fBsignal\fP(7)). .P يُعيد كل \fBread\fP(2) ناجح مخزنًا مؤقتًا يحتوي على بنية واحدة أو أكثر مما يلي: .P .in +4n .EX .\" FIXME . The type of the 'wd' field should probably be "int32_t". .\" I submitted a patch to fix this. See the LKML thread .\" "[patch] Fix type errors in inotify interfaces", 18 Nov 2008 .\" glibc bug filed: https://www.sourceware.org/bugzilla/show_bug.cgi?id=7040 struct inotify_event { int wd; /* Watch descriptor */ uint32_t mask; /* Mask describing event */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of \f[I]name\fR field */ char name[]; /* Optional null\-terminated name */ }; .EE .in .P يُحدد \fIwd\fP المراقبة التي يحدث لها هذا الحدث. وهو أحد واصفات المراقبة التي أعيدت بواسطة استدعاء سابق لـ \fBinotify_add_watch\fP(2). .P يحتوي \fImask\fP على بتات تصف الحدث الذي حدث (انظر أدناه). .P \fIcookie\fP هو عدد صحيح فريد يربط الأحداث ذات الصلة. حاليًا، يُستخدم هذا فقط لأحداث إعادة التسمية، ويسمح للتطبيق بربط الزوج الناتج من أحداث \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP. بالنسبة لجميع أنواع الأحداث الأخرى، يُضبط \fIcookie\fP على 0. .P حقل \fIname\fP موجود فقط عند إعادة حدث لملف داخل دليل مراقب؛ يُحدد اسم الملف داخل الدليل المراقب. اسم الملف هذا منتهي بصفر، وقد يتضمن بايتات صفرية إضافية (\[aq]\[rs]0\[aq]) لمحاذاة القراءات اللاحقة إلى حد عنوان مناسب. .P يحسب حقل \fIlen\fP جميع البايتات في \fIname\fP، بما في ذلك البايتات الصفرية؛ وبالتالي فإن حجم كل بنية \fIinotify_event\fP هو \fIsizeof(struct inotify_event)+size\fP. .P يعتمد السلوك عندما يكون المخزن المؤقت المُعطى لـ \fBread\fP(2) صغيرًا جدًا لإعادة معلومات حول الحدث التالي على إصدار النواة: قبل Linux 2.6.21، يُعيد \fBread\fP(2) 0؛ منذ Linux 2.6.21، يفشل \fBread\fP(2) مع الخطأ \fBEINVAL\fP. تحديد مخزن مؤقت بحجم .P .in +4n .EX sizeof(struct inotify_event) + NAME_MAX + 1 .EE .in .P سيكون كافيًا لقراءة حدث واحد على الأقل. .SS "أحداث inotify" وسيط \fImask\fP لـ \fBinotify_add_watch\fP(2) وحقل \fImask\fP لبنية \fIinotify_event\fP المُعاد عند قراءة \fBread\fP(2) لواصف ملف inotify هما قناعا بتات يُحددان أحداث inotify. يمكن تحديد البتات التالية في \fImask\fP عند استدعاء \fBinotify_add_watch\fP(2) وقد تُعاد في حقل \fImask\fP المُعاد بواسطة \fBread\fP(2): .RS 4 .TP \fBIN_ACCESS\fP (+) تم الوصول إلى الملف (مثل \fBread\fP(2)، \fBexecve\fP(2)). .TP \fBIN_ATTRIB\fP (*) .\" FIXME . .\" Events do not occur for link count changes on a file inside a monitored .\" directory. This differs from other metadata changes for files inside .\" a monitored directory. تغيرت البيانات الوصفية\[em]على سبيل المثال، الأذونات (مثل \fBchmod\fP(2))، الطوابع الزمنية (مثل \fButimensat\fP(2))، السمات الموسعة (\fBsetxattr\fP(2))، عدد الروابط (منذ Linux 2.6.25؛ مثل لهدف \fBlink\fP(2) و \fBunlink\fP(2))، ومعرف المستخدم/المجموعة (مثل \fBchown\fP(2)). .TP \fBIN_CLOSE_WRITE\fP (+) أغلق الملف المفتوح للكتابة. .TP \fBIN_CLOSE_NOWRITE\fP (*) أغلق الملف أو الدليل غير المفتوح للكتابة. .TP \fBIN_CREATE\fP (+) أنشئ ملف/دليل في الدليل المراقب (مثل \fBopen\fP(2) \fBO_CREAT\fP، \fBmkdir\fP(2)، \fBlink\fP(2)، \fBsymlink\fP(2)، \fBbind\fP(2) على مقبس نطاق UNIX). .TP \fBIN_DELETE\fP (+) حذف ملف/دليل من الدليل المراقب. .TP \fBIN_DELETE_SELF\fP حذف الملف/الدليل المراقب نفسه. (يحدث هذا الحدث أيضًا إذا نقل كائن إلى نظام ملفات آخر، لأن \fBmv\fP(1) ينسخ الملف فعليًا إلى نظام الملفات الآخر ثم يحذفه من نظام الملفات الأصلي.) بالإضافة إلى ذلك، سيولد حدث \fBIN_IGNORED\fP لاحقًا لوصف المراقبة. .TP \fBIN_MODIFY\fP (+) عدل الملف (مثل \fBwrite\fP(2)، \fBtruncate\fP(2)). .TP \fBIN_MOVE_SELF\fP نقل الملف/الدليل المراقب نفسه. .TP \fBIN_MOVED_FROM\fP (+) يولد للدليل الذي يحتوي على اسم الملف القديم عند إعادة تسمية ملف. .TP \fBIN_MOVED_TO\fP (+) يولد للدليل الذي يحتوي على اسم الملف الجديد عند إعادة تسمية ملف. .TP \fBIN_OPEN\fP (*) فتح الملف أو الدليل. .RE .P مراقبة Inotify قائمة على inode: عند مراقبة ملف (ولكن ليس عند مراقبة الدليل الذي يحتوي على ملف)، يمكن توليد حدث لنشاط على أي رابط للملف (في نفس الدليل أو دليل مختلف). .P عند مراقبة دليل: .IP \[bu] 3 الأحداث المميزة أعلاه بعلامة النجمة (*) يمكن أن تحدث لكل من الدليل نفسه وللكائنات داخل الدليل؛ و .IP \[bu] الأحداث المميزة بعلامة الجمع (+) تحدث فقط للكائنات داخل الدليل (وليس للدليل نفسه). .P \fIملاحظة\fP: عند مراقبة دليل، لا تُنشأ أحداث للملفات داخل الدليل عندما تُنفذ الأحداث عبر اسم مسار (أي رابط) يقع خارج الدليل المراقب. .P عند إنشاء أحداث للكائنات داخل دليل مراقب، يحدد حقل \fIname\fP في بنية \fIinotify_event\fP المعادة اسم الملف داخل الدليل. .P عُرفت الكلية \fBIN_ALL_EVENTS\fP كقناع بت لجميع الأحداث أعلاه. يمكن استخدام هذه الكلية كوسيط \fImask\fP عند استدعاء \fBinotify_add_watch\fP(2). .P عُرفت كليتان إضافيتان للتسهيل: .RS 4 .TP \fBIN_MOVE\fP تساوي \fBIN_MOVED_FROM | IN_MOVED_TO\fP. .TP \fBIN_CLOSE\fP تساوي \fBIN_CLOSE_WRITE | IN_CLOSE_NOWRITE\fP. .RE .P يمكن تحديد البتات الإضافية التالية في \fImask\fP عند استدعاء \fBinotify_add_watch\fP(2): .RS 4 .TP \fBIN_DONT_FOLLOW\fP (منذ Linux 2.6.15) لا تفك إسناد \fIpathname\fP إذا كان رابطًا رمزيًا. .TP \fBIN_EXCL_UNLINK\fP (منذ Linux 2.6.36) .\" commit 8c1934c8d70b22ca8333b216aec6c7d09fdbd6a6 مبدئيًا، عند مراقبة أحداث على أبناء دليل، تُنشأ أحداث للأبناء حتى بعد فصلهم عن الدليل. قد ينتج عن هذا أعداد كبيرة من الأحداث غير المهمة لبعض التطبيقات (مثلًا، عند مراقبة \fI/tmp\fP، حيث تنشئ تطبيقات عديدة ملفات مؤقتة تُفصل أسماؤها فورًا). تغيير تحديد \fBIN_EXCL_UNLINK\fP السلوك المبدئي، بحيث لا تُنشأ أحداث للأبناء بعد فصلهم عن الدليل المراقب. .TP \fBIN_MASK_ADD\fP إذا وُجدت نسخة مراقبة مسبقًا لكائن نظام الملفات المطابق لـ \fIpathname\fP، أضف (OR) الأحداث في \fImask\fP إلى قناع المراقبة (بدل استبدال القناع)؛ ينتج الخطأ \fBEINVAL\fP إذا حُدد \fBIN_MASK_CREATE\fP أيضًا. .TP \fBIN_ONESHOT\fP راقب كائن نظام الملفات المطابق لـ \fIpathname\fP لحدث واحد، ثم أزله من قائمة المراقبة. .TP \fBIN_ONLYDIR\fP (منذ Linux 2.6.15) راقب \fIpathname\fP فقط إذا كان دليلًا؛ ينتج الخطأ \fBENOTDIR\fP إذا لم يكن \fIpathname\fP دليلًا. يوفر استخدام هذه العلامة للتطبيق طريقة خالية من السباق لضمان أن الكائن المراقب هو دليل. .TP \fBIN_MASK_CREATE\fP (منذ Linux 4.18) راقب \fIpathname\fP فقط إذا لم يكن لديه مراقبة مرتبطة به بالفعل؛ ينتج الخطأ \fBEEXIST\fP إذا كان \fIpathname\fP مراقبًا بالفعل. .IP يوفر استخدام هذه العلامة للتطبيق طريقة لضمان أن المراقبات الجديدة لا تعدل الموجودة. هذا مفيد لأن مسارات متعددة قد تشير إلى نفس inode، وقد تؤدي الاستدعاءات المتعددة لـ \fBinotify_add_watch\fP(2) بدون هذه العلامة إلى إتلاف أقنعة المراقبة الموجودة. .RE .P قد تُضبط البتات التالية في حقل \fImask\fP المعاد بواسطة \fBread\fP(2): .RS 4 .TP \fBIN_IGNORED\fP أزيلت المراقبة صراحة (\fBinotify_rm_watch\fP(2)) أو آليًا (حُذف الملف، أو فُصل نظام الملفات). انظر أيضًا BUGS. .TP \fBIN_ISDIR\fP موضوع هذا الحدث هو دليل. .TP \fBIN_Q_OVERFLOW\fP فاضت قائمة انتظار الأحداث (\fIwd\fP يساوي \-1 لهذا الحدث). .TP \fBIN_UNMOUNT\fP نظام الملفات الذي يحتوي على الكائن المراقب فُصل. بالإضافة إلى ذلك، يُولد حدث \fBIN_IGNORED\fP لاحقًا لواصف المراقبة. .RE .SS أمثلة افترض أن تطبيقًا يراقب الدليل \fIdir\fP والملف \fIdir/myfile\fP لجميع الأحداث. الأمثلة أدناه تُظهر بعض الأحداث التي ستُولد لهذين الكائنين. .RS 4 .TP fd = open("dir/myfile", O_RDWR); يُولد أحداث \fBIN_OPEN\fP لكل من \fIdir\fP و \fIdir/myfile\fP. .TP read(fd, buf, count); يُولد أحداث \fBIN_ACCESS\fP لكل من \fIdir\fP و \fIdir/myfile\fP. .TP write(fd, buf, count); يُولد أحداث \fBIN_MODIFY\fP لكل من \fIdir\fP و \fIdir/myfile\fP. .TP fchmod(fd, mode); يُولد أحداث \fBIN_ATTRIB\fP لكل من \fIdir\fP و \fIdir/myfile\fP. .TP close(fd); يُولد أحداث \fBIN_CLOSE_WRITE\fP لكل من \fIdir\fP و \fIdir/myfile\fP. .RE .P افترض أن تطبيقًا يراقب الدليلين \fIdir1\fP و \fIdir2\fP، والملف \fIdir1/myfile\fP. الأمثلة التالية تُظهر بعض الأحداث التي قد تُولد. .RS 4 .TP link("dir1/myfile", "dir2/new"); يُولد حدث \fBIN_ATTRIB\fP لـ \fImyfile\fP وحدث \fBIN_CREATE\fP لـ \fIdir2\fP. .TP rename("dir1/myfile", "dir2/myfile"); يُولد حدث \fBIN_MOVED_FROM\fP لـ \fIdir1\fP، وحدث \fBIN_MOVED_TO\fP لـ \fIdir2\fP، وحدث \fBIN_MOVE_SELF\fP لـ \fImyfile\fP. أحداث \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP سيكون لها نفس قيمة \fIcookie\fP. .RE .P افترض أن \fIdir1/xx\fP و \fIdir2/yy\fP هما (الروابط الوحيدة) لنفس الملف، وتطبيق يراقب \fIdir1\fP و \fIdir2\fP و \fIdir1/xx\fP و \fIdir2/yy\fP. تنفيذ الاستدعاءات التالية بالترتيب المعطى أدناه سيُولد الأحداث التالية: .RS 4 .TP unlink("dir2/yy"); يُولد حدث \fBIN_ATTRIB\fP لـ \fIxx\fP (لأن عدد روابطه يتغير) وحدث \fBIN_DELETE\fP لـ \fIdir2\fP. .TP unlink("dir1/xx"); يُولّد أحداث \fBIN_ATTRIB\fP و\fBIN_DELETE_SELF\fP و\fBIN_IGNORED\fP لـ \fIxx\fP، وحدث \fBIN_DELETE\fP لـ \fIdir1\fP. .RE .P افترض أن تطبيقًا يراقب الدليل \fIdir\fP والدليل (الفارغ) \fIdir/subdir\fP. الأمثلة التالية تُظهر بعض الأحداث التي قد تُولّد. .RS 4 .TP mkdir("dir/new", mode); يُولّد حدث \fBIN_CREATE | IN_ISDIR\fP لـ \fIdir\fP. .TP rmdir("dir/subdir"); يُولّد أحداث \fBIN_DELETE_SELF\fP و\fBIN_IGNORED\fP لـ \fIsubdir\fP، وحدث \fBIN_DELETE | IN_ISDIR\fP لـ \fIdir\fP. .RE .SS "واجهات /proc" الواجهات التالية يمكن استخدامها لتحديد كمية ذاكرة النواة التي يستهلكها inotify: .TP \fI/proc/sys/fs/inotify/max_queued_events\fP القيمة في هذا الملف تُستخدم عندما يستدعي تطبيق \fBinotify_init\fP(2) لتعيين حد أعلى لعدد الأحداث التي يمكن وضعها في طابور لنفس نسخة inotify. الأحداث التي تتجاوز هذا الحد تُسقط، لكن حدث \fBIN_Q_OVERFLOW\fP يُولّد دائمًا. .TP \fI/proc/sys/fs/inotify/max_user_instances\fP هذا يُحدد حدًا أعلى لعدد نسخ inotify التي يمكن إنشاؤها لكل معرف مستخدم حقيقي. .TP \fI/proc/sys/fs/inotify/max_user_watches\fP هذا يُحدد حدًا أعلى لعدد المراقبات التي يمكن إنشاؤها لكل معرف مستخدم حقيقي. .SH المعايير لينكس. .SH التاريخ Inotify دُمج في Linux 2.6.13. واجهات المكتبة المطلوبة أُضيفت في glibc 2.4. (\fBIN_DONT_FOLLOW\fP و\fBIN_MASK_ADD\fP و\fBIN_ONLYDIR\fP أُضيفت في glibc 2.5.) .SH ملاحظات مُعرّفات ملفات inotify يمكن مراقبتها باستخدام \fBselect\fP(2) و\fBpoll\fP(2) و\fBepoll\fP(7). عندما يكون حدث متاحًا، يُشير مُعرّف الملف إلى أنه قابل للقراءة. .P منذ Linux 2.6.25، إعلام الإدخال/الإخراج المُوجّه بالإشارة متاح لمُعرّفات ملفات inotify؛ انظر مناقشة \fBF_SETFL\fP (لتعيين علامة \fBO_ASYNC\fP) و\fBF_SETOWN\fP و\fBF_SETSIG\fP في \fBfcntl\fP(2). بنية \fIsiginfo_t\fP (الموصوفة في \fBsigaction\fP(2)) التي تُمرّر إلى معالج الإشارة تحتوي على الحقول التالية المُعيّنة: \fIsi_fd\fP يُعيّن إلى رقم مُعرّف ملف inotify؛ \fIsi_signo\fP يُعيّن إلى رقم الإشارة؛ \fIsi_code\fP يُعيّن إلى \fBPOLL_IN\fP؛ و\fBPOLLIN\fP يُعيّن في \fIsi_band\fP. .P إذا كانت أحداث inotify الناتجة المتتالية على مُعرّف ملف inotify متطابقة (نفس \fIwd\fP و\fImask\fP و\fIcookie\fP و\fIname\fP)، فإنها تُدمج في حدث واحد إذا لم يُقرأ الحدث الأقدم بعد (لكن انظر BUGS). هذا يُقلل كمية ذاكرة النواة المطلوبة لطابور الأحداث، لكنه يعني أيضًا أن التطبيق لا يمكنه استخدام inotify لعد أحداث الملفات بشكل موثوق. .P الأحداث المُعادة بالقراءة من مُعرّف ملف inotify تُشكّل طابورًا مُرتّبًا. وبالتالي، على سبيل المثال، مضمون أنه عند إعادة التسمية من دليل إلى آخر، ستُنتج الأحداث بالترتيب الصحيح على مُعرّف ملف inotify. .P مجموعة مُعرّفات المراقبة التي تُراقب عبر مُعرّف ملف inotify يمكن عرضها عبر الإدخال لمُعرّف ملف inotify في دليل العملية \fI/proc/\fPpid\fI/fdinfo\fP. انظر \fBproc\fP(5) لمزيد من التفاصيل. \fBFIONREAD\fP \fBioctl\fP(2) يُعيد عدد البايتات المتاحة للقراءة من مُعرّف ملف inotify. .SS "القيود والتحذيرات" واجهة برمجة inotify لا تُوفّر معلومات عن المستخدم أو العملية التي أثارت حدث inotify. على وجه الخصوص، لا توجد طريقة سهلة لعملية تُراقب الأحداث عبر inotify لتمييز الأحداث التي تُثيرها بنفسها عن تلك التي تُثار بواسطة عمليات أخرى. .P Inotify يُبلغ فقط عن الأحداث التي يُثيرها برنامج في مساحة المستخدم عبر واجهة برمجة نظام الملفات. نتيجة لذلك، لا يلتقط الأحداث البعيدة التي تحدث على أنظمة ملفات الشبكة. (يجب على التطبيقات العودة إلى استقصاء نظام الملفات لالتقاط مثل هذه الأحداث.) علاوة على ذلك، أنظمة ملفات زائفة متنوعة مثل \fI/proc\fP و\fI/sys\fP و\fI/dev/pts\fP غير قابلة للمراقبة باستخدام inotify. .P واجهة برمجة inotify لا تُبلغ عن وصولات وتعديلات الملفات التي قد تحدث بسبب \fBmmap\fP(2) و\fBmsync\fP(2) و\fBmunmap\fP(2). .P واجهة برمجة inotify تُحدد الملفات المتأثرة باسم الملف. ومع ذلك، بحلول الوقت الذي يعالج فيه تطبيق حدث inotify، قد يكون اسم الملف قد حُذف أو أُعيدت تسميته بالفعل. .P واجهة برمجة inotify تُحدد الأحداث عبر مُعرّفات المراقبة. من مسؤولية التطبيق تخزين تعيين (إذا كان مطلوبًا) بين مُعرّفات المراقبة وأسماء المسارات. كن على علم بأن إعادة تسمية الدلائل قد تؤثر على أسماء مسارات مخزنة متعددة. .P مراقبة الأدلة باستخدام inotify ليست متكررة: لمراقبة الأدلة الفرعية ضمن دليل، يجب إنشاء مراقبات إضافية. قد يستغرق هذا وقتًا كبيرًا لأشجار الأدلة الكبيرة. .P إذا كنت تراقب شجرة دليل كاملة، وتم إنشاء دليل فرعي جديد في تلك الشجرة أو تمت إعادة تسمية دليل موجود إلى تلك الشجرة، فاعلم أنه بحلول الوقت الذي تنشئ فيه مراقبة للدليل الفرعي الجديد، قد تكون الملفات (والأدلة الفرعية) الجديدة موجودة بالفعل داخل الدليل الفرعي. لذلك، قد ترغب في مسح محتويات الدليل الفرعي فورًا بعد إضافة المراقبة (وإذا رغبت، أضف مراقبات بشكل متكرر لأي أدلة فرعية يحتويها). .P لاحظ أن قائمة انتظار الأحداث قد تفيض. في هذه الحالة، تُفقد الأحداث. يجب على التطبيقات القوية التعامل مع احتمال فقدان الأحداث بلطف. على سبيل المثال، قد يكون من الضروري إعادة بناء جزء أو كل الخبيئة الخاصة بالتطبيق. (أحد الأساليب البسيطة، ولكن ربما المكلفة، هو إغلاق واصف ملف inotify، وتفريغ الخبيئة، وإنشاء واصف ملف inotify جديد، ثم إعادة إنشاء المراقبات وإدخالات الخبيئة للكائنات المراد مراقبتها.) .P .\" إذا تم وصل نظام ملفات فوق دليل مراقَب، لا يتم إنشاء أي حدث، ولا يتم إنشاء أحداث للكائنات الموجودة مباشرة تحت نقطة الوصل الجديدة. إذا تم فك وصل نظام الملفات لاحقًا، فسيتم إنشاء أحداث لاحقًا للدليل والكائنات التي يحتويها. .SS "التعامل مع أحداث rename()" كما ذكر أعلاه، يمكن مطابقة زوج الأحداث \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP الذي يولده \fBrename\fP(2) من خلال قيمة الكوكي المشتركة. ومع ذلك، فإن مهمة المطابقة تواجه بعض التحديات. .P عادةً ما يكون هذان الحدثان متتاليين في تدفق الأحداث المتاح عند القراءة من واصف ملف inotify. ومع ذلك، هذا غير مضمون. إذا كانت عمليات متعددة تُطلق أحداثًا لكائنات مراقَبة، فقد تظهر (في حالات نادرة) عدد عشوائي من الأحداث الأخرى بين حدثي \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP. علاوة على ذلك، ليس مضمونًا أن يتم إدراج زوج الأحداث بشكل ذري في قائمة الانتظار: قد تكون هناك فترة وجيزة حيث يظهر \fBIN_MOVED_FROM\fP، ولكن \fBIN_MOVED_TO\fP لم يظهر بعد. .P وبالتالي، فإن مطابقة زوج الأحداث \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP الذي يولده \fBrename\fP(2) هو أمر محفوف بالمخاطر بطبيعته. (لا تنس أنه إذا تمت إعادة تسمية كائن خارج دليل مراقَب، فقد لا يكون هناك حتى حدث \fBIN_MOVED_TO\fP.) يمكن استخدام الأساليب الاستكشافية (مثل افتراض أن الأحداث متتالية دائمًا) لضمان تطابق في معظم الحالات، لكنها ستفتقد حتمًا بعض الحالات، مما يتسبب في أن يرى التطبيق حدثي \fBIN_MOVED_FROM\fP و \fBIN_MOVED_TO\fP كحدثين غير مرتبطين. إذا تم تدمير واصفات المراقبة وإعادة إنشائها نتيجة لذلك، فإن واصفات المراقبة هذه ستكون غير متسقة مع واصفات المراقبة في أي أحداث معلقة. (قد تكون إعادة إنشاء واصف ملف inotify وإعادة بناء الخبيئة مفيدة للتعامل مع هذا السيناريو.) .P يجب على التطبيقات أيضًا أن تسمح باحتمال أن يكون حدث \fBIN_MOVED_FROM\fP هو آخر حدث يمكن وضعه في المخزن المؤقت الذي أرجعته الاستدعاء الحالي لـ \fBread\fP(2)، وأن حدث \fBIN_MOVED_TO\fP المصاحب قد يتم جلبه فقط في استدعاء \fBread\fP(2) التالي، والذي يجب أن يتم مع مهلة (صغيرة) لمراعاة حقيقة أن إدراج زوج الأحداث \fBIN_MOVED_FROM\fP+\fBIN_MOVED_TO\fP ليس ذريًا، وأيضًا احتمال عدم وجود أي حدث \fBIN_MOVED_TO\fP. .SH العلل .\" commit 820c12d5d6c0890bc93dd63893924a13041fdc35 قبل لينكس 3.19، لم ينشئ \fBfallocate\fP(2) أي أحداث inotify. منذ لينكس 3.19، تولد استدعاءات \fBfallocate\fP(2) أحداث \fBIN_MODIFY\fP. .P .\" FIXME . kernel commit 611da04f7a31b2208e838be55a42c7a1310ae321 .\" implies that unmount events were buggy since Linux 2.6.11 to Linux 2.6.36 .\" قبل لينكس 2.6.16، لا تعمل علامة \fBIN_ONESHOT\fP \fImask\fP. .P كما تم تصميمه وتنفيذه أصلاً، لم تتسبب علامة \fBIN_ONESHOT\fP في إنشاء حدث \fBIN_IGNORED\fP عند إسقاط المراقبة بعد حدث واحد. ومع ذلك، كأثر غير مقصود لتغييرات أخرى، منذ لينكس 2.6.36، يتم إنشاء حدث \fBIN_IGNORED\fP في هذه الحالة. .P .\" commit 1c17d18e3775485bf1e0ce79575eb637a94494a2 قبل لينكس 2.6.25، كان رمز النواة الذي كان يهدف إلى دمج الأحداث المتطابقة المتتالية (أي، كان من الممكن دمج أحدث حدثين إذا لم يتم قراءة الأقدم بعد) يتحقق بدلاً من ذلك مما إذا كان يمكن دمج أحدث حدث مع \fIأقدم\fP حدث غير مقروء. .P .\" FIXME . https://bugzilla.kernel.org/show_bug.cgi?id=77111 عند إزالة واصف مراقبة عن طريق استدعاء \fBinotify_rm_watch\fP(2) (أو بسبب حذف ملف مراقَب أو فك وصل نظام الملفات الذي يحتويه)، تظل أي أحداث معلقة غير مقروءة لواصف المراقبة هذا متاحة للقراءة. نظرًا لأنه يتم تخصيص واصفات المراقبة لاحقًا باستخدام \fBinotify_add_watch\fP(2)، تقوم النواة بالتنقل عبر نطاق واصفات المراقبة الممكنة (من 1 إلى \fBINT_MAX\fP) بشكل تدريجي. عند تخصيص واصف مراقبة حر، لا يتم إجراء أي فحص لمعرفة ما إذا كان رقم واصف المراقبة هذا يحتوي على أي أحداث معلقة غير مقروءة في قائمة انتظار inotify. وبالتالي، يمكن أن يحدث أن يتم إعادة تخصيص واصف مراقبة حتى عندما توجد أحداث معلقة غير مقروءة لتجسيد سابق لرقم واصف المراقبة ذلك، مما يؤدي إلى أن التطبيق قد يقرأ تلك الأحداث ويفسرها على أنها تنتمي إلى الملف المرتبط بواصف المراقبة المعاد تدويره حديثًا. من الناحية العملية، قد يكون احتمال الوصول إلى هذا الخطأ منخفضًا للغاية، لأنه يتطلب أن يتنقل التطبيق عبر \fBINT_MAX\fP من واصفات المراقبة، ويحرر واصف مراقبة مع ترك أحداث غير مقروءة لواصف المراقبة ذلك في قائمة الانتظار، ثم يعيد تدوير واصف المراقبة ذلك. لهذا السبب، ولأنه لم ترد تقارير عن حدوث الخطأ في التطبيقات الواقعية، فاعتبارًا من لينكس 3.15، لم يتم إجراء أي تغييرات على النواة بعد لإزالة هذا الخطأ المحتمل. .SH أمثلة يُظهر البرنامج التالي استخدام واجهة برمجة تطبيقات inotify. يحدد الأدلة التي تم تمريرها كوسائط سطر أوامر وينتظر أحداثًا من النوع \fBIN_OPEN\fP و \fBIN_CLOSE_NOWRITE\fP و \fBIN_CLOSE_WRITE\fP. .P تم تسجيل المخرجات التالية أثناء تحرير الملف \fI/home/user/temp/foo\fP وسرد الدليل \fI/tmp\fP. قبل فتح الملف والدليل، حدثت أحداث \fBIN_OPEN\fP. بعد إغلاق الملف، حدث حدث \fBIN_CLOSE_WRITE\fP. بعد إغلاق الدليل، حدث حدث \fBIN_CLOSE_NOWRITE\fP. انتهى تنفيذ البرنامج عندما ضغط المستخدم على مفتاح ENTER. .SS "مثال على الخرج" .in +4n .EX $\fB ./a.out /tmp /home/user/temp\fP; Press enter key to terminate. Listening for events. IN_OPEN: /home/user/temp/foo [file] IN_CLOSE_WRITE: /home/user/temp/foo [file] IN_OPEN: /tmp/ [directory] IN_CLOSE_NOWRITE: /tmp/ [directory] \& Listening for events stopped. .EE .in .SS "مصدر البرنامج" \& .EX #include #include #include #include #include #include #include \& /* Read all available inotify events from the file descriptor \[aq]fd\[aq]. wd is the table of watch descriptors for the directories in argv. argc is the size of wd and argv. argv is the list of watched directories. Entry 0 of wd and argv is unused. */ \& static void handle_events(int fd, int *wd, int argc, char* argv[]) { /* Some systems cannot read integer variables if they are not properly aligned. On other systems, incorrect alignment may decrease performance. Hence, the buffer used for reading from the inotify file descriptor should have the same alignment as struct inotify_event. */ \& char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event)))); const struct inotify_event *event; ssize_t size; \& /* Loop while events can be read from inotify file descriptor. */ \& for (;;) { \& /* Read some events. */ \& size = read(fd, buf, sizeof(buf)); if (size == \-1 && errno != EAGAIN) { perror("read"); exit(EXIT_FAILURE); } \& /* If the nonblocking read() found no events to read, then it returns \-1 with errno set to EAGAIN. In that case, we exit the loop. */ \& if (size <= 0) break; \& /* Loop over all events in the buffer. */ \& for (char *ptr = buf; ptr < buf + size; ptr += sizeof(struct inotify_event) + event\->len) { \& event = (const struct inotify_event *) ptr; \& /* Print event type. */ \& if (event\->mask & IN_OPEN) printf("IN_OPEN: "); if (event\->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE: "); if (event\->mask & IN_CLOSE_WRITE) printf("IN_CLOSE_WRITE: "); \& /* Print the name of the watched directory. */ \& for (size_t i = 1; i < argc; ++i) { if (wd[i] == event\->wd) { printf("%s/", argv[i]); break; } } \& /* Print the name of the file. */ \& if (event\->len) printf("%s", event\->name); \& /* Print type of filesystem object. */ \& if (event\->mask & IN_ISDIR) printf(" [directory]\[rs]n"); else printf(" [file]\[rs]n"); } } } \& int main(int argc, char* argv[]) { char buf; int fd, i, poll_num; int *wd; nfds_t nfds; struct pollfd fds[2]; \& if (argc < 2) { printf("Usage: %s PATH [PATH ...]\[rs]n", argv[0]); exit(EXIT_FAILURE); } \& printf("Press ENTER key to terminate.\[rs]n"); \& /* Create the file descriptor for accessing the inotify API. */ \& fd = inotify_init1(IN_NONBLOCK); if (fd == \-1) { perror("inotify_init1"); exit(EXIT_FAILURE); } \& /* Allocate memory for watch descriptors. */ \& wd = calloc(argc, sizeof(int)); if (wd == NULL) { perror("calloc"); exit(EXIT_FAILURE); } \& /* Mark directories for events \- file was opened \- file was closed */ \& for (i = 1; i < argc; i++) { wd[i] = inotify_add_watch(fd, argv[i], IN_OPEN | IN_CLOSE); if (wd[i] == \-1) { fprintf(stderr, "Cannot watch \[aq]%s\[aq]: %s\[rs]n", argv[i], strerror(errno)); exit(EXIT_FAILURE); } } \& /* Prepare for polling. */ \& nfds = 2; \& fds[0].fd = STDIN_FILENO; /* Console input */ fds[0].events = POLLIN; \& fds[1].fd = fd; /* Inotify input */ fds[1].events = POLLIN; \& /* Wait for events and/or terminal input. */ \& printf("Listening for events.\[rs]n"); for (;;) { poll_num = poll(fds, nfds, \-1); if (poll_num == \-1) { if (errno == EINTR) continue; perror("poll"); exit(EXIT_FAILURE); } \& if (poll_num > 0) { \& if (fds[0].revents & POLLIN) { \& /* Console input is available. Empty stdin and quit. */ \& while (read(STDIN_FILENO, &buf, 1) > 0 && buf != \[aq]\[rs]n\[aq]) continue; break; } \& if (fds[1].revents & POLLIN) { \& /* Inotify events are available. */ \& handle_events(fd, wd, argc, argv); } } } \& printf("Listening for events stopped.\[rs]n"); \& /* Close inotify file descriptor. */ \& close(fd); \& free(wd); exit(EXIT_SUCCESS); } .EE .SH "انظر أيضًا" \fBinotifywait\fP(1), \fBinotifywatch\fP(1), \fBinotify_add_watch\fP(2), \fBinotify_init\fP(2), \fBinotify_init1\fP(2), \fBinotify_rm_watch\fP(2), \fBread\fP(2), \fBstat\fP(2), \fBfanotify\fP(7) .P \fIDocumentation/filesystems/inotify.rst\fP في شجرة مصدر نواة لينكس .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .