ftw(3)

الاسم
ftw, nftw - التجوال في شجرة الملفات

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

موجز
#include <ftw.h>

int nftw(const char *dirpath,
        typeof(int (const char *fpath, const struct stat *sb,
                    int typeflag, struct FTW *ftwbuf))
            *fn,
        int nopenfd, int flags);

[[deprecated]]
int ftw(const char *dirpath,
        typeof(int (const char *fpath, const struct stat *sb,
                    int typeflag))
            *fn,
        int nopenfd);

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

nftw():
    _XOPEN_SOURCE >= 500

الوصف
nftw() يتجول في شجرة الدليل الموجودة تحت الدليل dirpath، ويستدعي fn() مرة واحدة لكل مدخل في الشجرة. مبدئيًا، تُعالج الدلائل قبل الملفات والدلائل الفرعية التي تحتويها (اجتياز بالترتيب المسبق).

لتجنب استهلاك كل واصفات الملفات لعملية الاستدعاء، يُحدد nopenfd الحد الأقصى لعدد الدلائل التي سيبقيها nftw() مفتوحة في وقت واحد. عندما يتجاوز عمق البحث هذا، يصبح nftw() أبطأ لأنه يجب إغلاق الدلائل وإعادة فتحها. يستخدم nftw() واصف ملف واحد على الأكثر لكل مستوى في شجرة الدليل.

لكل مدخل يُوجد في الشجرة، يستدعي nftw() fn() بأربع وسائط: fpath و sb و typeflag و ftwbuf. fpath هو اسم مسار المدخل، ويُعبر عنه إما كاسم مسار نسبي لدليل العمل الحالي لعملية الاستدعاء وقت استدعاء nftw()، إذا عُبر عن dirpath كاسم مسار نسبي، أو كاسم مسار مطلق، إذا عُبر عن dirpath كاسم مسار مطلق. sb هو مؤشر لبنية stat التي أرجعها استدعاء stat(2) لـ fpath.

الوسيطة typeflag الممررة إلى fn() هي عدد صحيح له إحدى القيم التالية:

FTW_F
    fpath هو ملف عادي.

FTW_D
    fpath هو دليل.

FTW_DNR
    fpath هو دليل لا يمكن قراءته.

FTW_DP
    fpath هو دليل، وحدد FTW_DEPTH في flags. (إذا لم يُحدد FTW_DEPTH في flags، فستُزار الدلائل دائمًا مع تعيين typeflag إلى FTW_D.) عُولجت جميع الملفات والدلائل الفرعية داخل fpath.

FTW_NS
    فشل استدعاء stat(2) على fpath، وهو ليس رابطًا رمزيًا. السبب المحتمل لذلك هو أن المستدعي كان لديه إذن قراءة على الدليل الأب، بحيث يمكن رؤية اسم الملف fpath، ولكن لم يكن لديه إذن تنفيذ، بحيث لا يمكن الوصول إلى الملف لـ stat(2). محتويات المخزن المؤقت المشار إليه بواسطة sb غير محددة.

FTW_SL
    fpath هو رابط رمزي، ووُضع FTW_PHYS في flags.

FTW_SLN
    fpath هو رابط رمزي يشير إلى ملف غير موجود. (يحدث هذا فقط إذا لم يُضبط FTW_PHYS.) في هذه الحالة، تحتوي الوسيطة sb الممررة إلى fn() على معلومات أُعيدت بتنفيذ lstat(2) على الرابط الرمزي "المتدلي". (لكن انظر BUGS.)

الوسيطة الرابعة (ftwbuf) التي يوفرها nftw() عند استدعاء fn() هي مؤشر لبنية من النوع FTW:

    struct FTW {
        int base;
        int level;
    };

base هو إزاحة اسم الملف (أي مكون الاسم الأساسي) في اسم المسار المعطى في fpath. level هو عمق fpath في شجرة الدليل، نسبة إلى جذر الشجرة (dirpath، الذي له عمق 0).

لإيقاف التجوال في الشجرة، تُرجع fn() قيمة غير صفرية؛ ستصبح هذه القيمة القيمة المُعادة من nftw(). طالما تُرجع fn() 0، سيستمر nftw() إما حتى يجتاز الشجرة بأكملها، وفي هذه الحالة سيعيد صفرًا، أو حتى يواجه خطأ (مثل فشل malloc(3))، وفي هذه الحالة سيعيد -1.

لأن nftw() يستخدم بنى بيانات ديناميكية، الطريقة الآمنة الوحيدة للخروج من تجوال الشجرة هي إعادة قيمة غير صفرية من fn(). للسماح لإشارة بإنهاء التجوال دون التسبب بتسرب ذاكرة، اجعل المعالج يضبط علمًا عامًا يُفحص بواسطة fn(). لا تستخدم longjmp(3) ما لم يكن البرنامج على وشك الإنهاء.

تُشكل الوسيطة flags الخاصة بـ nftw() بعملية OR على صفر أو أكثر من الأعلام التالية:

FTW_ACTIONRETVAL (منذ glibc 2.3.3)
    إذا ضُبط هذا العلم الخاص بـ glibc، فإن nftw() يعالج القيمة المُعادة من fn() بشكل مختلف. يجب أن تُرجع fn() إحدى القيم التالية:

    FTW_CONTINUE
        يأمر nftw() بالاستمرار بشكل طبيعي.

    FTW_SKIP_SIBLINGS
        إذا أعادت fn() هذه القيمة، فسيُتجاوز عن أشقاء المدخل الحالي، ويستمر المعالجة في الدليل الأب.

    FTW_SKIP_SUBTREE
        إذا استُدعيت fn() بمدخل هو دليل (typeflag هو FTW_D)، ستمنع قيمة الإرجاع هذه تمرير الكائنات داخل ذلك الدليل كوسيطات إلى fn(). يستمر nftw() في المعالجة مع الشقيق التالي للدليل.

    FTW_STOP
        يسبب إرجاع nftw() فورًا بقيمة الإرجاع FTW_STOP.

    قد تُربط قيم إرجاع أخرى بإجراءات جديدة في المستقبل؛ يجب ألا تُرجع fn() قيمًا غير تلك المذكورة أعلاه.

    يجب تعريف كلية اختبار الميزة _GNU_SOURCE (قبل تضمين أي ملفات رأس) للحصول على تعريف FTW_ACTIONRETVAL من <ftw.h>.

FTW_CHDIR
    إذا ضُبط، يُنفذ chdir(2) إلى كل دليل قبل معالجة محتوياته. هذا مفيد إذا احتاج البرنامج لأداء إجراء في الدليل الذي يوجد فيه fpath. (تحديد هذه العلامة لا يؤثر على اسم المسار المُمرر في وسيط fpath للدالة fn.)

FTW_DEPTH
    إذا ضُبط، يُنفذ اجتياز بعدي، أي تُستدعى fn() للدليل نفسه بعد معالجة محتويات الدليل وأدلته الفرعية. (مبدئيًا، يُعالج كل دليل قبل محتوياته.)

FTW_MOUNT
    إذا ضُبط، يبقى داخل نفس نظام الملفات (أي لا يعبر نقاط الوصل).

FTW_PHYS
    إذا ضُبط، لا يتبع الروابط الرمزية. (هذا ما تريده.) إذا لم يُضبط، تُتبع الروابط الرمزية، لكن لا يُبلغ عن أي ملف مرتين.

    إذا لم يُضبط FTW_PHYS، لكن ضُبط FTW_DEPTH، فلا تُستدعى الدالة fn() أبدًا لدليل سيكون سليلًا لنفسه.

  ftw()
ftw() دالة أقدم تقدم مجموعة فرعية من وظائف nftw(). الاختلافات البارزة كما يلي:

•   ftw() ليس لها وسيط flags. تتصرف بنفس الطريقة عندما تُستدعى nftw() مع تحديد flags كصفر.

•   دالة الاستدعاء، fn()، لا تُزود بوسيط رابع.

•   نطاق القيم المُمررة عبر وسيط typeflag المُزود لـ fn() أصغر: فقط FTW_F، FTW_D، FTW_DNR، FTW_NS، و (ربما) FTW_SL.

قيمة الإرجاع
ترجع هذه الدوال 0 عند النجاح، و -1 إذا حدث خطأ.

إذا أرجع fn() قيمة غير صفرية، يُنهى اجتياز الشجرة وتُرجع القيمة التي أرجعها fn() كنتيجة لـ ftw() أو nftw().

إذا استُدعيت nftw() مع علامة FTW_ACTIONRETVAL، فإن القيمة غير الصفرية الوحيدة التي يجب أن تستخدمها fn() لإنهاء اجتياز الشجرة هي FTW_STOP، وتُرجع تلك القيمة كنتيجة لـ nftw().

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
nftw() | سلامة الخيوط | MT-Safe cwd
ftw() | سلامة الخيوط | MT-Safe

الإصدارات
في بعض التطبيقات (مثل glibc)، لن تستخدم ftw() أبدًا FTW_SL؛ في أنظمة أخرى، يحدث FTW_SL فقط للروابط الرمزية التي لا تشير إلى ملف موجود؛ وفي أنظمة أخرى، ستستخدم ftw() FTW_SL لكل رابط رمزي. إذا كان fpath رابطًا رمزيًا وفشل stat(2)، ينص POSIX.1-2008 على أنه غير محدد ما إذا كان FTW_NS أو FTW_SL يُمرر في typeflag. للحصول على نتائج قابلة للتنبؤ، استخدم nftw().

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

التاريخ

ftw()
    POSIX.1-2001, SVr4, SUSv1. يُصنف POSIX.1-2008 هذه الدالة على أنها مهملة.

nftw()
    glibc 2.1. POSIX.1-2001, SUSv1.

FTW_SL
    POSIX.1-2001, SUSv1.

ملاحظات
يلاحظ POSIX.1-2008 أن النتائج غير محددة إذا لم يحافظ fn على دليل العمل الحالي.

العلل
وفقًا لـ POSIX.1-2008، عندما يحتوي معامل typeflag الممرر إلى fn() على FTW_SLN، يجب أن تحتوي الخبيئة المشار إليها بواسطة sb على معلومات حول الرابط الرمزي المعلق (التي حُصل عليها باستدعاء lstat(2) على الرابط). اتبعت إصدارات glibc المبكرة مواصفات POSIX بشكل صحيح في هذه النقطة. ومع ذلك، نتيجة لانحدار أُدخل في glibc 2.4، كانت محتويات الخبيئة المشار إليها بواسطة sb غير محددة عندما يُمرر FTW_SLN في typeflag. (بشكل أكثر دقة، تُركت محتويات الخبيئة دون تغيير في هذه الحالة.) أُصلح هذا الانحدار في النهاية في glibc 2.30، بحيث يتبع تطبيق glibc (مرة أخرى) مواصفات POSIX.

أمثلة
يجتاز البرنامج التالي شجرة الدليل تحت المسار المسمى في وسيط سطر الأوامر الأول، أو تحت الدليل الحالي إذا لم يُقدم وسيط. يعرض معلومات متنوعة عن كل ملف. يمكن استخدام وسيط سطر الأوامر الثاني لتحديد محارف تتحكم في القيمة المسندة إلى وسيط flags عند استدعاء nftw().

  مصدر البرنامج
    #define _XOPEN_SOURCE 500
    #include <ftw.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    static int
    display_info(const char *fpath, const struct stat *sb,
                 int tflag, struct FTW *ftwbuf)
    {
        printf("%-3s %2d ",
               (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
               (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
               (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
               (tflag == FTW_SLN) ? "sln" : "???",
               ftwbuf->level);

        if (tflag == FTW_NS)
            printf("-------");
        else
            printf("%7jd", (intmax_t) sb->st_size);

        printf("   %-40s %d %s\n",
               fpath, ftwbuf->base, fpath + ftwbuf->base);

        return 0;           /* لإخبار nftw() بالاستمرار */
    }

    int
    main(int argc, char *argv[])
    {
        int flags = 0;

        if (argc > 2 && strchr(argv[2], 'd') != NULL)
            flags |= FTW_DEPTH;
        if (argc > 2 && strchr(argv[2], 'p') != NULL)
            flags |= FTW_PHYS;

        if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
            == -1)
        {
            perror("nftw");
            exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
stat(2), fts(3), readdir(3)

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

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

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