CMSG(3)

الاسم
CMSG_ALIGN و CMSG_SPACE و CMSG_NXTHDR و CMSG_FIRSTHDR - الوصول إلى البيانات المساعدة (ancillary data)

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

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

struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh,
                            struct cmsghdr *cmsg);
size_t CMSG_ALIGN(size_t length);
size_t CMSG_SPACE(size_t length);
size_t CMSG_LEN(size_t length);
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);

الوصف
تُستخدم هذه الكليّات لإنشاء والوصول إلى رسائل التحكم (وتسمى أيضًا البيانات المساعدة) التي ليست جزءًا من حمولة المقبس. قد تتضمن معلومات التحكم هذه الواجهة التي استُلمت عليها الحزمة، وحقول رأس متنوعة نادرة الاستخدام، ووصف خطأ موسع، ومجموعة من واصفات الملفات، أو بيانات اعتماد UNIX. على سبيل المثال، يمكن استخدام رسائل التحكم لإرسال حقول رأس إضافية مثل خيارات IP. تُرسل البيانات المساعدة باستدعاء sendmsg(2) وتُستلم باستدعاء recvmsg(2). راجع صفحات الدليل الخاصة بهما لمزيد من المعلومات.

البيانات المساعدة هي سلسلة من بنى cmsghdr مع بيانات ملحقة. راجع صفحات دليل البروتوكول المحدد لأنواع رسائل التحكم المتاحة. يمكن ضبط الحجم الأقصى للمخزن المؤقت المساعد المسموح به لكل مقبس باستخدام /proc/sys/net/core/optmem_max؛ انظر socket(7).

تُعرّف بنية cmsghdr كالتالي:

    struct cmsghdr {
        size_t cmsg_len;    /* Data byte count, including header
                               (type is socklen_t in POSIX) */
        int    cmsg_level;  /* Originating protocol */
        int    cmsg_type;   /* Protocol-specific type */
    /* followed by
       unsigned char cmsg_data[]; */
    };

لا ينبغي أبدًا الوصول إلى سلسلة بنى cmsghdr مباشرة. بدلاً من ذلك، استخدم فقط الكليّات التالية:

CMSG_FIRSTHDR()
    تُرجع مؤشرًا إلى أول cmsghdr في المخزن المؤقت للبيانات المساعدة المرتبط بـ msghdr المُمرر. تُرجع NULL إذا لم تكن هناك مساحة كافية لـ cmsghdr في المخزن.

CMSG_NXTHDR()
    تُرجع cmsghdr الصحيح التالي بعد cmsghdr المُمرر. تُرجع NULL عندما لا توجد مساحة كافية متبقية في المخزن.

    عند تهيئة مخزن سيحتوي على سلسلة من بنى cmsghdr (مثلًا، لإرسالها مع sendmsg(2))، يجب أولاً تهيئة ذلك المخزن بالأصفار لضمان التشغيل الصحيح لـ CMSG_NXTHDR().

CMSG_ALIGN()،
    بإعطائها طولًا، تُرجعه شاملًا المحاذاة المطلوبة. هذا تعبير ثابت.

CMSG_SPACE()
    تُرجع عدد البايتات التي يشغلها عنصر مساعد بحمولة طول البيانات المُمررة. هذا تعبير ثابت.

CMSG_DATA()
    تُرجع مؤشرًا إلى جزء البيانات من cmsghdr. لا يمكن افتراض أن المؤشر المُعاد محاذاته بشكل مناسب للوصول إلى أنواع بيانات حمولة عشوائية. لا ينبغي للتطبيقات تحويله إلى نوع مؤشر يطابق الحمولة، بل يجب بدلاً من ذلك استخدام memcpy(3) لنسخ البيانات إلى أو من كائن مُصرّح به بشكل مناسب.

CMSG_LEN()
    تُرجع القيمة المراد تخزينها في عضو cmsg_len من بنية cmsghdr، مع مراعاة أي محاذاة ضرورية. تأخذ طول البيانات كوسيطة. هذا تعبير ثابت.

لإنشاء بيانات مساعدة، يُهيأ أولاً عضو msg_controllen من msghdr بطول مخزن رسالة التحكم. يُستخدم CMSG_FIRSTHDR() على msghdr للحصول على أول رسالة تحكم و CMSG_NXTHDR() للحصول على كل الرسائل اللاحقة. في كل رسالة تحكم، يُهيأ cmsg_len (باستخدام CMSG_LEN())، وحقول رأس cmsghdr الأخرى، وجزء البيانات باستخدام CMSG_DATA(). أخيراً، يُضبط حقل msg_controllen من msghdr ليكون مجموع CMSG_SPACE() لطول كل رسائل التحكم في المخزن. لمزيد من المعلومات حول msghdr، انظر recvmsg(2).

الإصدارات
للتوافقية، يجب الوصول إلى البيانات المساعدة باستخدام وحدات الماكرو الموصوفة هنا فقط.

في لينكس، CMSG_LEN() و CMSG_DATA() و CMSG_ALIGN() هي تعابير ثابتة (بافتراض أن وسيطها ثابت)، مما يعني أن هذه القيم يمكن استخدامها لتعريف حجم متغيرات عامة. لكن هذا قد لا يكون محمولاً.

المعايير

CMSG_FIRSTHDR()
CMSG_NXTHDR()
CMSG_DATA()
    POSIX.1-2008.

CMSG_SPACE()
CMSG_LEN()
CMSG_ALIGN()
    لينكس.

التاريخ
يتوافق نموذج البيانات المساعدة هذا مع مسودة POSIX.1g و 4.4BSD-Lite و API المتقدم لـ IPv6 الموصوف في RFC 2292 و SUSv2.

سيُدرج CMSG_SPACE() و CMSG_LEN() في الإصدار التالي من POSIX (العدد 8).

أمثلة
يبحث هذا الكود عن خيار IP_TTL في مخزن مساعد مستلم:

    struct msghdr msgh;
    struct cmsghdr *cmsg;
    int received_ttl;

    /* Receive auxiliary data in msgh */

    for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
            cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
        if (cmsg->cmsg_level == IPPROTO_IP
                && cmsg->cmsg_type == IP_TTL) {
            memcpy(&receive_ttl, CMSG_DATA(cmsg), sizeof(received_ttl));
            break;
        }
    }

    if (cmsg == NULL) {
        /* Error: IP_TTL not enabled or small buffer or I/O error */
    }

يمرر الكود أدناه مصفوفة من واصفات الملفات عبر مقبس نطاق UNIX باستخدام SCM_RIGHTS:

    struct msghdr msg = { 0 };
    struct cmsghdr *cmsg;
    int myfds[NUM_FD];  /* Contains the file descriptors to pass */
    char iobuf[1];
    struct iovec io = {
        .iov_base = iobuf,
        .iov_len = sizeof(iobuf)
    };
    union {         /* Ancillary data buffer, wrapped in a union
                       in order to ensure it is suitably aligned */
        char buf[CMSG_SPACE(sizeof(myfds))];
        struct cmsghdr align;
    } u;

    msg.msg_iov = &io;
    msg.msg_iovlen = 1;
    msg.msg_control = u.buf;
    msg.msg_controllen = sizeof(u.buf);
    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(myfds));
    memcpy(CMSG_DATA(cmsg), myfds, sizeof(myfds));

لمثال كود كامل يوضح تمرير واصفات الملفات عبر مقبس نطاق UNIX، انظر seccomp_unotify(2).

انظر أيضًا
recvmsg(2), sendmsg(2)

RFC 2292

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

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

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