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

移植可能ですか: flags = fcntl(fd, F_GETFL);(注: いいえarg)?

LinuxFreeBSDの両方のマニュアル ページでは、これargは無視されると述べています。

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

voidLinux のドキュメントで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次に、次のように述べています。

F_GETFD、F_SETFD、F_GETFL、および F_SETFL への arg 値はすべて、将来の拡張を可能にするフラグ値を表します。

それは将来的にF_GETFL使用される可能性があることを意味しますか?arg

Ohloh コードで "F_GETFL" をすばやく検索すると、ほとんどのオープンソース プロジェクトが合格argするという印象が生まれます(通常0、場合によってNULLは、または (壊れた?) 場合もあります&fl)。fcntl(fd, F_GETFL, 0)が好ましい形式である理由がわかりません。@Wumpus Q.Wumbleyは、フォームも使用する「UNIX環境での高度なプログラミング」ブックが原因である可能性があることを示唆していfcntl(fd, F_GETFL, 0)ます。

3 番目の引数を必要とするシステム/コンパイラはありflags = fcntl(fd, F_GETFL, 0);ますか? 現在または将来 (準拠した実装を前提として) 異なる結果fcntl(fd, F_GETFL)を生成できますか?fcntl(fd, F_GETFL, 0)

4

3 に答える 3

5

残りの fcntl コマンドを見てください。それらのいくつか (F_DUPFD、F_SETFL など) が、3 番目の引数が何に使用されているかを示していることに注目してください。それらのいずれかを使用する場合は、3 番目の引数を指定する必要があります。F_GETFL または F_GETFD を使用する場合は除きます。

SYNOPSIS では、fcntl が 2 つの引数と a...を取ることがわかります。これは、使用しない場合は 3 番目の引数を省略できることを意味します。

さらに調査を行った後、SYNOPSIS が 3 つの引数すべてが必要であることを暗示している (最初の 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);

ヘッダーで実際にそのように宣言されたという証拠は見つかりませんが、そうである場合、2つの引数のみで呼び出されたときにコンパイルが失敗します。これは、コードに追加の 0 引数を含める十分な理由になります。

私の推測が正しく、これが 3 引数 F_GETFL の歴史的な使用の実際の理由である場合、関数プロトタイプが新しく恐ろしいものであり、OS ベンダーがそれらを誤解していた時代からの役に立たない化石です。

于 2014-07-31T14:52:01.210 に答える
2

FreeBSD ベース システムでは、fcntl(fd, F_GETFL)との両方fcntl(fd, F_GETFL, 0)が使用されます。しかし、ほとんどの場合、3 番目の引数 0 が使用されます。fcntlこれは4.2BSD にさかのぼり、4.4BSD-Lite ソース コードを介して FreeBSD にインポートされたため、歴史的な理由による可能性があります。

4.4BSD (および FreeBSD 2.0) では、実際の古い学校のヘッダーは : ではありません、マニュアル ページには引数が必須:としてリストされていました。int fcntl(int fd, int cmd, int arg)int fcntl(int, int, ...)

その理由については、答えるのが難しいでしょう。原作者に聞いてみる必要があります。しかし、元のソース管理タグには (ユーザー) 名が記録されていないため、それらを追跡する方法がわかりません。

余分な 0 引数は、おそらく FreeBSD コードベースで削除されることはありませんでした。これは、何も壊さず、「修正」するほど重要ではないためです。

于 2014-08-05T10:44:13.303 に答える
2

この 2 つの呼び出し

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

3 番目の可変引数が無視されるため、これらは同等です。fs/fcntl.c:262fs/fcntl.c:269を見ると、arg使用されていないことがわかります。
ただし、何らかの値を設定する必要がある場合は、設定する値を渡す必要があります。ゲッターとセッターに相当する OOP と
考えることができます。fcntl

3 番目の引数が必要なシステムはありますか: flags = fcntl(fd, F_GETFL, 0);?

私は何も知りません。少なくとも、Linux にはありません。ドキュメントには、使用されないため無視されることが明確に記載されていますarg。何かを渡すことができるという事実は、渡す必要があることを意味するものではありません。

fcntl(fd, F_GETFL)一部のシステムで異なる結果を返すことはできます fcntl(fd, F_GETFL, 0)か (過去、現在、および将来 (適合する実装を想定))?

lxrLinux の古いバージョンを掘り下げることができ、1991 年には Linux 2.0.4fcntlが 3 番目の引数に渡されました。これ以上の議論を受け入れる意味はありません。したがって、その 3 番目の引数に意味があるシステムがあるとすれば、それは Linux ではありません。


さらに調査を行ったところ、相反する結果がいくつか見つかりました。ここを見てください: 3つの引数関数としてprotected提案する本がいくつかあります (それらへの直接リンクは掲載していません)。fcntlしかし、少なくともGETFL/に関してGETFDは、 については言及されていませんarg
IMHO、その動作は真剣に受け止められたことはありません。つまり、不思議に思うことです。さらに、その 3 番目の引数を使用することは有害であるとさえ考えます。

私は再び Linux を調べましたが、これらのコマンドの 3 番目の引数は渡されません。

ついに

3 番目の引数 flags = fcntl(fd, F_GETFL, 0); を必要とするシステム/コンパイラはありますか? fcntl(fd, F_GETFL) と fcntl(fd, F_GETFL, 0) は、現在または将来 (準拠した実装を想定) 異なる結果を生成できますか?

未来は謎です。今日、私はそれを除外するのに十分な確信を持っています。でも、昔はそうだったかもしれません

于 2014-07-31T14:59:08.540 に答える