سؤال

int fcntl(int fd, int command, ... /* arg */ );

هل هو محمول: flags = fcntl(fd, F_GETFL); (ملحوظة:لا arg)?

كلاهما لينكس و فري بي إس دي صفحات الرجل تقول ذلك arg يتم تجاهل:

F_GETFL (void)
    Get the file access mode and the file status flags; arg
    is ignored.

void في وثائق Linux يعني ذلك arg غير مطلوب.

وهنا أ مثال الاستخدام من POSIX لموضوع ذي صلة F_GETFD علَم:

#include <unistd.h>
#include <fcntl.h>
...
    int flags;


    flags = fcntl(fd, F_GETFD);
    if (flags == -1)
        /* Handle error */;
    flags |= FD_CLOEXEC;
    if (fcntl(fd, F_SETFD, flags) == -1)
        /* Handle error */;"

إنه يظهر أن arg ليس مطلوبا ل F_GETFD (اليوم).ثم يقول:

تمثل قيم ARG إلى F_GETFD و F_SETFD و F_GETFL و F_SETFL قيم العلامة للسماح بالنمو في المستقبل.

هل يدل على ذلك F_GETFL قد تستخدم arg فى المستقبل؟

البحث السريع عن "F_GETFL" على كود Ohloh يخلق انطباعًا بذلك معظم المشاريع مفتوحة المصدر تنجح arg(عادة 0, ، أحيانا NULL, أو حتى (مكسورة؟) &fl).أنا لا أفهم لماذا fcntl(fd, F_GETFL, 0) هو الشكل المفضل. @ومبوس س.يقترح ومبلي أنه قد يكون سببا كتاب "البرمجة المتقدمة في بيئة UNIX". الذي يستخدم أيضا fcntl(fd, F_GETFL, 0) استمارة.

هل هناك نظام/مترجم يتطلب الوسيط الثالث: flags = fcntl(fd, F_GETFL, 0);؟يستطيع fcntl(fd, F_GETFL) و fcntl(fd, F_GETFL, 0) هل تنتج نتائج مختلفة اليوم أم في المستقبل (بافتراض التنفيذ المتوافق)؟

هل كانت مفيدة؟

المحلول

انظر إلى بقية أوامر fcntl.لاحظ كيف أن بعضها (F_DUPFD، F_SETFL، وغيرها) يخبرك بما يتم استخدام الوسيط الثالث فيه.تحتاج إلى تقديم الوسيط الثالث عند استخدام أحد هؤلاء.ليس عند استخدام F_GETFL أو F_GETFD.

في الملخص، يمكنك أن ترى أن fcntl يأخذ وسيطتين بالإضافة إلى a ... مما يعني أنه يمكن حذف الوسيط الثالث عندما لا يتم استخدامه.

بعد إجراء المزيد من البحث، وجدت أن هناك بعض الصفحات القديمة (من وقت APUE الأول تقريبًا) والتي يشير فيها الملخص إلى أن جميع الوسائط الثلاثة مطلوبة.مثال: http://www.freebsd.org/cgi/man.cgi?query=fcntl&manpath=FreeBSD+2.2.7-RELEASE

SYNOPSIS
     #include <fcntl.h>

     int
     fcntl(int fd, int cmd, int arg);

لا يمكنني العثور على أي دليل على أنه تم الإعلان عنه بهذه الطريقة في الرأس، ولكن إذا كان الأمر كذلك، فسيفشل التجميع عندما يتم استدعاؤه باستخدام وسيطتين فقط.سيكون هذا سببًا جيدًا لتضمين الوسيطة 0 الإضافية في التعليمات البرمجية الخاصة بك.

إذا كان تخميني صحيحًا وكان هذا هو السبب الفعلي للاستخدام التاريخي لـ 3-arg F_GETFL، فهو أحفورة عديمة الفائدة من وقت كانت فيه النماذج الأولية للوظائف جديدة ومخيفة وكان بائعو أنظمة التشغيل يخطئون في فهمها.

نصائح أخرى

في النظام الأساسي FreeBSD، كلاهما fcntl(fd, F_GETFL) و fcntl(fd, F_GETFL, 0) يستخدم.ولكن في معظم الحالات يتم استخدام الوسيطة الثالثة 0.قد يكون هذا لأسباب تاريخية منذ ذلك الحين fcntl يعود تاريخه إلى 4.2BSD، وتم استيراده إلى FreeBSD عبر كود المصدر 4.4BSD-Lite.

في 4.4BSD (وFreeBSD 2.0)، أدرجت صفحة الدليل الوسيطة على أنها إلزامي: int fcntl(int fd, int cmd, int arg), ، على الرغم من أن رأس المدرسة القديمة الفعلي يفعل ذلك لا: int fcntl(int, int, ...).

كما هو ل لماذا, ، سيكون من الصعب الإجابة على ذلك.علينا أن نسأل المؤلف (المؤلفين) الأصليين.ولكن نظرًا لعدم وجود أسماء (مستخدمين) مسجلة في علامات التحكم بالمصدر الأصلية، فلن أعرف كيفية تتبعها.

ربما لم تتم إزالة الوسيطة 0 الإضافية مطلقًا في قاعدة بيانات FreeBSD لأنها لا تكسر أي شيء وبالتالي فهي ليست مهمة بما يكفي "لإصلاحها".

هاتين النداءتين

flags = fcntl(fd, F_GETFL);
flags = fcntl(fd, F_GETFL, 0);

متكافئة لأنه تم تجاهل المعلمة المتغيرة الثالثة.إذا ألقيت نظرة على fs/fcntl.c:262 و fs/fcntl.c:269 سترى أن arg هو ليس مستخدما.
ومع ذلك، عندما تحتاج إلى تعيين بعض القيمة، يجب عليك تمرير القيمة التي تريد تعيينها.
هل يمكن أن تنظر fcntl كمعادل OOP للحروف والمستوطنين.

هل هناك نظام يتطلب الوسيط الثالث:الأعلام = fcntl(fd, F_GETFL, 0);؟

أنا لست على علم بأي.لينكس لا يفعل ذلك، على الأقل.تنص الوثائق بوضوح على أنه تم تجاهلها لأنه لن يكون هناك أي فائدة منها arg.حقيقة أنك تستطيع تمرير شيء ما لا تعني أنه يتعين عليك ذلك.

يستطيع fcntl(fd, F_GETFL) و fcntl(fd, F_GETFL, 0) إرجاع نتيجة مختلفة على بعض الأنظمة (في الماضي واليوم وفي المستقبل (بافتراض التنفيذ المطابق))؟

lxr يتيح لنا البحث في الإصدارات الأقدم من Linux وحتى في عام 1991، مع Linux 2.0.4، fcntl مرت على الحجة الثالثة.ليس هناك معنى لقبول أي حجة أخرى.لذلك، إذا كان هناك نظام يكون لهذه الوسيطة الثالثة معنى، فهو ليس Linux بالتأكيد.


لقد أجريت المزيد من الأبحاث ووجدت بعض النتائج المتضاربة.ينظر الى هنا:هناك بعض الكتب (لا أنشر رابطًا مباشرًا لها كما قد تكون protected) التي لا تقترح fcntl كوظيفة ثلاث وسائط.ولكن، على الأقل فيما يتعلق GETFL/GETFD, ، لم يتم ذكر أي شيء عنه arg.
IMHO، لم يتم أخذ سلوكها على محمل الجد أبدًا:وهذا هو، ما الذي يجعلك تتساءل.علاوة على ذلك، فإنني أعتبر أنه من الضار استخدام تلك الحجة الثالثة:ماذا لو كان/سيكون له معنى؟

لقد قمت بمراجعة Linux مرة أخرى، ولم يتم تمرير الوسيطة الثالثة لهذه الأوامر مطلقًا.

أخيراً

هل هناك نظام/مترجم يتطلب الوسيط الثالث:الأعلام = fcntl(fd, F_GETFL, 0);؟هل يمكن لـ fcntl(fd, F_GETFL) وfcntl(fd, F_GETFL, 0) إنتاج نتائج مختلفة اليوم أو في المستقبل (بافتراض التنفيذ المتوافق)؟

المستقبل غامض.اليوم أشعر بما فيه الكفاية من اليقين لاستبعاد ذلك.ومع ذلك، في الماضي ذلك قد لقد كان الأمر كذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top