getgroups(2)

الاسم
getgroups, setgroups - الحصول/تعيين قائمة معرفات المجموعات التكميلية

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

موجز
#include <unistd.h>

int getgroups(int size, gid_t list[_Nullable size]);

#include <grp.h>

int setgroups(size_t size, const gid_t list[size]);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

setgroups():
    منذ glibc 2.19:
        _DEFAULT_SOURCE
    glibc 2.19 وما قبله:
        _BSD_SOURCE

الوصف
ترجع getgroups() معرفات المجموعات التكميلية للعملية المستدعية في list. يجب تعيين الوسيط size إلى أقصى عدد من العناصر التي يمكن تخزينها في المخزن المؤقت المشار إليه بواسطة list. إذا كانت العملية المستدعية عضوًا في أكثر من size مجموعة تكميلية، ينتج خطأ.

من غير المحدد ما إذا كان معرف المجموعة الفعّال للعملية المستدعية مضمنًا في القائمة المرجعة. (وبالتالي، يجب على التطبيق أيضًا استدعاء getegid(2) وإضافة أو إزالة القيمة الناتجة.)

إذا كان size صفرًا، لا يتم تعديل list، ولكن يتم إرجاع العدد الإجمالي لمعرفات المجموعات التكميلية للعملية. يسمح هذا للمستدعي بتحديد حجم list المخصص ديناميكيًا لاستخدامه في استدعاء لاحق لـ getgroups().

تضبط setgroups() معرفات المجموعات التكميلية للعملية المستدعية. الامتيازات المناسبة مطلوبة (انظر وصف خطأ EPERM أدناه). تحدد الوسيطة size عدد معرفات المجموعات التكميلية في المخزن المؤقت المشار إليه بواسطة list. يمكن لعملية إسقاط جميع مجموعاتها التكميلية بالاستدعاء:

    setgroups(0, (gid_t [0]){});

قيمة الإرجاع
عند النجاح، ترجع getgroups() عدد معرفات المجموعات التكميلية. عند الخطأ، يتم إرجاع -1، ويتم تعيين errno للإشارة إلى الخطأ.

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

الأخطاء

EFAULT
    list له عنوان غير صالح.

يمكن أن تفشل getgroups() بالإضافة إلى ذلك مع الخطأ التالي:

EINVAL
    size أقل من عدد معرفات المجموعات التكميلية، ولكنه ليس صفرًا.

يمكن أن تفشل setgroups() بالإضافة إلى ذلك مع الأخطاء التالية:

EINVAL
    size أكبر من NGROUPS_MAX (32 قبل Linux 2.6.4؛ 65536 منذ Linux 2.6.4).

ENOMEM
    نفدت الذاكرة.

EPERM
    العملية المستدعية لديها امتياز غير كافٍ (المستدعي لا يملك القدرة CAP_SETGID في مساحة اسم المستخدم التي يقيم فيها).

EPERM (منذ Linux 3.19)
    استخدام setgroups() ممنوع في مساحة اسم المستخدم هذه. انظر وصف /proc/pid/setgroups في user_namespaces(7).

الإصدارات

  الاختلافات بين مكتبة C والنواة
على مستوى النواة، معرفات المستخدمين والمجموعات هي سمة لكل خيط. ومع ذلك، تتطلب POSIX أن تشترك جميع الخيوط في العملية في نفس بيانات الاعتماد. يعالج تطبيق الخيوط NPTL متطلبات POSIX من خلال توفير دوال غلاف لاستدعاءات النظام المختلفة التي تغير UIDs و GIDs للعملية. تستخدم دوال الغلاف هذه (بما في ذلك دالة setgroups()) تقنية قائمة على الإشارات لضمان أنه عندما يغير خيط بيانات اعتماده، فإن جميع الخيوط الأخرى في العملية تغير أيضًا بيانات اعتمادها. للتفاصيل، انظر nptl(7).

المعايير

getgroups()
    POSIX.1-2024.

setgroups()
    لا شيء.

التاريخ

getgroups()
    4.3BSD، SVr4، POSIX.1-1988.

setgroups()
    SVr4, 4.3BSD. نظرًا لأن setgroups() يتطلب امتيازًا، فهو غير مشمول بـ POSIX.1.

استدعاء النظام الأصلي Linux getgroups() دعم فقط معرفات مجموعات 16 بت. لاحقًا، أضاف Linux 2.4 getgroups32()، الذي يدعم معرفات 32 بت. تتعامل دالة الغلاف glibc getgroups() بشفافية مع الاختلاف عبر إصدارات النواة.

ملاحظات
يمكن أن تحتوي العملية على ما يصل إلى NGROUPS_MAX معرف مجموعة تكميلي بالإضافة إلى معرف المجموعة الفعّال. الثابت NGROUPS_MAX معرف في <limits.h>. مجموعة معرفات المجموعات التكميلية موروثة من العملية الأم، ومحفوظة عبر execve(2).

يمكن العثور على أقصى عدد لمعرفات المجموعات التكميلية في وقت التشغيل باستخدام sysconf(3):

    long ngroups_max;
    ngroups_max = sysconf(_SC_NGROUPS_MAX);

لا يمكن أن تكون القيمة القصوى المرجعة لـ getgroups() أكبر من واحد زائد هذه القيمة. منذ Linux 2.6.4، يتم أيضًا كشف أقصى عدد لمعرفات المجموعات التكميلية عبر الملف المخصص للقراءة فقط الخاص بـ Linux، /proc/sys/kernel/ngroups_max.

أمثلة
    #include <err.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>

    #define MALLOC(n, T)  ((T *) reallocarray(NULL, n, sizeof(T)))

    static gid_t *agetgroups(size_t *ngids);

    int
    main(void)
    {
        gid_t   *gids;
        size_t  n;

        gids = agetgroups(&n);
        if (gids == NULL)
            err(EXIT_FAILURE, "agetgroups");

        if (n != 0) {
            printf("%jd", (intmax_t) gids[0]);
            for (size_t i = 1; i < n; i++)
                printf(" %jd", (intmax_t) gids[i]);
        }
        puts("");

        free(gids);
        exit(EXIT_SUCCESS);
    }

    static gid_t *
    agetgroups(size_t *ngids)
    {
        int    n;
        gid_t  *gids;

        n = getgroups(0, NULL);
        if (n == -1)
            return NULL;

        gids = MALLOC(n, gid_t);
        if (gids == NULL)
            return NULL;

        n = getgroups(n, gids);
        if (n == -1) {
            free(gids);
            return NULL;
        }

        *ngids = n;
        return gids;
    }

انظر أيضًا
getgid(2), setgid(2), getgrouplist(3), group_member(3), initgroups(3), capabilities(7), credentials(7)

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

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

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