.\" -*- coding: UTF-8 -*- '\" t .\" 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 fopencookie 3 "21 سبتمبر 2025" "صفحات دليل لينكس 6.18" .SH الاسم fopencookie \- فتح دفق مخصص .SH المكتبة مكتبة سي المعيارية (\fIlibc\fP،\ \fI\-lc\fP) .SH موجز .nf \fB#define _GNU_SOURCE\fP /* See feature_test_macros(7) */ \fB#define _FILE_OFFSET_BITS 64\fP \fB#include \fP .P \fBFILE *fopencookie(void *restrict \fP\fIcookie\fP\fB, const char *restrict \fP\fImode\fP\fB,\fP \fB cookie_io_functions_t \fP\fIio_funcs\fP\fB);\fP .fi .SH الوصف تسمح الدالة \fBfopencookie\fP() للمبرمج بإنشاء تنفيذ مخصص لدفق إدخال/إخراج قياسي. يمكن لهذا التنفيذ تخزين بيانات الدفق في موقع يختاره بنفسه؛ على سبيل المثال، تُستخدم \fBfopencookie\fP() لتنفيذ \fBfmemopen\fP(3)، التي توفر واجهة دفق للبيانات المخزنة في مخزن مؤقت في الذاكرة. .P لإنشاء دفق مخصص، يجب على المبرمج: .IP \[bu] 3 تنفيذ أربع دوال "خطافية" تُستخدم داخليًا بواسطة مكتبة الإدخال/الإخراج القياسية عند تنفيذ الإدخال/الإخراج على الدفق. .IP \[bu] تحديد نوع بيانات "كعكة" (cookie)، وهي بنية توفر معلومات الحفظ والسجلات (مثل مكان تخزين البيانات) التي تُستخدم من قِبل دالات الخطاف (hook functions) المذكورة سابقاً. لا تحوز حزمة الإدخال/الإخراج القياسية أي معرفة بمحتويات هذه الكعكة (لذا تُعرّف بالنوع \fIvoid\ *\fP عند تمريرها إلى الدالة \fBfopencookie\fP())، ولكنها تمرر الكعكة تلقائياً بصفتها وسيطاً أولاً عند استدعاء دالات الخطاف. .IP \[bu] استدعاء \fBfopencookie\fP() لفتح دفق جديد وربط الخبيئة ودوال الخطاف بهذا الدفق. .P تخدم الدالة \fBfopencookie\fP() غرضًا مشابهًا لـ \fBfopen\fP(3): فهي تفتح دفقًا جديدًا وتُعيد مؤشرًا إلى كائن \fIFILE\fP يُستخدم للتعامل مع ذلك الدفق. .P الوسيط \fIcookie\fP هو مؤشر إلى هيكل الخبيئة الخاص بالمستدعي الذي سيُربط بالدفق الجديد. يُوفر هذا المؤشر كوسيط أول عندما تستدعي مكتبة الإدخال/الإخراج القياسية أيًا من دوال الخطاف الموصوفة أدناه. .P يخدم الوسيط \fImode\fP نفس الغرض كما في \fBfopen\fP(3). الأوضاع التالية مدعومة: \fIr\fP، \fIw\fP، \fIa\fP، \fIr+\fP، \fIw+\fP، و \fIa+\fP. انظر \fBfopen\fP(3) للتفاصيل. .P الوسيط \fIio_funcs\fP هو هيكل يحتوي على أربعة حقول تشير إلى دوال الخطاف المعرفة من قبل المبرمج والتي تُستخدم لتنفيذ هذا الدفق. يُعرف الهيكل كالتالي .P .in +4n .EX typedef struct { cookie_read_function_t *read; cookie_write_function_t *write; cookie_seek_function_t *seek; cookie_close_function_t *close; } cookie_io_functions_t; .EE .in .P الحقول الأربعة هي كالتالي: .TP \fIcookie_read_function_t *read\fP تنفذ هذه الدالة عمليات القراءة للدفق. عند استدعائها، تتلقى ثلاثة وسائط: .IP .in +4n .EX ssize_t read(void *cookie, char *buf, size_t size); .EE .in .IP الوسيطان \fIbuf\fP و \fIsize\fP هما، على التوالي، مخزن يمكن وضع بيانات الإدخال فيه وحجم ذلك المخزن. كنتيجة للدالة، يجب أن تُعيد دالة \fIread\fP عدد البايتات المنسوخة إلى \fIbuf\fP، أو 0 عند نهاية الملف، أو \-1 عند الخطأ. يجب أن تُحدّث دالة \fIread\fP إزاحة الدفق بشكل مناسب. .IP إذا كان \fI*read\fP مؤشرًا فارغًا، فإن القراءات من الدفق المخصص تُعيد دائمًا نهاية الملف. .TP \fIcookie_write_function_t *write\fP تنفذ هذه الدالة عمليات الكتابة للدفق. عند استدعائها، تستقبل ثلاث وسائط: .IP .in +4n .EX ssize_t write(void *cookie, const char *buf, size_t size); .EE .in .IP الوسيطان \fIbuf\fP و \fIsize\fP هما، على التوالي، مخزن بيانات سيُخرج إلى الدفق وحجم ذلك المخزن. كنتيجة لدالتها، يجب على دالة \fIwrite\fP أن تُرجع عدد البايتات المنسوخة من \fIbuf\fP، أو 0 عند الخطأ. (يجب ألا تُرجع الدالة قيمة سالبة.) يجب على دالة \fIwrite\fP أن تُحدّث إزاحة الدفق بشكل مناسب. .IP إذا كان \fI*write\fP مؤشرًا فارغًا، فسيُتجاهل الإخراج إلى الدفق. .TP \fIcookie_seek_function_t *seek\fP تنفذ هذه الدالة عمليات البحث في الدفق. عند استدعائها، تستقبل ثلاث وسائط: .IP .in +4n .EX int seek(void *cookie, off_t *offset, int whence); .EE .in .IP يحدد الوسيط \fI*offset\fP إزاحة الملف الجديدة اعتمادًا على أي من القيم الثلاث التالية المُقدمة في \fIwhence\fP: .RS .TP \fBSEEK_SET\fP يجب ضبط إزاحة الدفق على \fI*offset\fP بايت من بداية الدفق. .TP \fBSEEK_CUR\fP يجب إضافة \fI*offset\fP إلى إزاحة الدفق الحالية. .TP \fBSEEK_END\fP يجب ضبط إزاحة الدفق على حجم الدفق زائد \fI*offset\fP. .RE .IP قبل الإرجاع، يجب على دالة \fIseek\fP أن تُحدّث \fI*offset\fP للإشارة إلى إزاحة الدفق الجديدة. .IP كنتيجة لدالتها، يجب على دالة \fIseek\fP أن تُرجع 0 عند النجاح، و \-1 عند الخطأ. .IP إذا كان \fI*seek\fP مؤشرًا فارغًا، فمن غير الممكن تنفيذ عمليات بحث على الدفق. .TP \fIcookie_close_function_t *close\fP تغلق هذه الدالة الدفق. يمكن لدالة الخطاف أن تفعل أشياء مثل تحرير المخازن المُخصصة للدفق. عند استدعائها، تستقبل وسيطًا واحدًا: .IP .in +4n .EX int close(void *cookie); .EE .in .IP الوسيط \fIcookie\fP هو الكعكة التي قدمها المبرمج عند استدعاء \fBfopencookie\fP(). .IP كنتيجة لدالتها، يجب على دالة \fIclose\fP أن تُرجع 0 عند النجاح، و \fBEOF\fP عند الخطأ. .IP إذا كان \fI*close\fP NULL، فلن يُنفذ أي إجراء خاص عند إغلاق الدفق. .SH "قيمة الإرجاع" .\" .SH ERRORS .\" It's not clear if errno ever gets set... عند النجاح، تُرجع \fBfopencookie\fP() مؤشرًا إلى التدفق الجديد. عند الخطأ، يُرجع NULL. .SH السمات للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. الواجهة السمة القيمة T{ .na .nh \fBfopencookie\fP() T} سلامة الخيوط MT\-Safe .TE .SH المعايير GNU. .SH أمثلة البرنامج أدناه يُنفذ تدفقًا مخصصًا وظيفته مشابهة (ولكن ليست مطابقة) لتلك المتاحة عبر \fBfmemopen\fP(3). يُنفذ تدفقًا تُخزّن بياناته في مخزن مؤقت للذاكرة. يكتب البرنامج وسائط سطر الأوامر إلى التدفق، ثم يبحث عبر التدفق قارئًا حرفين من كل خمسة أحرف ويكتبها إلى المخرجات القياسية. جلسة الصدفة التالية تُظهر استخدام البرنامج: .P .in +4n .EX $\fB ./a.out \[aq]hello world\[aq]\fP /he/ / w/ /d/ Reached end of file .EE .in .P لاحظ أن نسخة أكثر عمومية من البرنامج أدناه يُمكن تحسينها للتعامل بشكل أكثر متانة مع حالات خطأ متنوعة (مثل، فتح تدفق باستخدام كعكة لديها بالفعل تدفق مفتوح؛ إغلاق تدفق أُغلق بالفعل). .SS "مصدر البرنامج" .\" SRC BEGIN (fopencookie.c) \& .EX #define _GNU_SOURCE #include #include #include #include #include \& #define INIT_BUF_SIZE 4 \& struct memfile_cookie { char *buf; /* Dynamically sized buffer for data */ size_t allocated; /* Size of buf */ size_t endpos; /* Number of characters in buf */ off_t offset; /* Current file offset in buf */ }; \& static ssize_t memfile_write(void *c, const char *buf, size_t size) { char *new_buff; struct memfile_cookie *cookie = c; \& /* Buffer too small? Keep doubling size until big enough. */ \& while (size + cookie\->offset > cookie\->allocated) { new_buff = realloc(cookie\->buf, cookie\->allocated * 2); if (new_buff == NULL) return \-1; cookie\->allocated *= 2; cookie\->buf = new_buff; } \& memcpy(cookie\->buf + cookie\->offset, buf, size); \& cookie\->offset += size; if (cookie\->offset > cookie\->endpos) cookie\->endpos = cookie\->offset; \& return size; } \& static ssize_t memfile_read(void *c, char *buf, size_t size) { ssize_t xbytes; struct memfile_cookie *cookie = c; \& /* Fetch minimum of bytes requested and bytes available. */ \& xbytes = size; if (cookie\->offset + size > cookie\->endpos) xbytes = cookie\->endpos \- cookie\->offset; if (xbytes < 0) /* offset may be past endpos */ xbytes = 0; \& memcpy(buf, cookie\->buf + cookie\->offset, xbytes); \& cookie\->offset += xbytes; return xbytes; } \& static int memfile_seek(void *c, off_t *offset, int whence) { off_t new_offset; struct memfile_cookie *cookie = c; \& if (whence == SEEK_SET) new_offset = *offset; else if (whence == SEEK_END) new_offset = cookie\->endpos + *offset; else if (whence == SEEK_CUR) new_offset = cookie\->offset + *offset; else return \-1; \& if (new_offset < 0) return \-1; \& cookie\->offset = new_offset; *offset = new_offset; return 0; } \& static int memfile_close(void *c) { struct memfile_cookie *cookie = c; \& free(cookie\->buf); cookie\->allocated = 0; cookie\->buf = NULL; \& return 0; } \& int main(int argc, char *argv[]) { cookie_io_functions_t memfile_func = { .read = memfile_read, .write = memfile_write, .seek = memfile_seek, .close = memfile_close }; FILE *stream; struct memfile_cookie mycookie; size_t nread; char buf[1000]; \& /* Set up the cookie before calling fopencookie(). */ \& mycookie.buf = malloc(INIT_BUF_SIZE); if (mycookie.buf == NULL) { perror("malloc"); exit(EXIT_FAILURE); } \& mycookie.allocated = INIT_BUF_SIZE; mycookie.offset = 0; mycookie.endpos = 0; \& stream = fopencookie(&mycookie, "w+", memfile_func); if (stream == NULL) { perror("fopencookie"); exit(EXIT_FAILURE); } \& /* Write command\-line arguments to our file. */ \& for (size_t j = 1; j < argc; j++) if (fputs(argv[j], stream) == EOF) { perror("fputs"); exit(EXIT_FAILURE); } \& /* Read two bytes out of every five, until EOF. */ \& for (long p = 0; ; p += 5) { if (fseek(stream, p, SEEK_SET) == \-1) { perror("fseek"); exit(EXIT_FAILURE); } nread = fread(buf, 1, 2, stream); if (nread == 0) { if (ferror(stream) != 0) { fprintf(stderr, "fread failed\[rs]n"); exit(EXIT_FAILURE); } printf("Reached end of file\[rs]n"); break; } \& printf("/%.*s/\[rs]n", (int) nread, buf); } \& free(mycookie.buf); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH ملاحظات يجب تعريف \fB_FILE_OFFSET_BITS\fP على أنه 64 في الكود الذي يستخدم \fIseek\fP غير فارغ أو الذي يأخذ عنوان \fBfopencookie\fP، إذا كان الكود يُقصد به أن يكون محمولاً إلى منصات x86 و ARM التقليدية ذات 32 بت حيث عرض \fBoff_t\fP المبدئي هو 32 بت. .SH "انظر أيضًا" \fBfclose\fP(3), \fBfmemopen\fP(3), \fBfopen\fP(3), \fBfseek\fP(3) .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .