Scroll to navigation

syscall(2) System Calls Manual syscall(2)

الاسم

syscall - استدعاء نظام غير مباشر

المكتبة

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

موجز

#include <sys/syscall.h>      /* تعريف ثوابت SYS_* */
#include <unistd.h>
long syscall(long number, ...);

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

syscall():


بدءًا من glibc 2.19:
_DEFAULT_SOURCE
قبل glibc 2.19:
_BSD_SOURCE || _SVID_SOURCE

الوصف

syscall() هي دالة مكتبة صغيرة تستدعي استدعاء النظام الذي تمتلك واجهة لغة التجميع الخاصة به الـ number المحدّد مع الوسائط المحدّدة. يُعدّ استخدام syscall() مفيدًا، على سبيل المثال، عند استدعاء استدعاء نظام ليس له دالة غلاف (wrapper) في مكتبة سي.

تحفظ syscall() سجلات وحدة المعالجة المركزية قبل إجراء استدعاء النظام، وتستعيد السجلات عند العودة من استدعاء النظام، وتخزن أي خطأ يرجعه استدعاء النظام في errno(3).

يمكن العثور على الثوابت الرمزية لأرقام استدعاءات النظام في ملف الترويسة <sys/syscall.h>.

قيمة الإرجاع

تُعرّف قيمة الإرجاع بواسطة استدعاء النظام المُستدعَى. وبشكل عام، تشير قيمة الإرجاع 0 إلى النجاح. وتشير قيمة الإرجاع -1 إلى حدوث خطأ، ويُخزن رقم الخطأ في errno.

الأخطاء

رقم استدعاء النظام المطلوب غير مُنفّذ.

الأخطاء الأخرى خاصة باستدعاء النظام المُستدعَى.

التاريخ

ظهرت syscall() لأول مرة في 4BSD.

ملاحظات

متطلبات خاصة بالبنية

لكل واجهة تطبيق ثنائية (ABI) خاصة ببنية معينة متطلباتها الخاصة حول كيفية تمرير وسائط استدعاء النظام إلى النواة. بالنسبة لاستدعاءات النظام التي تملك غلاف glibc (مثل معظم استدعاءات النظام)، تتولى glibc تفاصيل نسخ الوسائط إلى السجلات الصحيحة بطريقة مناسبة للبنية. ومع ذلك، عند استخدام syscall() لإجراء استدعاء نظام، قد يحتاج المستدعِي إلى التعامل مع التفاصيل المعتمدة على البنية؛ ويواجه هذا المتطلب بشكل شائع في بنى معينة ذات 32 بت.

على سبيل المثال، في بنية ARM ذات واجهة التطبيق الثنائية المدمجة (EABI)، يجب محاذاة القيمة ذات 64 بت (مثل long long) مع زوج سجلات زوجي. وبالتالي، عند استخدام syscall() بدلاً من الغلاف الذي توفره glibc، سيُستدعى استدعاء النظام readahead(2) كما يلي على بنية ARM مع EABI في وضع endian الصغير (little endian):


syscall(SYS_readahead, fd, 0,

(unsigned int) (offset & 0xFFFFFFFF),
(unsigned int) (offset >> 32),
count);

بما أن وسيط الإزاحة (offset) هو 64 بت، والوسيط الأول (fd) يُمرر في r0، يجب على المستدعِي تقسيم ومحاذاة القيمة ذات 64 بت يدويًا بحيث تُمرر في زوج السجلات r2/r3. وهذا يعني إدراج قيمة وهمية في r1 (الوسيط الثاني وهو 0). يجب أيضًا توخي الحذر لضمان أن التقسيم يتبع اتفاقيات endian (وفقًا لواجهة التطبيق الثنائية للغة سي للمنصة).

يمكن أن تحدث مشكلات مماثلة على MIPS مع O32 ABI، وعلى PowerPC و parisc مع ABI ذي 32 بت، وعلى Xtensa.

لاحظ أنه على الرغم من أن parisc C ABI يستخدم أيضًا أزواج سجلات محاذاة، إلا أنه يستخدم طبقة حشو (shim layer) لإخفاء المشكلة عن مساحة المستخدم.

استدعاءات النظام المتأثرة هي fadvise64_64(2)، و ftruncate64(2)، و posix_fadvise(2)، و pread64(2)، و pwrite64(2)، و readahead(2)، و sync_file_range(2)، و truncate64(2).

لا يؤثر هذا على استدعاءات النظام التي تقسم وتجمع القيم ذات 64 بت يدويًا مثل _llseek(2)، و preadv(2)، و preadv2(2)، و pwritev(2)، و pwritev2(2). مرحبًا بك في عالم الموروثات التاريخية الرائع.

اتفاقيات استدعاء البنية

لكل بنية طريقتها الخاصة في استدعاء الوسائط وتمريرها إلى النواة. تفاصيل البنى المختلفة مدرجة في الجدولين أدناه.

يسرد الجدول الأول التعليمات المستخدمة للانتقال إلى وضع النواة (والتي قد لا تكون الطريقة الأسرع أو الأفضل للانتقال إلى النواة، لذا قد تضطر إلى الرجوع إلى vdso(7))، والسجل المستخدم للإشارة إلى رقم استدعاء النظام، والسجل (السجلات) المستخدم لإرجاع نتيجة استدعاء النظام، والسجل المستخدم للإشارة إلى خطأ.

البنية/ABI التعليمة النظام Ret Ret الخطأ ملاحظات
رقم الاستدعاء val val2
alpha callsys v0 v0 a4 a3 1, 6
arc trap0 r8 r0 - -
arm/OABI swi NR - r0 - - 2
arm/EABI swi 0x0 r7 r0 r1 -
arm64 svc #0 w8 x0 x1 -
blackfin excpt 0x0 P0 R0 - -
i386 int $0x80 eax eax edx -
ia64 break 0x100000 r15 r8 r9 r10 1, 6
loongarch syscall 0 a7 a0 - -
m68k trap #0 d0 d0 - -
microblaze brki r14,8 r12 r3 - -
mips syscall v0 v0 v1 a3 1, 6
nios2 trap r2 r2 - r7
parisc ble 0x100(%sr2, %r0) r20 r28 - -
powerpc sc r0 r3 - r0 1
powerpc64 sc r0 r3 - cr0.SO 1
riscv ecall a7 a0 a1 -
s390 svc 0 r1 r2 r3 - 3
s390x svc 0 r1 r2 r3 - 3
superh trapa #31 r3 r0 r1 - 4, 6
sparc/32 t 0x10 g1 o0 o1 psr/csr 1, 6
sparc/64 t 0x6d g1 o0 o1 psr/csr 1, 6
tile swint1 R10 R00 - R01 1
x86-64 syscall eax rax rdx - 5
x32 syscall eax rax rdx - 5
xtensa syscall a2 a2 - -

ملاحظات:

[1]
في عدد قليل من المعماريات، يُستخدم مسجل كقيمة منطقية (0 تشير إلى عدم وجود خطأ، و -1 تشير إلى وجود خطأ) للإشارة إلى فشل استدعاء النظام. ما تزال قيمة الخطأ الفعلية موجودة في مسجل الإرجاع. في sparc، تُستخدم بتة الحمل (csr) في مسجل حالة المعالج (psr) بدلاً من مسجل كامل. وفي powerpc64، تُستخدم بتة تجاوز المخلص (SO) في الحقل 0 من مسجل الحالة (cr0).
[2]
NR هو رقم استدعاء النظام.
[3]
بالنسبة لـ s390 و s390x، يمكن تمرير NR (رقم استدعاء النظام) مباشرة عبر svc NR إذا كان أقل من 256.
[4]
تُدعم أرقام مصيدة (trap) إضافية في SuperH لأسباب تاريخية، ولكن trapa#31 هي واجهة تطبيق الثنائيات (ABI) "الموحدة" الموصى بها.
[5]
تتشارك ABI الخاصة بـ x32 جدول استدعاءات النظام مع ABI الخاصة بـ x86-64، ولكن هناك بعض الفوارق الدقيقة:
للإشارة إلى أن استدعاء النظام يُستدعى تحت ABI الخاصة بـ x32، تُجرى عملية OR منطقية لبتة إضافية، __X32_SYSCALL_BIT، مع رقم استدعاء النظام. تؤثر ABI المستخدمة من قبل العملية على بعض سلوكيات العملية، بما في ذلك معالجة الإشارات أو إعادة تشغيل استدعاء النظام.
بما أن x32 لديه أحجام مختلفة للأنواع long والمؤشرات، فإن تخطيطات بعض الهياكل تختلف (ولكن ليس كلها؛ struct timeval أو struct rlimit هي 64 بت، على سبيل المثال). للتعامل مع هذا، أُضيفت استدعاءات نظام إضافية إلى جدول استدعاءات النظام، بدءاً من الرقم 512 (بدون __X32_SYSCALL_BIT). على سبيل المثال، عُرّف __NR_readv بالرقم 19 لـ ABI الخاصة بـ x86-64 وبالقيمة __X32_SYSCALL_BIT | 515 لـ ABI الخاصة بـ x32. معظم استدعاءات النظام الإضافية هذه متطابقة فعلياً مع استدعاءات النظام المستخدمة لتوفير توافق i386. ومع ذلك، هناك بعض الاستثناءات الملحوظة، مثل preadv2(2)، الذي يستخدم كيانات struct iovec بمؤشرات وأحجام من 4 بايت ("compat_iovec" بمصطلحات النواة)، ولكنه يمرر وسيط pos بحجم 8 بايت في مسجل واحد وليس اثنين، كما هو الحال في كل ABI أخرى.
[6]
تستخدم بعض المعماريات (وهي Alpha و IA-64 و MIPS و SuperH و sparc/32 و sparc/64) مسجلاً إضافياً ("Retval2" في الجدول أعلاه) لإعادة قيمة إرجاع ثانية من استدعاء النظام pipe(2)؛ وتستخدم Alpha هذه التقنية في استدعاءات النظام الخاصة بالمعمارية getxpid(2) و getxuid(2) و getxgid(2) أيضًا. المعماريات الأخرى لا تستخدم مسجل قيمة الإرجاع الثانية في واجهة استدعاء النظام، حتى لو كانت معرفة في ABI الخاصة بـ System V.

يوضح الجدول الثاني المسجلات المستخدمة لتمرير وسائط استدعاء النظام.

البنية/ABI arg1 arg2 arg3 arg4 arg5 arg6 arg7 ملاحظات
alpha a0 a1 a2 a3 a4 a5 -
arc r0 r1 r2 r3 r4 r5 -
arm/OABI r0 r1 r2 r3 r4 r5 r6
arm/EABI r0 r1 r2 r3 r4 r5 r6
arm64 x0 x1 x2 x3 x4 x5 -
blackfin R0 R1 R2 R3 R4 R5 -
i386 ebx ecx edx esi edi ebp -
ia64 out0 out1 out2 out3 out4 out5 -
loongarch a0 a1 a2 a3 a4 a5 a6
m68k d1 d2 d3 d4 d5 a0 -
microblaze r5 r6 r7 r8 r9 r10 -
mips/o32 a0 a1 a2 a3 - - - 1
mips/n32,64 a0 a1 a2 a3 a4 a5 -
nios2 r4 r5 r6 r7 r8 r9 -
parisc r26 r25 r24 r23 r22 r21 -
powerpc r3 r4 r5 r6 r7 r8 r9
powerpc64 r3 r4 r5 r6 r7 r8 -
riscv a0 a1 a2 a3 a4 a5 -
s390 r2 r3 r4 r5 r6 r7 -
s390x r2 r3 r4 r5 r6 r7 -
superh r4 r5 r6 r7 r0 r1 r2
sparc/32 o0 o1 o2 o3 o4 o5 -
sparc/64 o0 o1 o2 o3 o4 o5 -
tile R00 R01 R02 R03 R04 R05 -
x86-64 rdi rsi rdx r10 r8 r9 -
x32 rdi rsi rdx r10 r8 r9 -
xtensa a6 a3 a4 a5 a8 a9 -

ملاحظات:

[1]
تمرر اتفاقية استدعاء النظام mips/o32 المعاملات من 5 إلى 8 عبر مكدس المستخدم.

لاحظ أن هذه الجداول لا تغطي اتفاقية الاستدعاء بأكملها؛ فقد تفرغ بعض المعماريات سجلات أخرى غير مدرجة هنا دون تمييز.

أمثلة

#define _GNU_SOURCE
#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{

pid_t tid;
tid = syscall(SYS_gettid);
syscall(SYS_tgkill, getpid(), tid, SIGHUP); }

انظر أيضًا

_syscall(2)، intro(2)، syscalls(2)، errno(3)، vdso(7)

ترجمة

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

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

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

2 فبراير 2026 صفحات دليل لينكس 6.18