process_vm_readv(2)

الاسم
process_vm_readv, process_vm_writev - نقل البيانات بين مساحات عناوين العمليات

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

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

ssize_t process_vm_readv(pid_t pid,
                       const struct iovec *local_iov,
                       unsigned long liovcnt,
                       const struct iovec *remote_iov,
                       unsigned long riovcnt,
                       unsigned long flags);
ssize_t process_vm_writev(pid_t pid,
                       const struct iovec *local_iov,
                       unsigned long liovcnt,
                       const struct iovec *remote_iov,
                       unsigned long riovcnt,
                       unsigned long flags);

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

process_vm_readv(), process_vm_writev():
    _GNU_SOURCE

الوصف
تنقل استدعاءات النظام هذه البيانات بين مساحة عنوان العملية المستدعية ("العملية المحلية") والعملية المحددة بواسطة pid ("العملية البعيدة"). تتحرك البيانات مباشرة بين مساحتي عنوان العمليتين، دون المرور عبر مساحة النواة.

ينقل استدعاء النظام process_vm_readv() البيانات من العملية البعيدة إلى العملية المحلية. تُحدد البيانات المراد نقلها بواسطة remote_iov و riovcnt: remote_iov مؤشر لمصفوفة تصف نطاقات العناوين في العملية pid، ويحدد riovcnt عدد العناصر في remote_iov. تُنقل البيانات إلى المواقع المحددة بواسطة local_iov و liovcnt: local_iov مؤشر لمصفوفة تصف نطاقات العناوين في العملية المستدعية، ويحدد liovcnt عدد العناصر في local_iov.

استدعاء النظام process_vm_writev() هو عكس process_vm_readv()—ينقل البيانات من العملية المحلية إلى العملية البعيدة. بصرف النظر عن اتجاه النقل، فإن الوسائط liovcnt و local_iov و riovcnt و remote_iov لها نفس المعنى كما في process_vm_readv().

تشير الوسيطتان local_iov و remote_iov إلى مصفوفة من بنى iovec، الموصوفة في iovec(3type).

تُعالج المخازن المؤقتة بترتيب المصفوفة. يعني هذا أن process_vm_readv() يملأ local_iov[0] بالكامل قبل الانتقال إلى local_iov[1]، وهكذا. وبالمثل، يُقرأ remote_iov[0] بالكامل قبل الانتقال إلى remote_iov[1]، وهكذا.

وبالمثل، يكتب process_vm_writev() المحتوى الكامل لـ local_iov[0] قبل الانتقال إلى local_iov[1]، ويملأ remote_iov[0] بالكامل قبل الانتقال إلى remote_iov[1].

لا يجب أن تكون أطوال remote_iov[i].iov_len و local_iov[i].iov_len متساوية. وبالتالي، من الممكن تقسيم مخزن محلي واحد إلى مخازن بعيدة متعددة، أو العكس.

الوسيطة flags غير مستخدمة حالياً ويجب ضبطها على 0.

يجب أن تكون القيم المحددة في الوسيطتين liovcnt و riovcnt أقل من أو تساوي IOV_MAX (المعرفة في <limits.h> أو القابلة للوصول عبر الاستدعاء sysconf(_SC_IOV_MAX)).

تُفحص وسيطات العد و local_iov قبل إجراء أي عمليات نقل. إذا كانت الأعداد كبيرة جداً، أو كان local_iov غير صالح، أو كانت العناوين تشير إلى مناطق لا يمكن للعملية المحلية الوصول إليها، فلن تُعالج أي من المتجهات وسيُعاد خطأ فوراً.

لاحظ، مع ذلك، أن استدعاءات النظام هذه لا تفحص مناطق الذاكرة في العملية البعيدة إلا قبل القيام بالقراءة/الكتابة مباشرة. وبالتالي، قد ينتج قراءة/كتابة جزئية (انظر قيمة الإرجاع) إذا كان أحد عناصر remote_iov يشير إلى منطقة ذاكرة غير صالحة في العملية البعيدة. لن تُجرى محاولات قراءة/كتابة إضافية بعد تلك النقطة. ضع هذا في الاعتبار عند محاولة قراءة بيانات ذات طول غير معروف (مثل سلاسل C المنتهية بقيمة فارغة) من عملية بعيدة، بتجنب امتداد صفحات الذاكرة (عادةً 4 KiB) في عنصر iovec بعيد واحد. (بدلاً من ذلك، قسم القراءة البعيدة إلى عنصري remote_iov واجعلها تندمج مرة أخرى في إدخال local_iov واحد للكتابة. يصل إدخال القراءة الأول إلى حد الصفحة، بينما يبدأ الثاني على حد الصفحة التالي.)

يُحكم الإذن بالقراءة من أو الكتابة إلى عملية أخرى بواسطة فحص وضع الوصول ptrace PTRACE_MODE_ATTACH_REALCREDS؛ انظر ptrace(2).

قيمة الإرجاع
عند النجاح، يُرجع process_vm_readv() عدد البايتات المقروءة ويُرجع process_vm_writev() عدد البايتات المكتوبة. قد تكون قيمة الإرجاع هذه أقل من إجمالي عدد البايتات المطلوبة، إذا حدثت قراءة/كتابة جزئية. (تنطبق عمليات النقل الجزئية على دقة عناصر iovec. لن تؤدي استدعاءات النظام هذه عملية نقل جزئية تقسم عنصر iovec واحد.) يجب على المستدعي التحقق من قيمة الإرجاع لتحديد ما إذا حدثت قراءة/كتابة جزئية.

عند حدوث خطأ، يُرجع -1 ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EFAULT
    الذاكرة الموصوفة بواسطة local_iov خارج مساحة العنوان القابلة للوصول للمستدعي.

EFAULT
    الذاكرة الموصوفة بواسطة remote_iov خارج مساحة العنوان القابلة للوصول للعملية pid.

EINVAL
    مجموع قيم iov_len إما لـ local_iov أو remote_iov يفيض قيمة ssize_t.

EINVAL
    flags ليست 0.

EINVAL
    liovcnt أو riovcnt كبير جداً.

ENOMEM
    تعذر تخصيص ذاكرة للنسخ الداخلية لهياكل iovec.

EPERM
    ليس لدى المستدعي الإذن للوصول إلى مساحة عنوان العملية pid.

ESRCH
    لا توجد عملية بالمعرف pid.

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

التاريخ
لينكس 3.2، glibc 2.15.

ملاحظات
عمليات نقل البيانات التي ينفذها process_vm_readv() و process_vm_writev() ليست مضمونة لتكون ذرية بأي شكل.

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

أمثلة
يوضح نموذج الكود التالي استخدام process_vm_readv(). يقرأ 20 بايت عند العنوان 0x10000 من العملية ذات PID 10 ويكتب أول 10 بايتات في buf1 والـ 10 بايتات الثانية في buf2.

    #define _GNU_SOURCE
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/uio.h>

    int
    main(void)
    {
        char          buf1[10];
        char          buf2[10];
        pid_t         pid = 10;    /* PID of remote process */
        ssize_t       nread;
        struct iovec  local[2];
        struct iovec  remote[1];

        local[0].iov_base = buf1;
        local[0].iov_len = 10;
        local[1].iov_base = buf2;
        local[1].iov_len = 10;
        remote[0].iov_base = (void *) 0x10000;
        remote[0].iov_len = 20;

        nread = process_vm_readv(pid, local, 2, remote, 1, 0);
        if (nread != 20)
            exit(EXIT_FAILURE);

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
readv(2), writev(2)

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

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

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