readlink(2)

الاسم
readlink, readlinkat - قراءة قيمة رابط رمزي

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

موجز
#include <unistd.h>

ssize_t readlink(size_t bufsiz;
                 const char *restrict path,
                 char buf[restrict bufsiz], size_t bufsiz);

#include <fcntl.h>            /* تعريف ثوابت AT_* */
#include <unistd.h>

ssize_t readlinkat(size_t bufsiz;
                 int dirfd, const char *restrict path,
                 char buf[restrict bufsiz], size_t bufsiz);

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

readlink():
    _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
        || /* glibc <= 2.19: */ _BSD_SOURCE

readlinkat():
    منذ glibc 2.10:
        _POSIX_C_SOURCE >= 200809L
    قبل glibc 2.10:
        _ATFILE_SOURCE

الوصف
تضع readlink() محتويات الرابط الرمزي path في المخزن المؤقت buf، الذي حجمه bufsiz. لا تُلحق readlink() بايت فارغ ختامي بـ buf. ستقطع (بصمت) المحتويات (إلى طول bufsiz حرفًا)، إذا كان المخزن المؤقت صغيرًا جدًا لاستيعاب كل المحتويات.

  readlinkat()
تعمل استدعاء النظام readlinkat() بنفس طريقة readlink() تمامًا، باستثناء الاختلافات الموصوفة هنا.

إذا كان path نسبيًا، فيُفسر بالنسبة للدليل المشار إليه بواصف الملف dirfd (بدلاً من دليل العمل الحالي للعملية المستدعية، كما تفعل readlink() لاسم مسار نسبي).

إذا كان path نسبيًا و dirfd هو القيمة الخاصة AT_FDCWD، فيُفسر path بالنسبة لدليل العمل الحالي للعملية المستدعية (مثل readlink()).

إذا كان المسار path مطلقاً، فُيتجاهل dirfd.

منذ Linux 2.6.39، يمكن أن يكون path سلسلة فارغة، وفي هذه الحالة يعمل الاستدعاء على الرابط الرمزي المشار إليه بـ dirfd (والذي يجب الحصول عليه باستخدام open(2) مع العلمين O_PATH و O_NOFOLLOW).

انظر openat(2) لشرح الحاجة إلى readlinkat().

قيمة الإرجاع
عند النجاح، تُرجع هذه الاستدعاءات عدد البايتات الموضوعة في buf. (إذا كانت القيمة المُرجعة تساوي bufsiz، فقد حدث اقتطاع.) عند الخطأ، يُرجع -1 ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EACCES
    تم رفض إذن البحث لمكون من بادئة المسار. (انظر أيضًا path_resolution(7).)

EBADF
    (readlinkat()) path نسبي لكن dirfd ليس AT_FDCWD ولا واصف ملف صالح.

EFAULT
    يمتد buf خارج مساحة العنوان المخصصة للعملية.

EINVAL
    bufsiz ليس موجبًا.

EINVAL
    الملف المُسمى (أي مكون اسم الملف النهائي لـ path) ليس رابطًا رمزيًا.

EIO حدث خطأ إدخال/إخراج أثناء القراءة من نظام الملفات.

ELOOP
    صودفت روابط رمزية كثيرة جدًا عند ترجمة اسم المسار.

ENAMETOOLONG
    اسم مسار، أو مكون من اسم مسار، طويل جدًا.

ENOENT
    الملف المسمى غير موجود.

ENOMEM
    ذاكرة النواة المتوفرة غير كافية.

ENOTDIR
    أحد مكونات بادئة المسار ليس دليلاً.

ENOTDIR
    (readlinkat()) path نسبي و dirfd هو واصف ملف يشير إلى ملف غير دليل.

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

التاريخ

readlink()
    4.4BSD (ظهر لأول مرة في 4.2BSD)، POSIX.1-2001، POSIX.1-2008.

readlinkat()
    POSIX.1-2008. لينكس 2.6.16،‏ glibc 2.4.

حتى glibc 2.4 وما تضمنته، كان نوع الإرجاع لـ readlink() مُصرحًا به كـ int. حاليًا، يُصرح بنوع الإرجاع كـ ssize_t، كما هو مطلوب (حديثًا) في POSIX.1-2001.

  glibc
على النوى الأقدم حيث readlinkat() غير متوفرة، ترجع دالة الغلاف glibc إلى استخدام readlink(). عندما يكون path نسبيًا، تبني glibc اسم مسار بناءً على الرابط الرمزي في /proc/self/fd الذي يتوافق مع وسيطة dirfd.

ملاحظات
قد لا يوفر استخدام مخزن مؤقت بحجم ثابت مساحة كافية لمحتويات الرابط الرمزي. يمكن الحصول على الحجم المطلوب للمخزن المؤقت من قيمة stat.st_size المُرجعة باستدعاء lstat(2) على الرابط. ومع ذلك، يجب التحقق من عدد البايتات التي كتبتها readlink() و readlinkat() للتأكد من أن حجم الرابط الرمزي لم يزد بين الاستدعاءات. يعالج التخصيص الديناميكي للمخزن المؤقت لـ readlink() و readlinkat() أيضًا مشكلة قابلية النقل الشائعة عند استخدام PATH_MAX لحجم المخزن المؤقت، حيث أن هذا الثابت غير مضمون التعريف وفقًا لـ POSIX إذا لم يكن لدى النظام مثل هذا الحد.

أمثلة
يخصص البرنامج التالي المخزن المؤقت المطلوب بواسطة readlink() ديناميكيًا من المعلومات المقدمة بواسطة lstat(2)، مع الرجوع إلى مخزن مؤقت بحجم PATH_MAX في الحالات التي يُبلغ فيها lstat(2) عن حجم صفري.

    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>

    int
    main(int argc, char *argv[])
    {
        char         *buf;
        ssize_t      nbytes, bufsiz;
        struct stat  sb;

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

        if (lstat(argv[1], &sb) == -1) {
            perror("lstat");
            exit(EXIT_FAILURE);
        }

        /* Add one to the link size, so that we can determine whether
           the buffer returned by readlink() was truncated.  */

        bufsiz = sb.st_size + 1;

        /* Some magic symlinks under (for example) /proc and /sys
           report 'st_size' as zero.  In that case, take PATH_MAX as
           a "good enough" estimate.  */

        if (sb.st_size == 0)
            bufsiz = PATH_MAX;

        buf = malloc(bufsiz);
        if (buf == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }

        nbytes = readlink(argv[1], buf, bufsiz);
        if (nbytes == -1) {
            perror("readlink");
            exit(EXIT_FAILURE);
        }

        /* Print only 'nbytes' of 'buf', as it doesn't contain a terminating
           null byte ('\0').  */
        printf("'%s' points to '%.*s'\n", argv[1], (int) nbytes, buf);

        /* If the return value was equal to the buffer size, then
           the link target was larger than expected (perhaps because the
           target was changed between the call to lstat() and the call to
           readlink()).  Warn the user that the returned target may have
           been truncated.  */

        if (nbytes == bufsiz)
            printf("(Returned buffer may have been truncated)\n");

        free(buf);
        exit(EXIT_SUCCESS);
    }

انظر أيضًا
readlink(1), lstat(2), stat(2), symlink(2), realpath(3), path_resolution(7), symlink(7)

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

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

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