semctl(2)

الاسم
semctl - عمليات التحكم في الإشارات (semaphore) لنظام V

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

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

int semctl(int semid, int semnum, int op, ...);

الوصف
semctl() ينفذ عملية التحكم المحددة بواسطة op على مجموعة الإشارات (semaphore) لنظام V التي يُعرّفها semid، أو على الإشارة رقم semnum من تلك المجموعة. (يتم ترقيم الإشارات في المجموعة بدءًا من 0.)

تحتوي هذه الدالة على ثلاث أو أربع وسائط، اعتمادًا على op. عندما يكون هناك أربع وسائط، تكون الوسيطة الرابعة من النوع union semun. يجب على البرنامج المستدعي تعريف هذا الاتحاد (union) كما يلي:

    union semun {
        int              val;    /* Value for SETVAL */
        struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
        unsigned short  *array;  /* Array for GETALL, SETALL */
        struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                    (Linux-specific) */
    };

يتم تعريف بنية البيانات semid_ds في <sys/sem.h> كما يلي:

    struct semid_ds {
        struct ipc_perm sem_perm;  /* Ownership and permissions */
        time_t          sem_otime; /* Last semop time */
        time_t          sem_ctime; /* Creation time/time of last
                                      modification via semctl() */
        unsigned long   sem_nsems; /* # of semaphores in set */
    };

حقول بنية semid_ds هي كما يلي:

sem_perm
    هذه بنية ipc_perm (انظر أدناه) تحدد أذونات الوصول على مجموعة الإشارات.

sem_otime
    وقت آخر استدعاء نظام semop(2).

sem_ctime
    وقت إنشاء مجموعة الإشارات أو وقت آخر عملية semctl() IPCSET أو SETVAL أو SETALL.

sem_nsems
    عدد الإشارات في المجموعة. يتم الإشارة إلى كل إشارة في المجموعة بعدد صحيح غير سالب يتراوح من 0 إلى sem_nsems-1.

بنية ipc_perm مُعرفة كالتالي (الحقول المميزة قابلة للضبط باستخدام IPC_SET):

    struct ipc_perm {
        key_t          __key; /* Key supplied to semget(2) */
        uid_t          uid;   /* Effective UID of owner */
        gid_t          gid;   /* Effective GID of owner */
        uid_t          cuid;  /* Effective UID of creator */
        gid_t          cgid;  /* Effective GID of creator */
        unsigned short mode;  /* Permissions */
        unsigned short __seq; /* Sequence number */
    };

تحدد البتات الـ 9 الأقل أهمية في حقل mode لهيكل ipc_perm أذونات الوصول لقطاع الذاكرة المشتركة. بتات الأذونات هي كما يلي:
0400 | مقروء من المستخدم
0200 | الكتابة بواسطة المستخدم
0040 | مقروء من المجموعة
0020 | الكتابة بواسطة المجموعة
0004 | مقروء من الآخرين
0002 | الكتابة بواسطة الآخرين

في الواقع، تعني "write" "تعديل" لمجموعة الإشارات. البتات 0100 و0010 و0001 (بتات التنفيذ) غير مستخدمة من قبل النظام.

القيم الصالحة لـ op هي:

IPC_STAT
    انسخ المعلومات من بنية بيانات النواة المرتبطة بـ semid إلى بنية semid_ds المشار إليها بواسطة arg.buf. يتم تجاهل الوسيطة semnum. يجب أن تمتلك العملية المستدعية إذن قراءة على مجموعة الإشارات.

IPC_SET
    اكتب قيم بعض أعضاء بنية semid_ds المشار إليها بواسطة arg.buf إلى بنية بيانات النواة المرتبطة بمجموعة الإشارات هذه، مع تحديث عضو sem_ctime الخاص بها أيضًا.

    يتم تحديث الأعضاء التالية من البنية: sem_perm.uid وsem_perm.gid و(أقل 9 بتات أهمية من) sem_perm.mode.

    يجب أن يتطابق UID الفعّال للعملية المستدعية مع المالك (sem_perm.uid) أو المنشئ (sem_perm.cuid) لمجموعة الإشارات، أو يجب أن يكون المستدعي متميزًا (privileged). يتم تجاهل الوسيطة semnum.

IPC_RMID
    أزل مجموعة الإشارات فورًا، مع إيقاظ جميع العمليات المحظورة في استدعاءات semop(2) على المجموعة (مع إرجاع خطأ وتعيين errno إلى EIDRM). يجب أن يتطابق معرف المستخدم الفعّال للعملية المستدعية مع المنشئ أو المالك لمجموعة الإشارات، أو يجب أن يكون المستدعي متميزًا. يتم تجاهل الوسيطة semnum.

IPC_INFO (خاص بلينكس)
    أعد معلومات حول حدود ومعلمات الإشارات على مستوى النظام في البنية المشار إليها بواسطة arg.__buf. هذه البنية من النوع seminfo، المُعرّفة في <sys/sem.h> إذا تم تعريف ماكرو اختبار الميزة _GNU_SOURCE:

        struct seminfo {
            int semmap;  /* Number of entries in semaphore
                            map; unused within kernel */
            int semmni;  /* Maximum number of semaphore sets */
            int semmns;  /* Maximum number of semaphores in all
                            semaphore sets */
            int semmnu;  /* System-wide maximum number of undo
                            structures; unused within kernel */
            int semmsl;  /* Maximum number of semaphores in a
                            set */
            int semopm;  /* Maximum number of operations for
                            semop(2) */
            int semume;  /* Maximum number of undo entries per
                            process; unused within kernel */
            int semusz;  /* Size of struct sem_undo */
            int semvmx;  /* Maximum semaphore value */
            int semaem;  /* Max. value that can be recorded for
                            semaphore adjustment (SEM_UNDO) */
        };

    يمكن تغيير إعدادات semmsl وsemmns وsemopm وsemmni عبر /proc/sys/kernel/sem؛ انظر proc(5) للتفاصيل.

SEM_INFO (خاص بلينكس)
    أعد بنية seminfo تحتوي على نفس المعلومات كما في IPC_INFO، باستثناء أن الحقول التالية تُعاد بمعلومات حول موارد النظام المستهلكة بواسطة الإشارات: حقل semusz يعيد عدد مجموعات الإشارات الموجودة حاليًا على النظام؛ وحقل semaem يعيد العدد الإجمالي للإشارات في جميع مجموعات الإشارات على النظام.

SEM_STAT (خاص بلينكس)
    أعد بنية semid_ds كما في IPC_STAT. ومع ذلك، فإن الوسيطة semid ليست معرف إشارة، بل هي فهرس في المصفوفة الداخلية للنواة التي تحتفظ بمعلومات حول جميع مجموعات الإشارات على النظام.

SEM_STAT_ANY (خاص بلينكس، منذ لينكس 4.17)
    أعد بنية semid_ds كما في SEM_STAT. لكن، لا يُفحص sem_perm.mode للوصول للقراءة لـ semid مما يعني أن أي مستخدم يمكنه استخدام هذه العملية (تمامًا كما يمكن لأي مستخدم قراءة /proc/sysvipc/sem للحصول على نفس المعلومات).

GETALL
    أعد semval (أي القيمة الحالية) لجميع الإشارات في المجموعة إلى arg.array. الوسيط semnum يُتجاهل. يجب أن تملك العملية المستدعية صلاحية قراءة على مجموعة الإشارة.

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

GETPID
    أعد قيمة sempid للإشارة رقم semnum في المجموعة. هذا هو PID العملية التي نفذت آخر عملية على تلك الإشارة (لكن انظر الإصدارات). يجب أن تملك العملية المستدعية صلاحية قراءة على مجموعة الإشارة.

GETVAL
    أعد semval (أي قيمة الإشارة) للإشارة رقم semnum في المجموعة. يجب أن تملك العملية المستدعية صلاحية قراءة على مجموعة الإشارة.

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

SETALL
    اضبط قيم semval لجميع الإشارات في المجموعة باستخدام arg.array، مع تحديث عضو sem_ctime من بنية semid_ds المرتبطة بالمجموعة. تُمسح إدخالات التراجع (انظر semop(2)) للإشارات المعدلة في جميع العمليات. إذا كانت التغييرات في قيم الإشارات تسمح باستدعاءات semop(2) المحجوبة في عمليات أخرى بالمتابعة، فتُستيقظ تلك العمليات. الوسيط semnum يُتجاهل. يجب أن تملك العملية المستدعية صلاحية تغيير (كتابة) على مجموعة الإشارة.

SETVAL
    اضبط قيمة الإشارة (semval) إلى arg.val للإشارة رقم semnum في المجموعة، مع تحديث عضو sem_ctime من بنية semid_ds المرتبطة بالمجموعة. تُمسح إدخالات التراجع للإشارات المعدلة في جميع العمليات. إذا كانت التغييرات في قيم الإشارات تسمح باستدعاءات semop(2) المحجوبة في عمليات أخرى بالمتابعة، فتُستيقظ تلك العمليات. يجب أن تملك العملية المستدعية صلاحية تغيير على مجموعة الإشارة.

قيمة الإرجاع
عند النجاح، تُرجع semctl() قيمة غير سالبة تعتمد على op كالتالي:

GETNCNT
    قيمة semncnt.

GETPID
    قيمة sempid.

GETVAL
    قيمة semval.

GETZCNT
    قيمة semzcnt.

IPC_INFO
    فهرس أعلى إدخال مستخدم في المصفوفة الداخلية للنواة التي تسجل معلومات عن جميع مجموعات الإشارات. (يمكن استخدام هذه المعلومات مع عمليات SEM_STAT أو SEM_STAT_ANY المتكررة للحصول على معلومات عن جميع مجموعات الإشارات في النظام.)

SEM_INFO
    كما في IPC_INFO.

SEM_STAT
    معرف مجموعة الإشارة التي أُعطي فهرسها في semid.

SEM_STAT_ANY
    كما في SEM_STAT.

جميع قيم op الأخرى تُرجع 0 عند النجاح.

عند الفشل، تُرجع semctl() القيمة -1 وتُعيِّن errno للإشارة إلى الخطأ.

الأخطاء

EACCES
    الوسيطة op تحمل إحدى القيم GETALL أو GETPID أو GETVAL أو GETNCNT أو GETZCNT أو IPC_STAT أو SEM_STAT أو SEM_STAT_ANY أو SETALL أو SETVAL ولا تمتلك العملية المستدعية الصلاحيات المطلوبة على مجموعة الإشارات ولا تمتلك القدرة CAP_IPC_OWNER في مساحة المستخدم التي تحكم مساحة IPC الخاصة بها.

EFAULT
    العنوان المشار إليه بواسطة arg.buf أو arg.array غير قابل للوصول.

EIDRM
    حُذفت مجموعة السيمافور.

EINVAL
    قيمة غير صالحة لـ op أو semid. أو: بالنسبة لعملية SEM_STAT، تشير قيمة الفهرس المحددة في semid إلى فتحة مصفوفة غير مستخدمة حالياً.

EPERM
    الوسيطة op تحمل القيمة IPC_SET أو IPC_RMID لكن معرف المستخدم الفعّال للعملية المستدعية ليس هو المنشئ (كما هو موجود في sem_perm.cuid) أو المالك (كما هو موجود في sem_perm.uid) لمجموعة الإشارات، ولا تمتلك العملية القدرة CAP_SYS_ADMIN.

ERANGE
    الوسيطة op تحمل القيمة SETALL أو SETVAL والقيمة التي سيُعيَّن إليها semval (لبعض الإشارات في المجموعة) أقل من 0 أو أكبر من الحد التنفيذي SEMVMX.

الإصدارات
يحدد POSIX.1 حقل sem_nsems في بنية semid_ds على أنه من النوع unsigned short، والحقل مُعرَّف بهذا الشكل على معظم الأنظمة الأخرى. كان مُعرَّفاً بهذا الشكل أيضًا على Linux 2.2 والإصدارات الأقدم، لكن منذ Linux 2.4، أصبح الحقل من النوع unsigned long.

  قيمة sempid
يُعرِّف POSIX.1 sempid على أنه "معرف العملية لآخر عملية" على إشارة، ويُلاحظ صراحةً أن هذه القيمة تُعيَّن بواسطة استدعاء ناجح لـ semop(2)، مما يعني أن لا واجهة أخرى تؤثر على قيمة sempid.

بينما تلتزم بعض التطبيقات بالسلوك المحدد في POSIX.1، لا تفعل أخرى ذلك. (الخطأ هنا ربما يقع على POSIX.1 بقدر ما فشل في التقاط النطاق الكامل لسلوكيات التطبيق الموجودة.) تُحدِّث تطبيقات أخرى متنوعة أيضًا sempid للعمليات الأخرى التي تُحدِّث قيمة الإشارة: عمليات SETVAL و SETALL، بالإضافة إلى التعديلات على الإشارات التي تُجرى عند إنهاء العملية نتيجة استخدام العلم SEM_UNDO (انظر semop(2)).

يُحدِّث Linux أيضًا sempid لعمليات SETVAL وتعديلات الإشارات. ومع ذلك، بشكل غير متسق إلى حد ما، حتى Linux 4.5 بما في ذلك، لم يُحدِّث النواة sempid لعمليات SETALL. تم تصحيح هذا في Linux 4.6.

المعايير
POSIX.1-2024.

التاريخ
POSIX.1-2001، SVr4.

تم تعريف عدة حقول في struct semid_ds على أنها من النوع short تحت Linux 2.2 وأصبحت من النوع long تحت Linux 2.4. للاستفادة من هذا، يكفي إعادة الترجمة تحت glibc-2.1.91 أو أحدث. (تميز النواة بين الاستدعاءات القديمة والجديدة بواسطة علم IPC_64 في op.)

في بعض الإصدارات الأقدم من glibc، كان الاتحاد semun مُعرَّفاً في <sys/sem.h>، لكن POSIX.1 يتطلب أن يُعرِّف المستدعي هذا الاتحاد. في إصدارات glibc حيث هذا الاتحاد غير مُعرَّف، يتم تعريف الماكرو _SEM_SEMUN_UNDEFINED في <sys/sem.h>.

ملاحظات
تُستخدم عمليات IPC_INFO و SEM_STAT و SEM_INFO بواسطة برنامج ipcs(1) لتوفير معلومات عن الموارد المخصصة. في المستقبل، قد يتم تعديل هذه أو نقلها إلى واجهة نظام الملفات /proc.

الحد النظامي التالي على مجموعات الإشارات يؤثر على استدعاء semctl():

SEMVMX
    القيمة القصوى لـ semval: تعتمد على التطبيق (32767).

لتحقيق قابلية نقل أكبر، من الأفضل دائماً استدعاء semctl() بأربع وسائط.

أمثلة
انظر shmop(2).

انظر أيضًا
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), sysvipc(7)

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

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

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