signal(2)

الاسم
signal - معالجة الإشارات وفق معيار ANSI C

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

موجز
#include <signal.h>

typedef typeof(void (int))  *sighandler_t;

sighandler_t signal(int signum, sighandler_t handler);

الوصف
تحذير: يختلف سلوك signal() عبر إصدارات UNIX، كما اختلف تاريخيًا عبر إصدارات Linux المختلفة. تجنب استخدامها: استخدم sigaction(2) بدلاً من ذلك. انظر قابلية النقل أدناه.

تضبط signal() تصرف الإشارة signum إلى handler، والذي يكون إما SIG_IGN أو SIG_DFL أو عنوان دالة يحددها المبرمج (معالج إشارة).

إذا تم تسليم الإشارة signum إلى العملية، فيحدث أحد الأمور التالية:

*   إذا ضُبط التصرف على SIG_IGN، فتُتجاهل الإشارة.

*   إذا ضُبط التصرف على SIG_DFL، فيحدث الإجراء المبدئي المرتبط بالإشارة (انظر signal(7)).

*   إذا ضُبط التصرف على دالة، فإما يُعاد ضبط التصرف أولاً إلى SIG_DFL أو تُحجب الإشارة (انظر قابلية النقل أدناه)، ثم تُستدعى handler مع الوسيط signum. إذا تسبب استدعاء المعالج في حجب الإشارة، فتُرفع الحجب عن الإشارة عند العودة من المعالج.

لا يمكن التقاط الإشارتين SIGKILL و SIGSTOP أو تجاهلهما.

قيمة الإرجاع
تُرجع signal() القيمة السابقة لمعالج الإشارة. عند الفشل، تُرجع SIG_ERR، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EINVAL
    signum غير صالح.

الإصدارات
استخدام sighandler_t هو امتداد GNU، يُكشف عنه إذا عُرّف _GNU_SOURCE؛ كما تعرّف glibc (المشتق من BSD) sig_t إذا عُرّف _BSD_SOURCE (glibc 2.19 والإصدارات الأقدم) أو _DEFAULT_SOURCE (glibc 2.19 والإصدارات الأحدث). التعريف المعياري لـ signal() هو:

    typeof(void (int)) *signal(int signum, typeof(void (int)) *handler);

  قابلية النقل
الاستخدام الوحيد القابل للنقل لـ signal() هو ضبط تصرف إشارة إلى SIG_DFL أو SIG_IGN. تختلف الدلالات عند استخدام signal() لإنشاء معالج إشارة عبر الأنظمة (ويسمح POSIX.1 صراحةً بهذا الاختلاف)؛ لا تستخدمها لهذا الغرض.

حل POSIX.1 فوضى قابلية النقل بتحديد sigaction(2)، الذي يوفر تحكمًا صريحًا في الدلالات عند استدعاء معالج إشارة؛ استخدم تلك الواجهة بدلاً من signal().

المعايير
C11، ‏POSIX.1-2024.

التاريخ
C89, POSIX.1-2001.

في أنظمة UNIX الأصلية، عندما يُستدعى معالج أُنشئ باستخدام signal() عن طريق تسليم إشارة، يُعاد ضبط تصرف الإشارة إلى SIG_DFL، ولا يحجب النظام تسليم حالات إضافية من الإشارة. هذا يعادل استدعاء sigaction(2) مع الأعلام التالية:

    sa.sa_flags = SA_RESETHAND | SA_NODEFER;

يوفر System V أيضًا هذه الدلالات لـ signal(). كان هذا سيئًا لأنه قد تُسلم الإشارة مرة أخرى قبل أن تتاح للمعالج فرصة إعادة تأسيس نفسه. علاوة على ذلك، قد تؤدي التسليمات السريعة لنفس الإشارة إلى استدعاءات متكررة للمعالج.

حسّن BSD هذا الموقف، لكن للأسف غيّر أيضًا دلالات واجهة signal() الموجودة أثناء ذلك. في BSD، عندما يُستدعى معالج إشارة، لا يُعاد ضبط تصرف الإشارة، وتُحجب حالات إضافية من الإشارة من التسليم أثناء تنفيذ المعالج. علاوة على ذلك، تُعاد تشغيل بعض استدعاءات النظام الحاجبة آليًا إذا قاطعها معالج إشارة (انظر signal(7)). دلالات BSD تعادل استدعاء sigaction(2) مع الأعلام التالية:

    sa.sa_flags = SA_RESTART;

الوضع على Linux هو كالتالي:

•   استدعاء نظام signal() في النواة يوفر دلالات System V.

•   مبدئيًا، في glibc 2 والإصدارات الأحدث، لا تستدعي دالة التغليف signal() استدعاء نظام النواة. بدلاً من ذلك، تستدعي sigaction(2) باستخدام أعلام توفر دلالات BSD. يُوفر هذا السلوك المبدئي طالما عُرّف ماكرو اختبار ميزة مناسب: _BSD_SOURCE في glibc 2.19 والإصدارات الأقدم أو _DEFAULT_SOURCE في glibc 2.19 والإصدارات الأحدث. (مبدئيًا، هذه الماكروات مُعرّفة؛ انظر feature_test_macros(7) للتفاصيل.) إذا لم يُعرّف مثل هذا الماكرو، فتوفر signal() دلالات System V.

ملاحظات
تأثيرات signal() في عملية متعددة الخيوط غير محددة.

وفقًا لـ POSIX، يكون سلوك العملية غير محدد بعد تجاهلها لإشارة SIGFPE أو SIGILL أو SIGSEGV التي لم تُنتج بواسطة kill(2) أو raise(3). قسمة الأعداد الصحيحة على صفر لها نتيجة غير محددة. في بعض البنيات ستنتج إشارة SIGFPE. (كما أن قسمة أصغر عدد صحيح سالب على -1 قد تنتج SIGFPE). تجاهل هذه الإشارة قد يؤدي إلى حلقة مفرغة.

انظر sigaction(2) للتفاصيل حول ما يحدث عندما يُضبط التصرف SIGCHLD على SIG_IGN.

انظر signal-safety(7) للحصول على قائمة بالدوال الآمنة للإشارات غير المتزامنة التي يمكن استدعاؤها بأمان من داخل معالج إشارة.

انظر أيضًا
kill(1), alarm(2), kill(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), killpg(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)

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

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

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