Scroll to navigation

kcmp(2) System Calls Manual kcmp(2)

الاسم

kcmp - مقارنة عمليتين لتحديد ما إذا كانتا تشاركان مورد نواة

المكتبة

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

موجز

#include <linux/kcmp.h>       /* Definition of KCMP_* constants */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
int syscall(SYS_kcmp, pid_t pid1, pid_t pid2, int type,
            unsigned long idx1, unsigned long idx2);

ملاحظة: لا توفر glibc غلافًا لـ kcmp()، مما يستلزم استخدام syscall(2).

الوصف

يمكن استخدام استدعاء النظام kcmp() للتحقق مما إذا كانت العمليتان المحددتان بواسطة pid1 و pid2 تشاركان مورد نواة مثل الذاكرة الافتراضية، وواصفات الملفات، وما إلى ذلك.

يخضع الإذن لاستخدام kcmp() لفحوصات وضع الوصول ptrace PTRACE_MODE_READ_REALCREDS ضد كل من pid1 و pid2؛ انظر ptrace(2).

تحدد الوسيطة type أي مورد سيتم مقارنته في العمليتين. تأخذ إحدى القيم التالية:

التحقق مما إذا كان واصف الملف idx1 في العملية pid1 يشير إلى نفس وصف الملف المفتوح (انظر open(2)) مثل واصف الملف idx2 في العملية pid2. يمكن أن يحدث وجود واصفي ملف يشيران إلى نفس وصف الملف المفتوح نتيجة لـ dup(2) (وما شابه) fork(2)، أو تمرير واصفات الملفات عبر مقبس نطاق (انظر unix(7)).
التحقق مما إذا كانت العمليتان تشاركان نفس مجموعة واصفات الملفات المفتوحة. يتم تجاهل الوسيطتين idx1 و idx2. انظر مناقشة العلم CLONE_FILES في clone(2).
التحقق مما إذا كانت العمليتان تشاركان نفس معلومات نظام الملفات (أي قناع إنشاء وضع الملف، دليل العمل، وجذر نظام الملفات). يتم تجاهل الوسيطتين idx1 و idx2. انظر مناقشة العلم CLONE_FS في clone(2).
التحقق مما إذا كانت العمليتان تشاركان سياق الإدخال/الإخراج. يتم تجاهل الوسيطتين idx1 و idx2. انظر مناقشة العلم CLONE_IO في clone(2).
التحقق مما إذا كانت العمليتان تشاركان نفس جدول ترتيبات الإشارات. يتم تجاهل الوسيطتين idx1 و idx2. انظر مناقشة العلم CLONE_SIGHAND في clone(2).
تحقق مما إذا كانت العمليات تشترك في نفس قائمة عمليات التراجع عن إشارات System يتم تجاهل الوسيطتين idx1 و idx2. انظر شرح العلامة CLONE_SYSVSEM في clone(2).
التحقق مما إذا كانت العمليتان تشاركان نفس مساحة العنوان. يتم تجاهل الوسيطتين idx1 و idx2. انظر مناقشة العلم CLONE_VM في clone(2).
التحقق مما إذا كان واصف الملف idx1 للعملية pid1 موجودًا في مثيل epoll(7) الموصوف بواسطة idx2 للعملية pid2. الوسيطة idx2 هي مؤشر لبنية حيث يتم وصف الملف الهدف. هذه البنية لها الشكل:


struct kcmp_epoll_slot {

__u32 efd;
__u32 tfd;
__u64 toff; };

داخل هذه البنية، efd هو واصف ملف epoll مُعاد من epoll_create(2)، tfd هو رقم واصف ملف هدف، و toff هو إزاحة ملف هدف تُحسب من الصفر. يمكن تسجيل عدة أهداف مختلفة بنفس رقم واصف الملف، ويساعد تعيين إزاحة محددة في فحص كل منها.

لاحظ أن kcmp() غير محمي ضد النتائج الإيجابية الخاطئة التي قد تحدث إذا كانت العمليات قيد التشغيل حاليًا. يجب إيقاف العمليات عن طريق إرسال SIGSTOP (انظر signal(7)) قبل الفحص باستدعاء النظام هذا للحصول على نتائج ذات معنى.

قيمة الإرجاع

قيمة الإرجاع لاستدعاء ناجح لـ kcmp() هي ببساطة نتيجة المقارنة الحسابية لمؤشرات النواة (عندما تقارن النواة الموارد، تستخدم عناوين ذاكرتها).

أسهل طريقة للشرح هي النظر في مثال. افترض أن v1 و v2 هما عنوانا الموارد المناسبة، فإن قيمة الإرجاع تكون إحدى التالية:

0
v1 يساوي v2؛ بمعنى آخر، تشارك العمليتان المورد.
1
v1 أصغر من v2.
2
v1 أكبر من v2.
3
v1 لا يساوي v2، لكن معلومات الترتيب غير متوفرة.

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

صُمم kcmp() لإرجاع قيم مناسبة للفرز. هذا مفيد بشكل خاص إذا احتاج المرء لمقارنة عدد كبير من واصفات الملفات.

الأخطاء

type هو KCMP_FILE و fd1 أو fd2 ليس واصف ملف مفتوح.
فتحة epoll المُشار إليها بواسطة idx2 خارج نطاق عنوان المستخدم.
type غير صالح.
الملف الهدف غير موجود في مثيل epoll(7).
صلاحية غير كافية لفحص موارد العملية. القدرة CAP_SYS_PTRACE مطلوبة لفحص العمليات التي لا تملكها. قد تنطبق قيود ptrace أخرى أيضًا، مثل CONFIG_SECURITY_YAMA، والتي عندما تكون /proc/sys/kernel/yama/ptrace_scope مساوية لـ 2، تحد kcmp() من العمليات الفرعية؛ انظر ptrace(2).
العملية pid1 أو pid2 غير موجودة.

المعايير

لينكس.

التاريخ

لينكس 3.5.

قبل لينكس 5.12، تكون استدعاء النظام هذا متاحة فقط إذا كان النواة مُهيأة بـ CONFIG_CHECKPOINT_RESTORE، لأن الغرض الأصلي من استدعاء النظام كان لميزة نقطة التفتيش/الاستعادة في مساحة المستخدم (CRIU). (البديل لاستدعاء النظام هذا كان سيكون كشف معلومات العملية المناسبة عبر نظام ملفات proc(5)؛ اعتُبر هذا غير مناسب لأسباب أمنية.) منذ لينكس 5.12، تكون استدعاء النظام هذه متاحة أيضًا إذا كانت النواة مُهيأة بـ CONFIG_KCMP.

ملاحظات

انظر clone(2) للحصول على بعض المعلومات الأساسية حول الموارد المشتركة المُشار إليها في هذه الصفحة.

أمثلة

يستخدم البرنامج أدناه kcmp() لاختبار ما إذا كانت أزواج واصفات الملفات تشير إلى نفس وصف الملف المفتوح. يختبر البرنامج حالات مختلفة لأزواج واصفات الملفات، كما هو موصوف في مخرجات البرنامج. مثال على تشغيل البرنامج هو كما يلي:


$ ./a.out;
Parent PID is 1144
Parent opened file on FD 3
PID of child of fork() is 1145
	Compare duplicate FDs from different processes:
		kcmp(1145, 1144, KCMP_FILE, 3, 3) ==> same
Child opened file on FD 4
	Compare FDs from distinct open()s in same process:
		kcmp(1145, 1145, KCMP_FILE, 3, 4) ==> different
Child duplicated FD 3 to create FD 5
	Compare duplicated FDs in same process:
		kcmp(1145, 1145, KCMP_FILE, 3, 5) ==> same

مصدر البرنامج

#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <linux/kcmp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static int
kcmp(pid_t pid1, pid_t pid2, int type,

unsigned long idx1, unsigned long idx2) {
return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2); } static void test_kcmp(char *msg, pid_t pid1, pid_t pid2, int fd_a, int fd_b) {
printf("\t%s\n", msg);
printf("\t\tkcmp(%jd, %jd, KCMP_FILE, %d, %d) ==> %s\n",
(intmax_t) pid1, (intmax_t) pid2, fd_a, fd_b,
(kcmp(pid1, pid2, KCMP_FILE, fd_a, fd_b) == 0) ?
"same" : "different"); } int main(void) {
int fd1, fd2, fd3;
static const char pathname[] = "/tmp/kcmp.test";
fd1 = open(pathname, O_CREAT | O_RDWR, 0600);
if (fd1 == -1)
err(EXIT_FAILURE, "open");
printf("Parent PID is %jd\n", (intmax_t) getpid());
printf("Parent opened file on FD %d\n\n", fd1);
switch (fork()) {
case -1:
err(EXIT_FAILURE, "fork");
case 0:
printf("PID of child of fork() is %jd\n", (intmax_t) getpid());
test_kcmp("Compare duplicate FDs from different processes:",
getpid(), getppid(), fd1, fd1);
fd2 = open(pathname, O_CREAT | O_RDWR, 0600);
if (fd2 == -1)
err(EXIT_FAILURE, "open");
printf("Child opened file on FD %d\n", fd2);
test_kcmp("Compare FDs from distinct open()s in same process:",
getpid(), getpid(), fd1, fd2);
fd3 = dup(fd1);
if (fd3 == -1)
err(EXIT_FAILURE, "dup");
printf("Child duplicated FD %d to create FD %d\n", fd1, fd3);
test_kcmp("Compare duplicated FDs in same process:",
getpid(), getpid(), fd1, fd3);
break;
default:
wait(NULL);
}
exit(EXIT_SUCCESS); }

انظر أيضًا

clone(2), unshare(2)

ترجمة

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

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

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

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