説明
ヘッダーファイル
<errno.h>
で整数型の変数 errno
が定義されており、
システムコールやいくつかのライブラリ関数は、エラーが発生した際に
この変数にその原因を示す値を設定する。
errno
の値は呼び出しの返り値がエラー
(ほとんどのシステムコールでは
-1
で、ほとんどのライブラリ関数では
-1 か NULL)
を示したときにのみ意味を持つが、関数は成功した場合も
errno
を変更することが「許されている」。どのシステムコールもライブラリ関数も
errno の値を 0
に設定することはない。
いくつかのシステムコールやライブラリ関数
(例えば getpriority(2))
では、成功した場合の有効な返り値として
-1
が返されることがある。
このような場合、成功なのかエラーなのかを区別するためには、
呼び出しの前に errno
を 0
に設定しておけばよい。呼び出しの返り値がエラー発生の可能性を
示すものだった場合には、
errno が 0
以外の値かを見て確認すればよい。
errno は、ISO C standard で int
型の変更可能な左辺値
として定義されており、明示的に宣言を行ってはならない;
errno
はマクロの場合もありえる。
errno
はスレッド毎に値を持つ。
つまりあるスレッドで
errno
が設定されても、
他のスレッドの errno
には影響しない。
エラー番号とエラー名
有効なエラー番号はすべて正の数字である。ヘッダーファイル
<errno.h> で、 errno
で使われる可能性のあるすべてのエラー番号に対してシンボル名が定義されている。
POSIX.1
で定義されているすべてのエラー名には、
それぞれ異なる値が対応していなければならない。
但し、 EAGAIN と EWOULDBLOCK
は例外で、これらは同じ値を持ってもよい。
Linux
では、すべてのアーキテクチャーでこれら二つは同じ値である。
各シンボル名に対応するエラー番号は
UNIX
システムにより異なり、
Linux
ではアーキテクチャーによっても異なっている。したがって、数値は以下のエラー名の一覧には含まれていない。関数
perror(3) と strerror(3)
を使うと、これらの名前を、対応するテキストのエラーメッセージに変換できる。
各 Linux
システムでは、 errno(1)
コマンド (moreutils
パッケージに含まれている)
を使って、すべてのエラーのシンボル名と対応するエラー番号の一覧を取得できる。
$ errno -l
EPERM 1 Operation not permitted
ENOENT 2 No such file or directory
ESRCH 3 No such process
EINTR 4 Interrupted system call
EIO 5 Input/output error
...
errno(1)
コマンドを使うと、個々のエラー番号やエラー名を調べたり、エラーの説明に対する文字列検索でエラーを検索したりできる。以下に例を示す。
$ errno 2
ENOENT 2 No such file or directory
$ errno ESRCH
ESRCH 3 No such process
$ errno -s permission
EACCES 13 Permission denied
エラー名の一覧
以下のエラーのシンボル名の一覧で、シンボル名に付いている注記は以下の通りである。
- POSIX.1-2001: 名前が POSIX.1-2001
とそれ以降のバージョンの
POSIX.1
で定義されている。但し書きがある場合を除く。
- POSIX.1-2008: 名前が POSIX.1-2008
で定義されているが、それ以前の
POSIX.1
標準には存在しない。
- C99: 名前が C99
で定義されている。
以下は Linux
で定義されているエラーのシンボル名の一覧である。
- E2BIG
- 引数リストが長過ぎる
(POSIX.1-2001)
- EACCES
- 許可がない (POSIX.1-2001)
- EADDRINUSE
- アドレスがすでに使用されている
(POSIX.1-2001)
- EADDRNOTAVAIL
- アドレスが使用できない
(POSIX.1-2001)
- EAFNOSUPPORT
- アドレスファミリーがサポートされていない
(POSIX.1-2001)
- EAGAIN
- リソースが一時的に利用不可
(EWOULDBLOCK
と同じ値でもよい)
(POSIX.1-2001)
- EALREADY
- 接続が既に処理中である
(POSIX.1-2001)
- EBADE
- 不正なやり取り (exchange)
である
- EBADF
- ファイルディスクリプターが不正である
(POSIX.1-2001)
- EBADFD
- ファイルディスクリプターが不正な状態である
- EBADMSG
- メッセージが不正である
(POSIX.1-2001)
- EBADR
- 不正なリクエストディスクリプター
- EBADRQC
- 不正なリクエストコード
- EBADSLT
- 不正なスロット
- EBUSY
- リソースが使用中である
(POSIX.1-2001)
- ECANCELED
- 操作がキャンセルされた
(POSIX.1-2001)
- ECHILD
- 子プロセスがない
(POSIX.1-2001)
- ECHRNG
- チャンネル番号が範囲外である
- ECOMM
- 送信時に通信エラーが発生した
- ECONNABORTED
- 接続が異常終了した
(POSIX.1-2001)
- ECONNREFUSED
- 接続が拒否された
(POSIX.1-2001)
- ECONNRESET
- 接続がリセットされた
(POSIX.1-2001)
- EDEADLK
- リソースのデッドロックを回避した
(POSIX.1-2001)
- EDEADLOCK
- ほとんどのアーキテクチャーでは、
EDEADLK
の同義語である。いくつかのアーキテクチャー
(Linux MIPS, PowerPC, SPARC など)
では、別のエラーコード
"File locking deadlock error"
である。
- EDESTADDRREQ
- 宛先アドレスが必要である
(POSIX.1-2001)
- EDOM
- 数学関数で引数が領域外
(out of domain) である (POSIX.1, C99)
- EDQUOT
- ディスククォータ (quota)
を超過した (POSIX.1-2001)
- EEXIST
- ファイルが存在する
(POSIX.1-2001)
- EFAULT
- アドレスが不正である
(POSIX.1-2001)
- EFBIG
- ファイルが大き過ぎる
(POSIX.1-2001)
- EHOSTDOWN
- ホストがダウンしている
- EHOSTUNREACH
- ホストに到達不能である
(POSIX.1-2001)
- EHWPOISON
- メモリーページにハードウェアエラーがある
- EIDRM
- 識別子が削除された
(POSIX.1-2001)
- EILSEQ
- 無効もしくは不完全なマルチバイト文字、ワイド文字である
(POSIX.1, C99).
- ここに表示しているテキストは
glibc
のエラーの説明である。
POSIX.1-2001
では、このエラーの説明は「不正なバイトシーケンス」("Illegal
byte sequence")
となっている。
- EINPROGRESS
- 操作が実行中である
(POSIX.1-2001)
- EINTR
- 関数呼び出しが割り込まれた
(POSIX.1-2001); signal(7) 参照。
- EINVAL
- 引数が無効である
(POSIX.1-2001)
- EIO
- 入出力エラー (POSIX.1-2001)
- EISCONN
- ソケットが接続されている
(POSIX.1-2001)
- EISDIR
- ディレクトリである
(POSIX.1-2001)
- EISNAM
- 名前付きのファイルである
- EKEYEXPIRED
- 鍵が期限切れとなった
- EKEYREJECTED
- 鍵がサーバにより拒否された
- EKEYREVOKED
- 鍵が無効となった
- EL2HLT
- 停止 (レベル 2)
- EL2NSYNC
- 同期できていない
(レベル 2)
- EL3HLT
- 停止 (レベル 3)
- EL3RST
- 停止 (レベル 3)
- ELIBACC
- 必要な共有ライブラリにアクセスできなかった
- ELIBBAD
- 壊れた共有ライブラリにアクセスしようとした
- ELIBMAX
- リンクしようとした共有ライブラリが多過ぎる
- ELIBSCN
- a.out の .lib
セクションが壊れている
(corrupted)
- ELIBEXEC
- 共有ライブラリを直接実行できなかった
- ELNRANGE
- リンク番号が範囲外である
- ELOOP
- シンボリックリンクの回数が多過ぎる
(POSIX.1-2001)
- EMEDIUMTYPE
- 間違ったメディア種別である
- EMFILE
- オープンしているファイルが多過ぎる
(POSIX.1-2001)。 通常は getrlimit(2)
に説明があるリソース上限
RLIMIT_NOFILE
を超過した場合に発生する。
/proc/sys/fs/nr_open
で指定された上限を超過した場合にも発生する。
- EMLINK
- リンクが多過ぎる
(POSIX.1-2001)
- EMSGSIZE
- メッセージが長過ぎる
(POSIX.1-2001)
- EMULTIHOP
- マルチホップ (multihop)
を試みた (POSIX.1-2001)
- ENAMETOOLONG
- ファイル名が長過ぎる
(POSIX.1-2001)
- ENETDOWN
- ネットワークが不通である
(POSIX.1-2001)
- ENETRESET
- 接続がネットワーク側から中止された
(POSIX.1-2001)
- ENETUNREACH
- ネットワークが到達不能である
(POSIX.1-2001)
- ENFILE
- システムでオープンされたファイルが多すぎる
(POSIX.1-2001)。 Linux
では、たいてい
/proc/sys/fs/file-max
上限に達した結果である
(proc(5) を参照)。
- ENOANO
- anode がない
- ENOBUFS
- 使用可能なバッファー空間がない
(POSIX.1 (XSI STREAMS オプション))
- ENODATA
- ストリームの読み出しキューの先頭に読み出し可能なメッセージがない
(POSIX.1-2001)
- ENODEV
- そのようなデバイスはない
(POSIX.1-2001)
- ENOENT
- そのようなファイルやディレクトリはない
(POSIX.1-2001)
- 通常は、このエラーは、指定されたパス名が存在しないか、パス名のディレクトリプレフィックスの構成要素のいずれかが存在しないか、指定されたパス名が壊れた
(dangling)
シンボリックリンク、の場合に発生する。
- ENOEXEC
- 実行ファイル形式のエラー
(POSIX.1-2001)
- ENOKEY
- 要求された鍵が利用できない
- ENOLCK
- 利用できるロックがない
(POSIX.1-2001)
- ENOLINK
- リンクが切れている
(POSIX.1-2001)
- ENOMEDIUM
- メディアが見つからない
- ENOMEM
- 十分な空きメモリー領域がない/メモリを割り当てることができない
(POSIX.1-2001)
- ENOMSG
- 要求された型のメッセージが存在しない
(POSIX.1-2001)
- ENONET
- マシンがネットワーク上にない
- ENOPKG
- パッケージがインストールされていない
- ENOPROTOOPT
- 指定されたプロトコルが利用できない
(POSIX.1-2001)
- ENOSPC
- デバイスに空き領域がない
(POSIX.1-2001)
- ENOSR
- 指定されたストリームリソースが存在しない
(POSIX.1 (XSI STREAMS オプション))
- ENOSTR
- ストリームではない
(POSIX.1 (XSI STREAMS オプション))
- ENOSYS
- 関数が実装されていない
(POSIX.1-2001)
- ENOTBLK
- ブロックデバイスが必要である
- ENOTCONN
- ソケットが接続されていない
(POSIX.1-2001)
- ENOTDIR
- ディレクトリではない
(POSIX.1-2001)
- ENOTEMPTY
- ディレクトリが空ではない
(POSIX.1-2001)
- ENOTRECOVERABLE
- 状態が復元不可能である
(POSIX.1-2008)
- ENOTSOCK
- ソケットではない
(POSIX.1-2001)
- ENOTSUP
- 操作がサポートされていない
(POSIX.1-2001)
- ENOTTY
- I/O
制御操作が適切でない
(POSIX.1-2001)
- ENOTUNIQ
- 名前がネットワークで一意ではない
- ENXIO
- そのようなデバイスやアドレスはない
(POSIX.1-2001)
- EOPNOTSUPP
- ソケットでサポートしていない操作である
(POSIX.1-2001)
- (Linux では ENOTSUP と EOPNOTSUPP
は同じ値を持つが、
POSIX.1
に従えば両者のエラー値は区別されるべきである。)
- EOVERFLOW
- 指定されたデータ型に格納するには値が大き過ぎる
(POSIX.1-2001)
- EOWNERDEAD
- 所有者が死んでいる
(POSIX.1-2008)
- EPERM
- 操作が許可されていない
(POSIX.1-2001)
- EPFNOSUPPORT
- サポートされていないプロトコルファミリーである
- EPIPE
- パイプが壊れている
(POSIX.1-2001)
- EPROTO
- プロトコルエラー
(POSIX.1-2001)
- EPROTONOSUPPORT
- プロトコルがサポートされていない
(POSIX.1-2001)
- EPROTOTYPE
- ソケットに指定できないプロトコルタイプである
(POSIX.1-2001)
- ERANGE
- 結果が大き過ぎる (POSIX.1,
C99)
- EREMCHG
- リモートアドレスが変わった
- EREMOTE
- オブジェクトがリモートにある
- EREMOTEIO
- リモート I/O エラー
- ERESTART
- システムコールが中断され再スタートが必要である
- ERFKILL
- RF-kill
のため操作不可能
- EROFS
- 読み出し専用のファイルシステムである
(POSIX.1-2001)
- ESHUTDOWN
- 通信相手がシャットダウンされて送信できない
- ESPIPE
- 無効なシーク (POSIX.1-2001)
- ESOCKTNOSUPPORT
- サポートされていないソケット種別である
- ESRCH
- そのようなプロセスはない
(POSIX.1-2001)
- ESTALE
- ファイルハンドルが古い状態になっている
(POSIX.1-2001)
- NFS
や他のファイルシステムで起こりうる。
- ESTRPIPE
- ストリームパイプエラー
- ETIME
- 時間が経過した (POSIX.1 (XSI
STREAMS option))
- (POSIX.1 では "STREAM ioctl(2) timeout"
と書かれている)
- ETIMEDOUT
- 操作がタイムアウトした
(POSIX.1-2001)
- ETOOMANYREFS
- 参照が多すぎる:
接合できない
- ETXTBSY
- テキストファイルが使用中である
(POSIX.1-2001)
- EUCLEAN
- データ構造をきれいにする必要がある
- EUNATCH
- プロトコルのドライバが付与
(attach) されていない
- EUSERS
- ユーザー数が多過ぎる
- EWOULDBLOCK
- 操作がブロックされる見込みである
(EAGAIN
と同じ値でもよい)
(POSIX.1-2001)
- EXDEV
- 不適切なリンク
(POSIX.1-2001)
- EXFULL
- 変換テーブルが一杯である
注意
以下はよくやる間違いである。
if (somecall() == -1) {
printf("somecall() failed\n");
if (errno == ...) { ... }
}
このようにすると、参照している時点では
errno はもはや somecall()
から返された値を保持しているとは限らない
(printf(3)
により変更されているかもしれない)。
ライブラリコールをまたいで
errno
の値を保存したい場合は、以下のように保存しなければならない:
if (somecall() == -1) {
int errsv = errno;
printf("somecall() failed\n");
if (errsv == ...) { ... }
}
POSIX スレッド API
は、エラーの場合に
errno
を設定「しない」点に注意すること。代わりに、エラーの場合、関数の結果としてエラー番号が返される。これらのエラー番号は、他の
API で errno
で返されるエラー番号と同じ意味を持つ。
いくつかの古いシステムでは、
<errno.h>
は存在しなかったり、
errno
を定義していなかった。そのため、
errno を手動で (extern int errno
のように)
定義する必要があった。このようなことはしないこと。ずっと以前にこのようにする必要はなくなっており、最近のバージョンの
C
ライブラリでは問題になるからである。
関連項目
errno(1), err(3), error(3), perror(3),
strerror(3)
この文書について
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。