pidfd_send_signal(2)

الاسم
pidfd_send_signal - إرسال إشارة إلى عملية محددة بواصف ملف

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

موجز
#include <linux/signal.h>     /* Definition of SIG* constants */
#include <signal.h>           /* Definition of SI_* constants */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(SYS_pidfd_send_signal, int pidfd, int sig,
            siginfo_t *_Nullable info, unsigned int flags);

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

الوصف
ترسل استدعاء النظام pidfd_send_signal() الإشارة sig إلى العملية الهدف المشار إليها بـ pidfd، وهو واصف ملف PID يشير إلى عملية.

إذا أشارت وسيطة info إلى مخزن siginfo_t، فيجب ملء ذلك المخزن كما هو موصوف في rt_sigqueueinfo(2).

إذا كانت وسيطة info مؤشرًا فارغًا، فهذا يعادل تحديد مؤشر إلى مخزن siginfo_t تتطابق حقوله مع القيم المقدمة ضمنيًا عند إرسال إشارة باستخدام kill(2):

•   يُضبط si_signo على رقم الإشارة؛
•   يُضبط si_errno على 0؛
•   يُضبط si_code على SI_USER؛
•   يُضبط si_pid على PID للمتصل؛ و
•   يُضبط si_uid على معرف المستخدم الحقيقي للمتصل.

يجب أن تكون العملية المتصلة إما في نفس نطاق PID مثل العملية المشار إليها بـ pidfd، أو في سلف لذلك النطاق.

تسمح وسيطة flags بتعديل نطاق الإشارة. مبدئيًا، يُستنتج نطاق الإشارة من وسيطة pidfd. على سبيل المثال، إذا كان pidfd يشير إلى خيط محدد —أي، أُنشئ pidfd عبر pidfd_open(2) باستخدام العلم PIDFD_THREAD أو عبر clone3(2) باستخدام العلم CLONE_PIDFD مع العلم CLONE_THREAD— فإن تمرير pidfd إلى pidfd_send_signal(2) وترك وسيطة flags كـ 0 سيؤدي إلى إرسال الإشارة إلى الخيط المحدد المشار إليه بـ pidfd.

PIDFD_SIGNAL_THREAD (منذ Linux 6.9)
    يضمن إرسال الإشارة إلى الخيط المحدد المشار إليه بـ pidfd.

PIDFD_SIGNAL_THREAD_GROUP (منذ Linux 6.9)
    إذا كان pidfd يشير إلى قائد مجموعة خيوط، يضمن إرسال الإشارة إلى مجموعة الخيوط، حتى لو أُنشئ pidfd للإشارة إلى خيط محدد.

PIDFD_SIGNAL_PROCESS_GROUP (منذ Linux 6.9)
    إذا كان pidfd يشير إلى قائد مجموعة عمليات، يضمن إرسال الإشارة إلى مجموعة العمليات، حتى لو أُنشئ pidfd للإشارة إلى خيط محدد أو إلى قائد مجموعة خيوط.

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

الأخطاء

EBADF
    pidfd ليس واصف ملف PID صالحاً.

EINVAL
    sig ليست إشارة صالحة.

EINVAL
    العملية المتصلة ليست في نطاق PID يمكنها منه إرسال إشارة إلى العملية الهدف.

EINVAL
    flags غير صالح.

EPERM
    لا تملك العملية المتصلة الإذن لإرسال الإشارة إلى العملية الهدف.

EPERM
    لا يشير pidfd إلى العملية المتصلة، و info.si_code غير صالح (انظر rt_sigqueueinfo(2)).

ESRCH
    العملية الهدف غير موجودة (أي أنها أُنهيت وانتُظر اكتمالها).

المعايير
لينكس.

التاريخ
Linux 5.1.

ملاحظات

  واصفات ملفات PID
وسيطة pidfd هي واصف ملف PID، واصف ملف يشير إلى عملية. يمكن الحصول على مثل هذا الواصف بأي من الطرق التالية:

•   بفتح دليل /proc/pid؛

•   باستخدام pidfd_open(2); أو

•   عبر واصف ملف PID الذي يُرجعه استدعاء clone(2) أو clone3(2) يُحدد العَلَم CLONE_PIDFD.

يسمح استدعاء النظام pidfd_send_signal() بتجنب حالات السباق التي تحدث عند استخدام الواجهات التقليدية (مثل kill(2)) لإرسال إشارة إلى عملية. المشكلة هي أن الواجهات التقليدية تُحدد العملية الهدف عبر معرف العملية (PID)، مما قد يؤدي إلى إرسال المُرسِل إشارة إلى العملية الخاطئة عن طريق الخطأ إذا كانت العملية المستهدفة أصلاً قد انتهت وأُعيد استخدام PID الخاص بها لعملية أخرى. على النقيض، واصف ملف PID هو مرجع مستقر لعملية محددة؛ إذا انتهت تلك العملية، يفشل pidfd_send_signal() مع الخطأ ESRCH.

أمثلة
    #define _GNU_SOURCE
    #include <fcntl.h>
    #include <limits.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/syscall.h>
    #include <unistd.h>

    static int
    pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
                      unsigned int flags)
    {
        return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
    }

    int
    main(int argc, char *argv[])
    {
        int        pidfd, sig;
        char       path[PATH_MAX];
        siginfo_t  info;

        if (argc != 3) {
            fprintf(stderr, "Usage: %s <pid> <signal>\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        sig = atoi(argv[2]);

        /* Obtain a PID file descriptor by opening the /proc/PID directory
           of the target process.  */

        snprintf(path, sizeof(path), "/proc/%s", argv[1]);

        pidfd = open(path, O_RDONLY);
        if (pidfd == -1) {
            perror("open");
            exit(EXIT_FAILURE);
        }

        /* Populate a 'siginfo_t' structure for use with
           pidfd_send_signal().  */

        memset(&info, 0, sizeof(info));
        info.si_code = SI_QUEUE;
        info.si_signo = sig;
        info.si_errno = 0;
        info.si_uid = getuid();
        info.si_pid = getpid();
        info.si_value.sival_int = 1234;

        /* Send the signal.  */

        if (pidfd_send_signal(pidfd, sig, &info, 0) == -1) {
            perror("pidfd_send_signal");
            exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
clone(2), kill(2), pidfd_open(2), rt_sigqueueinfo(2), sigaction(2), pid_namespaces(7), signal(7)

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

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

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