web-dev-qa-db-ja.com

errnoを設定する必要がありますか?

sendrecvに類似したインターフェースをエクスポートするモジュールを書いています。

これらの関数はそれぞれ送信バイト数と受信バイト数を返すことになっているため、通常のように(つまり、列挙型を使用してニーモニック値を返す)、適切なエラー管理を行うことができません。

このような状況では、標準ライブラリのようにerrnoを設定する必要がありますか?もしそうなら、errnoはスレッド固有なので、それに書き込む特定の方法はありますか、それとも単に値を割り当てることができますか?

編集:実験割り当てによるerrnoの設定が機能していることに気付きました。それでも:これはどのシステムでも安全で移植可能ですか?

42
Dacav

これは少し古いですが、 errno-マニュアルセクション は、マクロであっても直接割り当てることができ、スレッドローカルになることを示しています

34
gbulmer

設定できるのはだけではありませんerrnoを設定できますが、多くの場合、すべきですerrno。一部のライブラリ関数を呼び出すとき、errnoを最初にゼロに設定した場合にのみ確実にエラーを検出できます。 例についてはstrtolを参照

strtolのPOSIX仕様から:

[CX] [オプションの開始] strtol()関数は、成功した場合、errnoの設定を変更しません。

0、{LONG_MIN}または{LLONG_MIN}、および{LONG_MAX}または{LLONG_MAX}は、エラーの場合に返され、成功の場合は有効な戻り値であるため、エラー状況を確認するアプリケーションは、errnoを0に設定してから、strtol()を呼び出す必要があります。またはstrtoll()の場合、errnoを確認してください。 【オプション終了】

18
Dan Moulding

実際、intが返されるため、おそらくcanは(適切に)エラー管理を実行します。

読み取るまたは書き込むバイト数には負でない値を使用し、エラーコードには負の値を使用してください。あなたはhaveを自分自身を-1に制限することはしません:

enum myerrors {
    ERR_NO_MEMORY    = -1,
    ERR_BAD_ARGS     = -2,
    ERR_CPU_EXPLODED = -3,
    // and so on
};

ただし、errnoを希望どおりに設定することは有効です。標準では、errnoは変更可能な左辺値に展開する、つまりユーザーが設定できることを示しています。 C1x/n1425, 7.5 Errors <errno.h>から:

...およびerrnoは、int型の変更可能な左辺値に展開され、その値は、いくつかのライブラリ関数によって正のエラー番号に設定されます。

9
paxdiablo

errnoに値を割り当てるだけですが、状況によってはより適切なエラーを通知する他の方法があることに注意してください。

  1. 読み込まれたバイト数を返さず、代わりにoutput parameterをタイプint *(またはsize_t *または使用するもの)で指定します。その後、エラーコードを返すことができます。
  2. 戻り値の型が符号付きの型であり、送信または受信したバイト数が負の値では意味がない場合、負の値を使用してそれぞれのエラー状態を通知します。
6
Julien Oster

差出人: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm

errnoの移植可能な値は、EDOMERANGEのみです。

これで、移植性に関する質問に答えることができます。

2
prelic

はい、あなたはそれに割り当てることができます、そしてはい、割り当てはスレッドセーフになります。参照 errnoはスレッドセーフですか?

2
Kyle Jones