errno

読み:エラーナンバー
外語:errno 英語
品詞:名詞

C/C++で、直近に発生したエラーの番号を持つint型の変数

目次

C

#include <errno.h>

C++

#include <cerrno>

スレッドセーフ

現在の実装では、errnoはスレッドローカルストレージに保存される。つまり、スレッド毎に値を持っている。あるスレッドでerrnoが設定された時、同じプロセスであっても他のスレッドのerrnoには影響しない。

極めて当然のことだが、マルチスレッドのプログラムは複数のスレッドが並行して動作する。同じプロセスという理由だけで、他のスレッドの動作によりerrnoが勝手に書き換わるようなことがあっては、使い物にならない。そこで、現在ではスレッドセーフになっているのである。

大昔の実装との差

このerrnoを、グローバル変数として説明する書籍等がある。これは、大昔には事実だった。現在はマルチスレッド対応のために、仕様が変わったのである。

マルチスレッドの機能を持っていなかった大昔の伝統的なUNIXでは、errnoはint型でグローバルに宣言された変数だとされていた。そこで、使用する時には次のようなexternを自分で書く必要があった。

extern int errno;

現在では、スレッドセーフになるよう、スレッドごとに独立した値を持つように工夫して実装されており、また<errno.h>というヘッダーファイルも導入されているため、このようなことはしてはいけない。

ユーザー空間

gcc 4.4

Linuxのユーザーランドで、gcc 4.4、glibc-2.11.1のamd64対応64ビット環境の場合、次のように定義されている。

errno.h

extern int errno;

bits/errno.h

extern int *__errno_location (void) __THROW __attribute__ ((__const__));
#define errno (*__errno_location ())

__errno_location()は、Linuxカーネルではなくglibc内に処理がある。

glibc-2.11.1/csu/errno-loc.c

__errno_location (void)
{
  return &errno;
}

glibc-2.11.1/csu/errno.c

__thread int errno;

このようにして、gccでは、errnoは間接的にスレッドローカル変数のint型として定義され、それが返されるようになっている。

Windows

Visual V++ 6.0の場合、include\ERRNO.H などで次のように定義されている。

_CRTIMP extern int * __cdecl _errno(void);
#define errno   (*_errno())

Visual C++ 10.0の場合、include\errno.h とファイル名が小文字になるが、定義内容は全く同じである。

ここで参照している _errno() の定義は不明だが、Windowsでも単なる変数ではなく関数化することでマルチスレッドに対応している。

カーネル空間

FreeBSD

FreeBSDのカーネルの場合、次のように実装されている。

/usr/include/errno.h(シンボリックリンクであり、実体は/usr/include/sys/errno.h)に定義されるerrnoはマクロであり、__errno()を呼び出す。

int * __error(void);
#define errno (* __error())

__errorは、/usr/src/lib/libc/sys/__error.cで定義されている(なお、以前は__error_unthreadedにvoidはなかったが、FreeBSD 9ではvoidが付いている)。

extern int errno;
__weak_reference(__error_unthreaded, __error);
int *
__error_unthreaded(void)
{
    return(&errno);
}

実際のerrno変数は、/usr/src/lib/libc/gen/errno.cで定義されている。

int errno;

スレッドライブラリlibthr用の定義は /usr/src/lib/libthr/sys/thr_error.cにある。

#undef errno
extern  int     errno;
int *
__error(void)
{
    struct pthread *curthread;
    if (_thr_initial != NULL) {
        curthread = _get_curthread();
        if (curthread != NULL && curthread != _thr_initial)
            return (&curthread->error);
    }
    return (&errno);
}

_get_curthread()はカレントのスレッド情報構造体struct pthread *を返す関数で、/usr/src/lib/libc_r/uthread/uthread_kern.cで定義されている。

つまり、マルチスレッド動作時は、スレッド情報構造体からerrnoを取り出す。このためスレッドセーフになっている。

Linux

Linuxカーネルでの errno の定義は不明。

Android Bionic

libc/include/errno.h に定義がある。

extern volatile int*   __errno(void);
#define  errno   (*__errno())

関数は、libc/bionic/__errno.c に定義がある。

volatile int*  __errno( void )
{
  return  &((volatile int*)__get_tls())[TLS_SLOT_ERRNO];
}

TLSはThread Local Storageの略である。

まず、TLS_SLOT_ERRNO はenumであり、2である。

enum {
  TLS_SLOT_SELF = 0, /* The kernel requires this specific slot for x86. */
  TLS_SLOT_THREAD_ID,
  TLS_SLOT_ERRNO,
(コメント略)
  TLS_SLOT_OPENGL_API = 3,
(以下略)

次に、__get_tls() の定義はCPUごとに変わってくるが、KitKat時点で、一般的なARMの場合は次のとおりである。

# define __get_tls() \
    ({ register unsigned int __val; \
       asm ("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \
       (volatile void*) __val; })

armv6k(マルチコア)とarmv7では、cp15がTLSレジスターとなり、ここにTLSの先頭アドレスが格納される。

それ以前のARMアーキテクチャでは、カーネル空間のメモリーアドレス 0xffff0ff0 からにTLSの先頭アドレスを格納しており、__get_tls()は次のような実装であった。

#      define __get_tls() ( *((volatile void **) 0xffff0ff0) )

いずれにしても、Bionicの__get_tls()はシステムコールなどは使わず、直接アドレスを参照する実装になっていることが分かる。

番号の定義

errnoが実際にどのような値であるかは、ユーザー空間であればC/C++コンパイラーごとに異なり、カーネル空間であればOSによって異なる。

このため、値を直接参照するのではなく、#defineされた定数を使うことになる。

FreeBSDカーネル

errnoが実際にどのような値であるかは、OSによって違う。このため、値を直接参照するのではなく、#defineされた定数を使うことになる。

FreeBSD 9の場合、次のように実装されている(最大94まで)。なお、※は_POSIX_SOURCEで除外されるもの。

名称英語の説明意訳
EPERM1Operation not permitted許可されていない操作
ENOENT2No such file or directoryファイルまたはディレクトリが見つからない
ESRCH3No such process指定されたプロセスは存在しない
EINTR4Interrupted system callシグナルに割り込まれた
EIO5Input/output error入出力エラー
ENXIO6Device not configuredデバイスが無いか準備されていない
E2BIG7Argument list too long引数リストが長すぎる
ENOEXEC8Exec format error実行形式が異常
EBADF9Bad file descriptor無効なファイルディスクリプターである
ECHILD10No child processes子プロセスが存在しない
EDEADLK11Resource deadlock avoidedリソースデッドロックを回避した
ENOMEM12Cannot allocate memoryメモリー不足
EACCES13Permission deniedパーミッションがない
EFAULT14Bad addressポインターがユーザーアドレス空間にない
ENOTBLK15※Block device requiredブロックデバイスが必要である
EBUSY16Device busyデバイスまたはリソースは使用中である
EEXIST17File existsファイルは既に存在する
EXDEV18Cross-device linkデバイスをまたぐリンクである
ENODEV19Operation not supported by deviceデバイスが対応していない操作である
ENOTDIR20Not a directoryディレクトリではない
EISDIR21Is a directoryディレクトリである
EINVAL22Invalid argument無効な引数である
ENFILE23Too many open files in systemオープン済ファイル数がシステム上限に達した
EMFILE24Too many open files開いているファイルが多すぎる
ENOTTY25Inappropriate ioctl for deviceデバイスが対応していないioctlである
ETXTBSY26※Text file busyテクストファイルが使用中である
EFBIG27File too largeファイルが大きすぎる
ENOSPC28No space left on deviceデバイスの空き領域が不足
ESPIPE29Illegal seek無効なシーク
EROFS30Read-only filesystemリードオンリーのファイルシステムである
EMLINK31Too many linksリンクの数が多すぎる
EPIPE32Broken pipeソケットはクライアント側で既にcloseされている
math software
EDOM33Numerical argument out of domain数値引数が領域外である
ERANGE34Result too large結果が大き過ぎる
non-blocking and interrupt i/o
EAGAIN35Resource temporarily unavailableリソースが一時的に利用不可
EWOULDBLOCK※Operation would block操作はブロックされる見込みである
EINPROGRESS36※Operation now in progress操作は現在実行中である
EALREADY37※Operation already in progress操作は既に実行中である
ipc/network software -- argument errors
ENOTSOCK38※Socket operation on non-socketソケットではない
EDESTADDRREQ39※Destination address required宛先のアドレスが必要
EMSGSIZE40※Message too longメッセージが長過ぎる
EPROTOTYPE41※Protocol wrong type for socketソケットに指定できないプロトコルタイプである
ENOPROTOOPT42※Protocol not available利用できないプロトコルである
EPROTONOSUPPORT43※Protocol not supported未対応のプロトコルである
ESOCKTNOSUPPORT44※Socket type not supported未対応のソケットタイプである
EOPNOTSUPP45※Operation not supportedソケットが対応していない操作である
ENOTSUP※Operation not supported対応していない操作である
EPFNOSUPPORT46※Protocol family not supported対応していないプロトコルファミリーである
EAFNOSUPPORT47※Address family not supported by protocol family対応していないアドレスファミリーである
EADDRINUSE48※Address already in useアドレスは既に使用されている
EADDRNOTAVAIL49※Can't assign requested addressアドレスが使用できない
ipc/network software -- operational errors
ENETDOWN50※Network is downネットワークは不通である
ENETUNREACH51※Network is unreachableネットワークは到達不能である
ENETRESET52※Network dropped connection on resetリセットでネットワーク接続が失われた
ECONNABORTED53※Software caused connection abortソフトウェア要求により接続は中止された
ECONNRESET54※Connection reset by peer接続は相手からリセットされた
ENOBUFS55※No buffer space availableバッファーは容量不足である
EISCONN56※Socket is already connectedソケットは既に接続されている
ENOTCONN57※Socket is not connectedソケットは接続されていない
ESHUTDOWN58※Can't send after socket shutdownソケットはシャットダウン中であり送信できない
ETOOMANYREFS59※Too many references: can't splice処理限界を超える多重参照である
ETIMEDOUT60※Operation timed out操作はタイムアウトした
ECONNREFUSED61※Connection refused接続は拒否された
ELOOP62※Too many levels of symbolic linksシンボリックリンクの回数が多すぎる
ENAMETOOLONG63File name too longファイル名が長過ぎる
should be rearranged
EHOSTDOWN64※Host is downホストはダウンしている
EHOSTUNREACH65※No route to hostホストに到達不能である
ENOTEMPTY66Directory not emptyディレクトリーが空ではない
quotas & mush
EPROCLIM67※Too many processesプロセスが多すぎる
EUSERS68※Too many usersユーザーが多すぎる
EDQUOT69※Disc quota exceededディスククォータ超過
Network File System
ESTALE70※Stale NFS file handleNFSファイルハンドルが古い
EREMOTE71※Too many levels of remote in pathオブジェクトはリモートにある
EBADRPC72※RPC struct is badRPC構造体は無効である
ERPCMISMATCH73※RPC version wrongRPCバージョンが間違っている
EPROGUNAVAIL74※RPC prog. not availRPCプログラムが利用できない
EPROGMISMATCH75※Program version wrongプログラムのバージョンが合っていない
EPROCUNAVAIL76※Bad procedure for programプログラムでは利用できないprocedureである
ENOLCK77No locks availableロックが利用できない
ENOSYS78Function not implemented関数は実装されていない
EFTYPE79※Inappropriate file type or formatファイルの型または形式が不適切である
EAUTH80※Authentication error認証エラーである
ENEEDAUTH81※Need authenticator認証物が必要である
EIDRM82※Identifier removed識別子は削除された
ENOMSG83※No message of desired type要求された型のメッセージがない
EOVERFLOW84※Value too large to be stored in data typeデータ型に格納するには値が大きすぎる
ECANCELED85※Operation canceled処理はキャンセルされた
EILSEQ86※Illegal byte sequence不正なバイト列である
ENOATTR87※Attribute not found属性がない
EDOOFUS88※Programming errorプログラミングエラーである
EBADMSG89Bad message無効なメッセージである
EMULTIHOP90Multihop attemptedマルチホップが試みられた
ENOLINK91Link has been severedリンクが切断されている
EPROTO92Protocol errorプロトコルエラーである
その他
ENOTCAPABLE93※Capabilities insufficientケーパビリティが不足
ECAPMODE94※Not permitted in capability modeケーパビリティモードでは不許可
ELAST94※Must be equal largest errnoerrnoの最大値
pseudo-errors returned inside kernel to modify return to process
ERESTART(-1)restart syscallシステムコールの再起動が必要
EJUSTRETURN(-2)don't modify regs, just returnレジスターは変更せず、そのまま返却した
ENOIOCTL(-3)ioctl not handled by this layerioctlは、この層で処理されない
EDIRIOCTL(-4)do direct ioctl in GEOMGEOMで直接ioctlを行なう

Linuxカーネル

Linuxの場合、include/asm-generic/errno-base.hで1〜34、それより大きいものがinclude/asm-generic/errno.h、更にカーネル内部専用の512以上がinclude/linux/errno.hで、それぞれ定義されている。BSDやPOSIX仕様と比較して、非常に種類が多いのが特徴である。

errno-base
名称英語の説明意訳
EPERM1Operation not permitted許可されていない操作
ENOENT2No such file or directoryファイルまたはディレクトリが見つからない
ESRCH3No such process指定されたプロセスは存在しない
EINTR4Interrupted system callシグナルに割り込まれた
EIO5I/O error入出力エラー
ENXIO6No such device or addressデバイスまたはアドレスが無い
E2BIG7Argument list too long引数リストが長すぎる
ENOEXEC8Exec format error実行形式が異常
EBADF9Bad file number無効なファイル番号である
ECHILD10No child processes子プロセスが存在しない
EAGAIN11Try again再度実行せよ
EWOULDBLOCKOperation would block操作はブロックされる見込みである
ENOMEM12Out of memoryメモリー不足
EACCES13Permission deniedパーミッションがない
EFAULT14Bad addressポインターがユーザーアドレス空間にない
ENOTBLK15Block device requiredブロックデバイスが必要である
EBUSY16Device or resource busyデバイスまたはリソースは使用中である
EEXIST17File existsファイルは既に存在する
EXDEV18Cross-device linkデバイスをまたぐリンクである
ENODEV19No such deviceデバイスがない
ENOTDIR20Not a directoryディレクトリではない
EISDIR21Is a directoryディレクトリである
EINVAL22Invalid argument無効な引数である
ENFILE23File table overflowオープン済ファイル数がシステム上限に達した
EMFILE24Too many open files開いているファイルが多すぎる
ENOTTY25Not a typewriterTTYではない
ETXTBSY26Text file busyテクストファイルが使用中である
EFBIG27File too largeファイルが大きすぎる
ENOSPC28No space left on deviceデバイスの空き領域が不足
ESPIPE29Illegal seek無効なシーク
EROFS30Read-only file systemリードオンリーのファイルシステムである
EMLINK31Too many linksリンクの数が多すぎる
EPIPE32Broken pipeソケットはクライアント側で既にcloseされている
EDOM33Math argument out of domain of func数値引数が領域外である
ERANGE34Math result not representable結果が大き過ぎる
errno
名称英語の説明意訳
EDEADLK35Resource deadlock would occurリソースデッドロックを回避した
EDEADLOCK
ENAMETOOLONG36File name too longファイル名が長過ぎる
ENOLCK37No record locks available利用できるロックが無い
ENOSYS38Function not implemented関数は実装されていない
ENOTEMPTY39Directory not emptyディレクトリーが空ではない
ELOOP40Too many symbolic links encounteredシンボリックリンクの回数が多すぎる
ENOMSG42No message of desired type要求された型のメッセージがない
EIDRM43Identifier removed識別子は削除された
ECHRNG44Channel number out of rangeチャンネル番号が範囲外である
EL2NSYNC45Level 2 not synchronized同期できていない (レベル2)
EL3HLT46Level 3 halted停止 (レベル3)
EL3RST47Level 3 resetリセット (レベル3)
ELNRNG48Link number out of rangeリンク番号が範囲外である
EUNATCH49Protocol driver not attachedプロトコルドライバがアタッチされていない
ENOCSI50No CSI structure availableCSI構造が利用できない
EL2HLT51Level 2 halted停止 (レベル2)
EBADE52Invalid exchange不正な交換である
EBADR53Invalid request descriptor無効な要求ディスクリプターである
EXFULL54Exchange full変換テーブルがいっぱいである
ENOANO55No anode陰極がない
EBADRQC56Invalid request code不正なリクエストコード
EBADSLT57Invalid slot不正なスロット
EBFONT59Bad font file format不正なフォントファイルフォーマット
ENOSTR60Device not a streamストリームではない
ENODATA61No data availableデータがない
ETIME62Timer expired時間が経過した
ENOSR63Out of streams resourcesストリームリソースが存在しない
ENONET64Machine is not on the network装置がネットワーク上にない
ENOPKG65Package not installedパッケージがインストールされていない
EREMOTE66Object is remoteオブジェクトがリモートにある
ENOLINK67Link has been severedリンクが切れている
EADV68Advertise errorAdvertiseエラー
ESRMNT69Srmount errorSrmountエラー
ECOMM70Communication error on send送信時に通信エラーが発生した
EPROTO71Protocol errorプロトコルエラーである
EMULTIHOP72Multihop attemptedマルチホップが試みられた
EDOTDOT73RFS specific errorRFS特有のエラー
EBADMSG74Not a data messageデータメッセージではない
EOVERFLOW75Value too large for defined data typeデータ型に格納するには値が大きすぎる
ENOTUNIQ76Name not unique on network名前がネットワークで一意ではない
EBADFD77File descriptor in bad stateファイルディスクリプターが不正な状態である
EREMCHG78Remote address changedリモートアドレスが変わった
ELIBACC79Can not access a needed shared library必要な共有ライブラリにアクセスできない
ELIBBAD80Accessing a corrupted shared library壊れた共有ライブラリにアクセスをした
ELIBSCN81.lib section in a.out corrupted.libセクションが壊れている
ELIBMAX82Attempting to link in too many shared librariesリンクしようとした共有ライブラリが多過ぎる
ELIBEXEC83Cannot exec a shared library directly共有ライブラリを直接実行できなかった
EILSEQ84Illegal byte sequence不正なバイト列である
ERESTART85Interrupted system call should be restarted中断システムコールは再起動が必要である
ESTRPIPE86Streams pipe errorストリームパイプエラー
EUSERS87Too many usersユーザー数が多過ぎる
ENOTSOCK88Socket operation on non-socketソケットではない
EDESTADDRREQ89Destination address required宛先のアドレスが必要
EMSGSIZE90Message too longメッセージが長過ぎる
EPROTOTYPE91Protocol wrong type for socketソケットに指定できないプロトコルタイプである
ENOPROTOOPT92Protocol not available利用できないプロトコルである
EPROTONOSUPPORT93Protocol not supported未対応のプロトコルである
ESOCKTNOSUPPORT94Socket type not supported未対応のソケットタイプである
EOPNOTSUPP95Operation not supported on transport endpointトランスポートエンドポイントで未対応の操作
EPFNOSUPPORT96Protocol family not supported対応していないプロトコルファミリーである
EAFNOSUPPORT97Address family not supported by protocol対応していないアドレスファミリーである
EADDRINUSE98Address already in useアドレスは既に使用されている
EADDRNOTAVAIL99Cannot assign requested addressアドレスが使用できない
ENETDOWN100Network is downネットワークは不通である
ENETUNREACH101Network is unreachableネットワークは到達不能である
ENETRESET102Network dropped connection because of resetリセットでネットワーク接続が失われた
ECONNABORTED103Software caused connection abortソフトウェア要求により接続は中止された
ECONNRESET104Connection reset by peer接続は相手からリセットされた
ENOBUFS105No buffer space availableバッファーは容量不足である
EISCONN106Transport endpoint is already connectedトランスポートエンドポイントは既に接続されている
ENOTCONN107Transport endpoint is not connectedトランスポートエンドポイントは接続されていない
ESHUTDOWN108Cannot send after transport endpoint shutdownトランスポートエンドポイントはシャットダウン中であり送信できない
ETOOMANYREFS109Too many references: cannot splice処理限界を超える多重参照である
ETIMEDOUT110Connection timed out操作はタイムアウトした
ECONNREFUSED111Connection refused接続は拒否された
EHOSTDOWN112Host is downホストはダウンしている
EHOSTUNREACH113No route to hostホストに到達不能である
EALREADY114Operation already in progress操作は既に実行中である
EINPROGRESS115Operation now in progress操作は現在実行中である
ESTALE116Stale NFS file handleNFSファイルハンドルが古い
EUCLEAN117Structure needs cleaning構造のクリーニングが必要
ENOTNAM118Not a XENIX named type fileXENIX名前付きファイルではない
ENAVAIL119No XENIX semaphores availableXENIXセマフォは利用できない
EISNAM120Is a named type file名前付きファイルである
EREMOTEIO121Remote I/O errorリモートI/Oエラー
EDQUOT122Quota exceededクォータ超過
ENOMEDIUM123No medium foundメディアが見つからない
EMEDIUMTYPE124Wrong medium type間違ったメディアタイプである
ECANCELED125Operation Canceled処理はキャンセルされた
ENOKEY126Required key not available要求された鍵が利用できない
EKEYEXPIRED127Key has expired鍵の期限が切れた
EKEYREVOKED128Key has been revoked鍵が無効となった
EKEYREJECTED129Key was rejected by service鍵がサーバーにより拒否された
robust mutexes
EOWNERDEAD130Owner died元のmutex所有者は既に終了した
ENOTRECOVERABLE131State not recoverable状態は回復不能
ERFKILL132Operation not possible due to RF-killRF-killのため操作できない
用語の所属
変数 (プログラミング)
関連する用語
int
errno_t
シグナル (イベント)

コメントなどを投稿するフォームは、日本語対応時のみ表示されます


KisoDic通信用語の基礎知識検索システム WDIC Explorer Version 7.04a (27-May-2022)
Search System : Copyright © Mirai corporation
Dictionary : Copyright © WDIC Creators club