20180504

エラー: UNIX プログラムでの errno

【外部リンク】
https://www.ibm.com/developerworks/jp/aix/library/au-errnovariable/index.html
エラー: UNIX プログラムでの errno

標準の errno の値としては、次のようなものがあります。

E2BIG -- 関数に渡される引数リストが長すぎました。
EACCESS -- アクセスが拒否されました。このプログラムを実行しているユーザーは、ファイルやディレクトリーなどへのアクセス権を持っていません。
EAGAIN -- 要求されたリソースが一時的に利用不能です。同じ操作を後で再度行えば、成功するかもしれません。
EBADF -- 関数が、不適切なファイル記述子を使おうとしました (例えば、開いているファイルを参照していない、あるいは、読み取り専用として開かれているファイルに書き込むために使われた、など)。
EBUSY -- 要求されたリソースは利用できません。例えば、別のアプリケーションが読んでいる最中にディレクトリーを削除しようとした、など。EBUSY と EAGAIN との微妙な違いに注意してください。当然ですが、読み取りを行っているプログラムが終了した後なら、そのディレクトリーを削除することができます。
ECHILD -- wait() 関数、または waitpid() 関数が、子プロセスが終了するのを待とうとしましたが、すべての子プロセスは既に終了していました。
EDEADLK -- リクエストが継続されると、リソース・デッドロックが発生します。これは、マルチスレッドのコードで起こるようなデッドロックではないことに注意してください。errno とその仲間では、とてもそうしたデッドロックは追跡できません。
EDOM -- 入力引数が、その数学関数の対象外です。
EEXIST -- ファイルが既に存在し、それが問題です。例えば、パスを付けて mkdir() を呼ぶと、既存のファイルやディレクトリーに名前を付けることになってしまうような場合です。
EFAULT -- 関数の引数の 1 つが、無効なアドレスを参照しています。大部分の実装では、これは検出できません (プログラムは SIGSEGFAULT シグナルを受け取り、終了します)。
EFBIG -- リクエストが、実装で定義された最大のファイルサイズを超えてファイルを拡張しようとしました。これは通常は約 2 GB ですが、最近のほとんどのファイルシステムはずっと大きなファイルをサポートしており、場合によると read()/write() や lseek() などの関数の 64 ビット版が必要になります。
EINTR -- 関数がシグナルに割り込まれ、割り込みはプログラムのシグナル・ハンドラーによってキャッチされ、そしてシグナル・ハンドラーの戻りは正常でした。
EINVAL -- 関数に対して無効な引数を渡しました。
EIO -- I/O エラーが発生しました。これは通常、ハードウェアの問題への反応として生成されます。
EISDIR -- ファイル引数を要求する関数を、ディレクトリー引数を付けて呼びました。
ENFILE -- このプロセスで既に開かれているファイルが多すぎます。各プロセスは OPEN_MAX ファイル記述子を持っており、今ユーザーは (OPEN_MAX + 1) ファイルを開こうとしています。ファイル記述子には、ソケットのようなものもの含まれることに注意してください。
ENLINK -- この関数を呼ぶと、そのファイルは LINK_MAX 以上のリンクを持つことになります。
ENAMETOOLONG -- PATH_MAX よりも長いパス名を作ってしまいました。あるいは、NAME_MAX よりも長いファイル名やディレクトリー名を作ってしまいました。
ENFILE -- このシステムで同時に開いているファイルが多すぎます。これは一時的な状態のはずであり、最近のシステムでは、通常は起こらないはずです。
ENODEV -- そのようなデバイスはありません。あるいは、指定されたデバイスに対して不適切なことを試みようとしています (例えば、大昔のライン・プリンターから読み取ろうとしてはいけません)。
ENOENT -- そのようなファイルは見つかりません。あるいは、指定されたパス名が存在しません。
ENOEXEC -- 実行可能ではないファイルを実行しようとしました。
ENOLCK -- ロックが利用できません。システム全体でのファイル制限、あるいはレコード・ロックに達しました。
ENOMEM -- システムのメモリーが足りなくなりました。従来から、アプリケーションは (そして OS そのものも)、これをうまく扱えません。そのために、特にディスク上のスワップ空間のサイズを動的に増加できないシステムでは、使いそうな RAM 量よりも多くの RAM が必要なのです。
ENOSPC -- デバイス上に空間が残っていません。ユーザーが、既に一杯のデバイスに対して書き込もうとした、あるいはファイルを作成しようとしました。これも同じく、アプリケーションでも OS でもうまく扱えないエラーです。
ENOSYS -- システムは、この関数をサポートしません。例えば、ジョブ・コントロールを持たないシステムに対して setpgid() を呼ぶと、ENOSYS エラーが発生します。
ENOTDIR -- 指定されたパス名はディレクトリーである必要がありますが、そうなっていません。これは EISDIR エラーの逆です。
ENOTEMPTY -- 指定されたディレクトリーが空ではありませんが、空である必要があります。空のディレクトリーでも、「.」 や「..」 などが含まれていることに注意してください。
ENOTTY -- その操作をサポートしていないファイル、あるいは特別なファイルに対して I/O コントロール操作をしようとしました。例えば、ディレクトリーに対してボーレートを設定しようとしてはいけません。
ENXIO -- 存在しないデバイスの特別なファイルに対して I/O リクエストを試みました。
EPERM -- この操作は許可されていません。ユーザーは、指定されたリソースへのアクセス権を持っていません。
EPIPE -- もはや存在しないパイプから読み取ろうとしました、あるいはパイプに書き込もうとしました。パイプ・チェーンの中のプログラムの 1 つが、そのストリーム部分を閉じてしまいました (例えば終了によって)。
ERANGE -- 関数が呼ばれましたが、戻り値は戻り型で表現するには大きすぎます。例えば、ある関数が unsigned char の値を返したものの、結果を 256 以上 (あるいは -1 以下) と計算したとすると、errno は ERANGE に設定され、その関数は無関係な値を返します。こうした場合には、入力データが適切かどうかを調べるか、あるいは関数を呼んだら必ず errno を調べることが重要です。
EROFS -- 読み取り専用のファイルシステム (あるいは読み取り専用モードでマウントされたファイルシステム) に保存されたファイル、あるいはディレクトリーを変更しようとしました。
ESPIPE -- パイプ、あるいは FIFO (First In, First Out) に対してシークしようとしました。
ESRCH -- 無効なプロセス ID、あるいはプロセス・グループを指定しました。
EXDEV -- デバイスにまたがってリンクを移動する操作を行おうとしました。例えば、UNIX ファイルシステムでは、ファイルシステム間でファイルを移動することを許しません (ファイルをコピーし、その後でオリジナルを削除する必要があります)。
POSIX 1003.1 仕様の特徴として気に入らない点は、ノー・エラーの値がないことです。errno が 0 に設定されても、これを標準のシンボリック定数で参照できないこと以外、何も問題が起きません。私は errno.h の中に E_OK や EOK、ENOERROR を持つプラットフォーム上でプログラムしたところ、リスト 4 のようなものを含むコードになってしまいました。こんなことにならないよう、仕様の中でカバーして欲しかったと思います。

リスト 4. no error というエラー値
1
2
3
#if !defined( EOK )
#  define EOK 0         /* no error */
#endif
sys_nerr グローバル変数と strerror() 関数を使うと、システムに組み込まれたエラー・メッセージをすべて出力するコードを簡単に作ることができます (リスト 5)。これによって、使われているシステムがサポートし、実装で定義される (つまり非標準の) 追加の errno 値がすべてダンプされることに注意してください。POSIX 1003.1 準拠のシステムで必要なエラーは、上記にリストしたエラーのみであり、それ以外はすべて「おまけ」です。

リスト 5. エラーのすべてを見せる
1
2
3
4
5
6
7
8
9
// Print out all known errors on the system.
void print_errs( void )
{
    int idx = 0;
   
    for( idx = 0; idx < sys_nerr; idx++ ) {
        printf( "Error #%3d: %s\n", idx, strerror( idx ) );
    }
}
私のシステム (この記事の執筆時では Mac OS X 10.4.7) がサポートする errno 値の完全なリストを見せて皆さんを退屈させるつもりはありませんが、下記は print_errs() 関数の出力のサンプルです (リスト 6)。

リスト 6. 標準のエラー値として取り得る値は大量にあります
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Error #  0: Unknown error: 0
Error #  1: Operation not permitted
Error #  2: No such file or directory
Error #  3: No such process
Error #  4: Interrupted system call
Error #  5: Input/output error
Error #  6: Device not configured
Error #  7: Argument list too long
Error #  8: Exec format error
Error #  9: Bad file descriptor
Error # 10: No child processes
   
Error # 93: Attribute not found
Error # 94: Bad message
Error # 95: EMULTIHOP (Reserved)
Error # 96: No message available on STREAM
Error # 97: ENOLINK (Reserved)
Error # 98: No STREAM resources
Error # 99: Not a STREAM
Error #100: Protocol error
Error #101: STREAM ioctl timeout
Error #102: Operation not supported on socket
--

注目の投稿

cURL error 60: SSL certificate problem: unable to get local issuer certificate

cURL error 60: SSL certificate problem: unable to get local issuer certificate 更新失敗: ダウンロードに失敗しました。 cURL error 60: SSL certificate problem: ...

人気の投稿