- trixie-backports 4.31.0-1~bpo13+1
- testing 4.31.0-1
- unstable 4.31.0-1
| pidfd_open(2) | System Calls Manual | pidfd_open(2) |
الاسم¶
pidfd_open - الحصول على واصف ملف يشير إلى عملية
المكتبة¶
مكتبة سي المعيارية (libc، -lc)
موجز¶
#include <sys/syscall.h> /* تعريف ثوابت SYS_* */ #include <unistd.h>
int syscall(SYS_pidfd_open, pid_t pid, unsigned int flags);
ملاحظة: لا توفر glibc غلافًا لـ pidfd_open()، مما يستلزم استخدام syscall(2).
الوصف¶
استدعاء النظام pidfd_open() ينشئ واصف ملف يشير إلى العملية التي يتم تحديد PID الخاص بها في pid. يتم إرجاع واصف الملف كنتيجة للدالة؛ يتم تعيين علامة الإغلاق عند التنفيذ (close-on-exec) على واصف الملف.
وسيطة flags إما أن تكون قيمتها 0، أو تحتوي على العلم التالي:
- PIDFD_NONBLOCK (منذ لينكس 5.10)
- إرجاع واصف ملف غير محظور (nonblocking). إذا لم تكن العملية المشار إليها بواسطة واصف الملف قد انتهت بعد، فإن محاولة الانتظار على واصف الملف باستخدام waitid(2) ستعيد الخطأ EAGAIN فورًا بدلاً من الحظر.
قيمة الإرجاع¶
عند النجاح، تُعيد pidfd_open() واصف ملف (عدد صحيح غير سالب). عند الخطأ، تُعاد -1 ويتم تعيين errno للإشارة إلى الخطأ.
الأخطاء¶
- EINVAL
- flags غير صالح.
- EINVAL
- pid غير صالح.
- EMFILE
- وُصل إلى الحد الأقصى لعدد واصفات الملفات المفتوحة لكل عملية (انظر وصف RLIMIT_NOFILE في getrlimit(2)).
- ENFILE
- وُصل إلى الحد الأقصى لإجمالي عدد الملفات المفتوحة على مستوى النظام.
- ENODEV
- نظام ملفات العقدة المجهول غير متوفر في هذه النواة.
- ENOMEM
- ذاكرة النواة المتوفرة غير كافية.
- ESRCH
- العملية المحددة بواسطة pid غير موجودة.
المعايير¶
لينكس.
التاريخ¶
لينكس 5.3.
ملاحظات¶
يمكن استخدام تسلسل الكود التالي للحصول على واصف ملف لابن fork(2):
pid = fork();
if (pid > 0) { /* If parent */
pidfd = pidfd_open(pid, 0);
...
}
حتى إذا كان الابن قد انتهى بالفعل بحلول وقت استدعاء pidfd_open()، فلن يتم إعادة استخدام PID الخاص به وسيشير واصف الملف المُعاد إلى عملية الزومبي الناتجة. لاحظ، مع ذلك، أن هذا مضمون فقط إذا تحققت الشروط التالية:
- •
- لم يتم تعيين تصرف SIGCHLD صراحةً إلى SIG_IGN (انظر sigaction(2))؛
- •
- لم يتم تحديد العلم SA_NOCLDWAIT أثناء إنشاء معالج لـ SIGCHLD أو أثناء تعيين تصرف تلك الإشارة إلى SIG_DFL (انظر sigaction(2))؛ و
- •
- لم يتم حصاد عملية الزومبي في مكان آخر في البرنامج (على سبيل المثال، إما بواسطة معالج إشارة يُنفذ بشكل غير متزامن أو بواسطة wait(2) أو ما شابه ذلك في خيط آخر).
إذا لم يتحقق أي من هذه الشروط، فيجب بدلاً من ذلك إنشاء العملية الابن (مع واصف ملف PID يشير إليها) باستخدام clone(2) مع العلم CLONE_PIDFD.
حالات استخدام واصفات ملفات PID¶
يمكن استخدام واصف ملف PID المُعاد بواسطة pidfd_open() (أو بواسطة clone(2) مع العلم CLONE_PID) للأغراض التالية:
- •
- يمكن استخدام استدعاء النظام pidfd_send_signal(2) لإرسال إشارة إلى العملية المشار إليها بواسطة واصف ملف PID.
- •
- يمكن مراقبة واصف ملف PID باستخدام poll(2), select(2), و epoll(7). عندما تنتهي العملية التي يشير إليها، تشير هذه الواجهات إلى أن واصف الملف قابل للقراءة. لاحظ، مع ذلك، أنه في التنفيذ الحالي، لا يمكن قراءة أي شيء من واصف الملف (read(2) على واصف الملف يفشل مع الخطأ EINVAL).
- •
- إذا كان واصف ملف PID يشير إلى ابن لعملية الاستدعاء، فيمكن الانتظار عليه باستخدام waitid(2).
- •
- يمكن استخدام استدعاء النظام pidfd_getfd(2) للحصول على نسخة مكررة من واصف ملف لعملية أخرى يُشار إليها بواسطة واصف ملف PID.
- •
- يمكن استخدام واصف ملف PID كوسيطة لـ setns(2) للانتقال إلى واحد أو أكثر من نفس مساحات الأسماء (namespaces) مثل العملية المشار إليها بواسطة واصف الملف.
- •
- يمكن استخدام واصف ملف PID كوسيطة لـ process_madvise(2) لتقديم نصائح حول أنماط استخدام الذاكرة للعملية المشار إليها بواسطة واصف الملف.
استدعاء النظام pidfd_open() هو الطريقة المفضلة للحصول على واصف ملف PID لعملية موجودة بالفعل. البديل هو الحصول على واصف ملف بفتح دليل /proc/pid. ومع ذلك، فإن التقنية الأخيرة ممكنة فقط إذا كان نظام الملفات proc(5) مركبًا (mounted)؛ علاوة على ذلك، واصف الملف الذي يتم الحصول عليه بهذه الطريقة ليس قابلًا للاستقصاء (pollable) ولا يمكن الانتظار عليه باستخدام waitid(2).
أمثلة¶
البرنامج أدناه يفتح واصف ملف PID للعملية التي يتم تحديد PID الخاص بها كوسيطة سطر أوامر. ثم يستخدم poll(2) لمراقبة واصف الملف لخروج العملية، كما هو موضح بواسطة حدث EPOLLIN.
مصدر البرنامج¶
#define _GNU_SOURCE
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
static int
pidfd_open(pid_t pid, unsigned int flags)
{
return syscall(SYS_pidfd_open, pid, flags);
}
int
main(int argc, char *argv[])
{
int pidfd, ready;
struct pollfd pollfd;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
exit(EXIT_SUCCESS);
}
pidfd = pidfd_open(atoi(argv[1]), 0);
if (pidfd == -1) {
perror("pidfd_open");
exit(EXIT_FAILURE);
}
pollfd.fd = pidfd;
pollfd.events = POLLIN;
ready = poll(&pollfd, 1, -1);
if (ready == -1) {
perror("poll");
exit(EXIT_FAILURE);
}
printf("Events (%#x): POLLIN is %sset\n", pollfd.revents,
(pollfd.revents & POLLIN) ? "" : "not ");
close(pidfd);
exit(EXIT_SUCCESS);
}
انظر أيضًا¶
clone(2), kill(2), pidfd_getfd(2), pidfd_send_signal(2), poll(2), process_madvise(2), select(2), setns(2), waitid(2), epoll(7)
ترجمة¶
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>
هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.
إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.
| 15 يونيو 2024 | صفحات دليل لينكس 6.9.1 |