.\" -*- coding: UTF-8 -*- '\" t .\" Copyright 2009, Petr Baudis .\" Copyright 2010, Michael Kerrisk .\" Copyright, the authors of the Linux man-pages project .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH getaddrinfo_a 3 "8 فبراير 2026" "صفحات دليل لينكس 6.18" .SH الاسم getaddrinfo_a, gai_suspend, gai_error, gai_cancel \- ترجمة غير متزامنة لعنوان الشبكة والخدمة .SH المكتبة مكتبة البحث عن الأسماء غير المتزامنة (\fIlibanl\fP,\ \fI\-lanl\fP) .SH موجز .nf \fB#define _GNU_SOURCE\fP /* انظر feature_test_macros(7) */ \fB#include \fP .P \fBint getaddrinfo_a(int \fP\fImode\fP\fB, struct gaicb *\fP\fIlist\fP\fB[restrict \fP\fIn\fP\fB],\fP \fB int \fP\fIn\fP\fB, struct sigevent *restrict \fP\fIsevp\fP\fB);\fP \fBint gai_suspend(const struct gaicb *const \fP\fIlist\fP\fB[\fP\fIn\fP\fB], int \fP\fIn\fP\fB,\fP \fB const struct timespec *\fP\fItimeout\fP\fB);\fP .P \fBint gai_error(struct gaicb *\fP\fIreq\fP\fB);\fP \fBint gai_cancel(struct gaicb *\fP\fIreq\fP\fB);\fP .fi .SH الوصف الدالة \fBgetaddrinfo_a\fP() تؤدي نفس مهمة \fBgetaddrinfo\fP(3)، لكنها تسمح بإجراء عمليات بحث متعددة عن الأسماء بشكل غير متزامن، مع إشعار اختياري عند اكتمال عمليات البحث. .P المعامل \fImode\fP له إحدى القيم التالية: .TP \fBGAI_WAIT\fP إجراء عمليات البحث بشكل متزامن. يُحجَز الاستدعاء حتى تكتمل عمليات البحث. .TP \fBGAI_NOWAIT\fP إجراء عمليات البحث بشكل غير متزامن. يعود الاستدعاء فورًا، وتُحل الطلبات في الخلفية. انظر مناقشة المعامل \fIsevp\fP أدناه. .P المصفوفة \fIlist\fP تحدد طلبات البحث التي ستُعالج. المعامل \fIn\fP يحدد عدد العناصر في \fIlist\fP. تُبدأ عمليات البحث المطلوبة بالتوازي. تُتجاهل العناصر NULL في \fIlist\fP. يُوصف كل طلب بهيكل \fIgaicb\fP، المُعرَّف كالتالي: .P .in +4n .EX struct gaicb { const char *ar_name; const char *ar_service; const struct addrinfo *ar_request; struct addrinfo *ar_result; }; .EE .in .P عناصر هذا الهيكل تتوافق مع معاملات \fBgetaddrinfo\fP(3). لذا، \fIar_name\fP يتوافق مع المعامل \fInode\fP و \fIar_service\fP مع المعامل \fIservice\fP، مُعرِّفًا مضيف إنترنت وخدمة. العنصر \fIar_request\fP يتوافق مع المعامل \fIhints\fP، مُحددًا معايير اختيار هياكل عنوان المقبس المُعادة. أخيرًا، \fIar_result\fP يتوافق مع المعامل \fIres\fP؛ لا تحتاج لتهيئة هذا العنصر، سيُضبط آليًا عند حل الطلب. هيكل \fIaddrinfo\fP المُشار إليه بالعنصرين الأخيرين موصوف في \fBgetaddrinfo\fP(3). .P عندما يُحدد \fImode\fP كـ \fBGAI_NOWAIT\fP، يمكن الحصول على إشعارات حول الطلبات المُحلّة باستخدام هيكل \fIsigevent\fP المُشار إليه بالمعامل \fIsevp\fP. للتعريف والتفاصيل العامة لهذا الهيكل، انظر \fBsigevent\fP(3type). الحقل \fIsevp\->sigev_notify\fP يمكن أن يكون له القيم التالية: .TP \fBSIGEV_NONE\fP لا تُقدم أي إشعار. .TP \fBSIGEV_SIGNAL\fP .\" si_pid and si_uid are also set, to the values of the calling process, .\" which doesn't provide useful information, so we'll skip mentioning it. عند اكتمال بحث، يُولَّد الإشارة \fIsigev_signo\fP للعملية. انظر \fBsigevent\fP(3type) للتفاصيل العامة. الحقل \fIsi_code\fP من هيكل \fIsiginfo_t\fP سيُضبط إلى \fBSI_ASYNCNL\fP. .TP \fBSIGEV_THREAD\fP عند اكتمال بحث، تُستدعى \fIsigev_notify_function\fP كما لو كانت دالة بدء خيط جديد. انظر \fBsigevent\fP(3type) للتفاصيل. .P بالنسبة لـ \fBSIGEV_SIGNAL\fP و \fBSIGEV_THREAD\fP، قد يكون من المفيد توجيه \fIsevp\->sigev_value.sival_ptr\fP إلى \fIlist\fP. .P الدالة \fBgai_suspend\fP() تُعلق تنفيذ الخيط المُستدعي، منتظرة اكتمال طلب واحد أو أكثر في المصفوفة \fIlist\fP. المعامل \fIn\fP يحدد حجم المصفوفة \fIlist\fP. يُحجَز الاستدعاء حتى يحدث أحد التالي: .IP \[bu] 3 تكتمل عملية أو أكثر من العمليات في \fIlist\fP. .IP \[bu] تُقاطع الاستدعاء بإشارة تم التقاطها. .IP \[bu] ينقضي الفاصل الزمني المحدد في \fItimeout\fP. تحدد هذه الوسيطة مهلة بالثواني بالإضافة إلى النانوثانية (انظر \fBnanosleep\fP(2) لتفاصيل بنية \fItimespec\fP). إذا كان \fItimeout\fP NULL، فتحجب الاستدعاء إلى أجل غير مسمى (حتى يقع أحد الأحداث أعلاه). .P لا يُعطى إشارة صريحة عن أي طلب أُكمل؛ يجب عليك تحديد أي الطلبات أُكملت بالتكرار مع \fBgai_error\fP() على قائمة الطلبات. .P ترجع الدالة \fBgai_error\fP() حالة الطلب \fIreq\fP: إما \fBEAI_INPROGRESS\fP إذا لم يُكمل الطلب بعد، أو 0 إذا عُولج بنجاح، أو رمز خطأ إذا تعذر حل الطلب. .P تلغي الدالة \fBgai_cancel\fP() الطلب \fIreq\fP. إذا أُلغي الطلب بنجاح، فتُضبط حالة خطأ الطلب إلى \fBEAI_CANCELED\fP ويُجرى الإعلام غير المتزامن العادي. لا يمكن إلغاء الطلب إذا كان يُعالج حاليًا؛ في تلك الحالة، يُعالج كما لو أن \fBgai_cancel\fP() لم تُستدعَ أبدًا. إذا كان \fIreq\fP NULL، فتُبذل محاولة لإلغاء جميع الطلبات المعلقة التي قامت بها العملية. .SH "قيمة الإرجاع" ترجع الدالة \fBgetaddrinfo_a\fP() 0 إذا صُفت جميع الطلبات في قائمة الانتظار بنجاح، أو أحد رموز الخطأ غير الصفرية التالية: .TP \fBEAI_AGAIN\fP لم تكن الموارد اللازمة لصف طلبات البحث في قائمة الانتظار متاحة. يمكن للتطبيق التحقق من حالة خطأ كل طلب لتحديد أي منها فشل. .TP \fBEAI_MEMORY\fP نفدت الذاكرة. .TP \fBEAI_SYSTEM\fP \fImode\fP غير صالح. .P ترجع الدالة \fBgai_suspend\fP() 0 إذا أُكمل طلب واحد على الأقل من الطلبات المدرجة. وإلا، فترجع أحد رموز الخطأ غير الصفرية التالية: .TP \fBEAI_AGAIN\fP انتهت المهلة المعطاة قبل أن يُكمل أي من الطلبات. .TP \fBEAI_ALLDONE\fP لم تُعطَ أي طلبات فعلية للدالة. .TP \fBEAI_INTR\fP قاطعت إشارة الدالة. لاحظ أن هذا الانقطاع قد يكون ناتجًا عن إعلام إشارة لبعض طلبات البحث المكتملة. .P يمكن للدالة \fBgai_error\fP() أن ترجع \fBEAI_INPROGRESS\fP لطلب بحث غير مكتمل، أو 0 لبحث أُكمل بنجاح (كما هو موصوف أعلاه)، أو أحد رموز الخطأ التي قد ترجعها \fBgetaddrinfo\fP(3)، أو رمز الخطأ \fBEAI_CANCELED\fP إذا أُلغي الطلب صراحةً قبل أن يُكمل. .P يمكن للدالة \fBgai_cancel\fP() أن ترجع إحدى هذه القيم: .TP \fBEAI_CANCELED\fP أُلغي الطلب بنجاح. .TP \fBEAI_NOTCANCELED\fP لم يُلغَ الطلب. .TP \fBEAI_ALLDONE\fP اكتمل الطلب بالفعل. .P ترجم الدالة \fBgai_strerror\fP(3) رموز الخطأ هذه إلى سلسلة نصية مقروءة للبشر، مناسبة للإبلاغ عن الأخطاء. .SH السمات للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. الواجهة السمة القيمة T{ .na .nh \fBgetaddrinfo_a\fP(), \fBgai_suspend\fP(), \fBgai_error\fP(), \fBgai_cancel\fP() T} سلامة الخيوط MT\-Safe .TE .SH المعايير GNU. .SH التاريخ glibc 2.2.3. .P صُممت واجهة \fBgetaddrinfo_a\fP() على غرار واجهة \fBlio_listio\fP(3). .SH أمثلة يُقدَّم مثالان: مثال بسيط يحل عدة طلبات بالتوازي بشكل تزامني، ومثال معقد يُظهر بعض القدرات اللاتزامنية. .SS "مثال تزامني" يحل البرنامج أدناه ببساطة عدة أسماء مضيفين بالتوازي، مما يُعطي تسريعًا مقارنة بحل أسماء المضيفين تسلسليًا باستخدام \fBgetaddrinfo\fP(3). يمكن استخدام البرنامج هكذا: .P .in +4n .EX $\fB ./a.out mirrors.kernel.org enoent.linuxfoundation.org gnu.org\fP; mirrors.kernel.org: 139.178.88.99 enoent.linuxfoundation.org: Name or service not known gnu.org: 209.51.188.116 .EE .in .P هذا هو الكود المصدري للبرنامج .P .\" SRC BEGIN (sync.c) .EX #define _GNU_SOURCE #include #include #include #include #include \& #define MALLOC(n, type) ((type *) reallocarray(NULL, n, sizeof(type))) \& int main(int argc, char *argv[]) { int ret; struct gaicb *reqs[argc \- 1]; char host[NI_MAXHOST]; struct addrinfo *res; \& if (argc < 2) { fprintf(stderr, "Usage: %s HOST...\[rs]n", argv[0]); exit(EXIT_FAILURE); } \& for (size_t i = 0; i < argc \- 1; i++) { reqs[i] = MALLOC(1, struct gaicb); if (reqs[i] == NULL) err(EXIT_FAILURE, "malloc"); \& memset(reqs[i], 0, sizeof(*reqs[0])); reqs[i]\->ar_name = argv[i + 1]; } \& ret = getaddrinfo_a(GAI_WAIT, reqs, argc \- 1, NULL); if (ret != 0) { fprintf(stderr, "getaddrinfo_a() failed: %s\[rs]n", gai_strerror(ret)); exit(EXIT_FAILURE); } \& for (size_t i = 0; i < argc \- 1; i++) { printf("%s: ", reqs[i]\->ar_name); ret = gai_error(reqs[i]); if (ret == 0) { res = reqs[i]\->ar_result; \& ret = getnameinfo(res\->ai_addr, res\->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); if (ret != 0) { fprintf(stderr, "getnameinfo() failed: %s\[rs]n", gai_strerror(ret)); exit(EXIT_FAILURE); } puts(host); \& } else { puts(gai_strerror(ret)); } } exit(EXIT_SUCCESS); } .EE .\" SRC END .SS "مثال لاتزامني" يُظهر هذا المثال واجهة أمامية تفاعلية بسيطة لـ \fBgetaddrinfo_a\fP(). لم يُوضَّح مرفق الإشعار. .P قد تبدو جلسة مثال هكذا: .P .in +4n .EX $\fB ./a.out\fP; > a mirrors.kernel.org enoent.linuxfoundation.org gnu.org > c 2 [2] gnu.org: Request not canceled > w 0 1 [00] mirrors.kernel.org: Finished > l [00] mirrors.kernel.org: 139.178.88.99 [01] enoent.linuxfoundation.org: Processing request in progress [02] gnu.org: 209.51.188.116 > l [00] mirrors.kernel.org: 139.178.88.99 [01] enoent.linuxfoundation.org: Name or service not known [02] gnu.org: 209.51.188.116 .EE .in .P المصدر البرمجي للبرنامج كما يلي: .P .\" SRC BEGIN (async.c) .EX #define _GNU_SOURCE #include #include #include #include #include #include \& #define CALLOC(n, type) ((type *) calloc(n, sizeof(type))) \& #define REALLOCF(ptr, n, type) \[rs] ({ \[rs] static_assert(__builtin_types_compatible_p(typeof(ptr), type *)); \[rs] \[rs] (type *) reallocarrayf(ptr, n, sizeof(type)); \[rs] }) \& static struct gaicb **reqs = NULL; static size_t nreqs = 0; \& static inline void * reallocarrayf(void *p, size_t n, size_t size) { void *q; \& q = reallocarray(p, n, size); if (q == NULL && n != 0 && size != 0) free(p); return q; } \& static char * getcmd(void) { static char buf[256]; \& fputs("> ", stdout); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) return NULL; \& if (buf[strlen(buf) \- 1] == \[aq]\[rs]n\[aq]) buf[strlen(buf) \- 1] = 0; \& return buf; } \& /* Add requests for specified hostnames. */ static void add_requests(void) { size_t nreqs_base = nreqs; char *host; int ret; \& while ((host = strtok(NULL, " "))) { nreqs++; reqs = REALLOCF(reqs, nreqs, struct gaicb *); if (reqs == NULL) err(EXIT_FAILURE, "reallocf"); \& reqs[nreqs \- 1] = CALLOC(1, struct gaicb); if (reqs[nreqs \- 1] == NULL) err(EXIT_FAILURE, "calloc"); \& reqs[nreqs \- 1]\->ar_name = strdup(host); } \& /* Queue nreqs_base..nreqs requests. */ \& ret = getaddrinfo_a(GAI_NOWAIT, &reqs[nreqs_base], nreqs \- nreqs_base, NULL); if (ret) { fprintf(stderr, "getaddrinfo_a() failed: %s\[rs]n", gai_strerror(ret)); exit(EXIT_FAILURE); } } \& /* Wait until at least one of specified requests completes. */ static void wait_requests(void) { char *id; int ret; size_t n; struct gaicb const **wait_reqs; \& wait_reqs = CALLOC(nreqs, const struct gaicb *); if (wait_reqs == NULL) err(EXIT_FAILURE, "calloc"); \& /* NULL elements are ignored by gai_suspend(). */ \& while ((id = strtok(NULL, " ")) != NULL) { n = atoi(id); \& if (n >= nreqs) { printf("Bad request number: %s\[rs]n", id); return; } \& wait_reqs[n] = reqs[n]; } \& ret = gai_suspend(wait_reqs, nreqs, NULL); if (ret) { printf("gai_suspend(): %s\[rs]n", gai_strerror(ret)); return; } \& for (size_t i = 0; i < nreqs; i++) { if (wait_reqs[i] == NULL) continue; \& ret = gai_error(reqs[i]); if (ret == EAI_INPROGRESS) continue; \& printf("[%02zu] %s: %s\[rs]n", i, reqs[i]\->ar_name, ret == 0 ? "Finished" : gai_strerror(ret)); } } \& /* Cancel specified requests. */ static void cancel_requests(void) { char *id; int ret; size_t n; \& while ((id = strtok(NULL, " ")) != NULL) { n = atoi(id); \& if (n >= nreqs) { printf("Bad request number: %s\[rs]n", id); return; } \& ret = gai_cancel(reqs[n]); printf("[%s] %s: %s\[rs]n", id, reqs[atoi(id)]\->ar_name, gai_strerror(ret)); } } \& /* List all requests. */ static void list_requests(void) { int ret; char host[NI_MAXHOST]; struct addrinfo *res; \& for (size_t i = 0; i < nreqs; i++) { printf("[%02zu] %s: ", i, reqs[i]\->ar_name); ret = gai_error(reqs[i]); \& if (!ret) { res = reqs[i]\->ar_result; \& ret = getnameinfo(res\->ai_addr, res\->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST); if (ret) { fprintf(stderr, "getnameinfo() failed: %s\[rs]n", gai_strerror(ret)); exit(EXIT_FAILURE); } puts(host); } else { puts(gai_strerror(ret)); } } } \& int main(void) { char *cmdline; char *cmd; \& while ((cmdline = getcmd()) != NULL) { cmd = strtok(cmdline, " "); \& if (cmd == NULL) { list_requests(); } else { switch (cmd[0]) { case \[aq]a\[aq]: add_requests(); break; case \[aq]w\[aq]: wait_requests(); break; case \[aq]c\[aq]: cancel_requests(); break; case \[aq]l\[aq]: list_requests(); break; default: fprintf(stderr, "Bad command: %c\[rs]n", cmd[0]); break; } } } exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "انظر أيضًا" \fBgetaddrinfo\fP(3), \fBinet\fP(3), \fBlio_listio\fP(3), \fBhostname\fP(7), \fBip\fP(7), \fBsigevent\fP(3type) .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .