8

通常 open()、新しいファイル記述子を返します。エラーが発生した場合は-1を返し、その場合errnoは適切に設定されます。

なぜこのメカニズムがerrnoここで使用されているのか理解できませんか?ここの目的は何ですか?なぜ、すべてのエラーを負のリターンnoでマップできないのですか?

お気に入り

fd = open("/dev/tty0", O_RDWR | O_SYNC);
if(fd == -1)
  printf("this is EACCES error");
else if (fd == -2)
    printf("this is EPERM error");

メカニズムのメリットはありerrno ますか?はいの場合、私は知りたい/理解したいので、他のことでもこのメカニズムを使用できます。

4

4 に答える 4

12

fopenを返すのでFILE*、そのポインタでエラーコードを返すことは期待できません。ポインタの「特別な」値は。だけです0

ご存知のように、openこの制限は当てはまりません。実際、Linuxのようなシステムは、あなたが提案したことをより低いレベルで正確に実行します。内部のシステムコールは、問題が発生した場合に負のエラーコードを返します。次に、その(否定された)コードはerrno、浅いユーザースペースラッパーによってプラグインされ-1、アプリケーションにエラーを示すためにを返します。

これが行われる理由は、純粋に歴史的なものです。古き良き時代には、スレッド化はなくerrno、単純なグローバル変数でした。当時、選択された戦略はそれほどオーバーヘッドがかからず、おそらくOSとアプリケーションの間で通信するための許容できる方法のようでした。このようなインターフェースは基本的に多くのコードを壊さずに変更することはできないため、errnoスレッドローカルである疑似変数として固執します。

これは理想的ではありませんが、これらは明らかに例外的にのみ発生するはずのエラー表示であるため、オーバーヘッドは思ったほど悪くはありません。

于 2012-07-10T12:52:47.730 に答える
9

私にとっての利点は、エラー情報の取得がそのように統一されていることです。負の値をopen返すと、整数がfopen返されるFILE *ので問題なく機能しますが、返されるので、そこで別の手法を使用する必要があります。

于 2012-07-10T12:35:12.673 に答える
1

errnoエラーコードです。エラーを実際に起こっていることにマッピングして、次に何をすべきかについてコードで戦略的な決定を下せるようにすることが重要です。たとえば、ERANGEで定義されてerrno.hいるは、の結果がstrtol("0xfffffffff",NULL,0)その関数の範囲外であることを示します。さらに重要なのは、あなたの例では、ファイルの処理方法を知っているので、エラーがあるEACCESかどうかを知ることは良いことです。EPERM

キャッチして処理したい複数の問題が発生する可能性があるため、1つのエラーコードですべての問題をマッピングすることはできません。私がキャッチと言うとき、私はトライ/キャッチを意味するのではありません。

errnoを使用すると、エラー処理メカニズムが確立されるため、-1だけでなくより多くの情報を取得できます。

ERANGE、EACCES、EPERMなどは、便宜上、特定のエラー番号にマップされるマクロと見なされます。

于 2012-07-10T12:34:19.787 に答える
1

各関数に個別の戻り値のセットを与えると、一般的な方法でコードを記述することが非常に複雑になります。現在のセマンティクスでは、ユニバーサルパターンを採用できます。

int fd;
if ((fd = some_function(arg1, arg2)) == -1)
{
    perror("some_function");
    exit(1);
}

これをマクロでラップすることもできます。

#define CALL_OR_DIE(function, ret, ...)      \
    if ((ret = function(__VA_ARGS__)) == -1) \
    { perror(#function); exit(1); }

使用法:

int fd;
CALL_OR_DIE(open, fd, "/dev/tty0", O_RDWR | O_SYNC);
于 2012-07-10T12:49:11.330 に答える