### 5.27 `strerror`—convert error number to string

Synopsis

    #include <string.h>
    char *strerror(int errnum);
    char *_strerror_r(struct _reent ptr, int errnum,
        int internal, int *error);

Description
`strerror` converts the error number errnum into a string. The value of errnum is usually a copy of `errno`. If `errnum` is not a known error number, the result points to an empty string.

This implementation of `strerror` prints out the following strings for each of the values defined in ‘`errno.h`’:

`0`

  Success

`E2BIG`

  Arg list too long

`EACCES`

  Permission denied

`EADDRINUSE`

  Address already in use

`EADDRNOTAVAIL`

  Address not available

`EADV`

  Advertise error

`EAFNOSUPPORT`

  Address family not supported by protocol family

`EAGAIN`

  No more processes

`EALREADY`

  Socket already connected

`EBADF`

  Bad file number

`EBADMSG`

  Bad message

`EBUSY`

  Device or resource busy

`ECANCELED`

  Operation canceled

`ECHILD`

  No children

`ECOMM`

  Communication error

`ECONNABORTED`

  Software caused connection abort

`ECONNREFUSED`

  Connection refused

`ECONNRESET`

  Connection reset by peer

`EDEADLK`

  Deadlock

`EDESTADDRREQ`

  Destination address required

`EEXIST`

  File exists

`EDOM`

  Mathematics argument out of domain of function

`EFAULT`

  Bad address

`EFBIG`

  File too large

`EHOSTDOWN`

  Host is down

`EHOSTUNREACH`

  Host is unreachable

`EIDRM`

  Identifier removed

`EILSEQ`

  Illegal byte sequence

`EINPROGRESS`

  Connection already in progress

`EINTR`

  Interrupted system call

`EINVAL`

  Invalid argument

`EIO`

  I/O error

`EISCONN`

  Socket is already connected

`EISDIR`

  Is a directory

`ELIBACC`

  Cannot access a needed shared library

`ELIBBAD`

  Accessing a corrupted shared library

`ELIBEXEC`

  Cannot exec a shared library directly

`ELIBMAX`

  Attempting to link in more shared libraries than system limit

`ELIBSCN`

  `.lib` section in a.out corrupted

`EMFILE`

  File descriptor value too large

`EMLINK`

  Too many links

`EMSGSIZE`

  Message too long

`EMULTIHOP`

  Multihop attempted

`ENAMETOOLONG`

  File or path name too long

`ENETDOWN`

  Network interface is not configured

`ENETRESET`

  Connection aborted by network

`ENETUNREACH`

  Network is unreachable

`ENFILE`

  Too many open files in system

`ENOBUFS`

  No buffer space available

`ENODATA`

  No data

`ENODEV`

  No such device

`ENOENT`

  No such file or directory

`ENOEXEC`

  Exec format error

`ENOLCK`

  No lock

`ENOLINK`

  Virtual circuit is gone

`ENOMEM`

  Not enough space

`ENOMSG`

  No message of desired type

`ENONET`

  Machine is not on the network

`ENOPKG`

  No package

`ENOPROTOOPT`

  Protocol not available

`ENOSPC`

  No space left on device

`ENOSR`

  No stream resources

`ENOSTR`

  Not a stream

`ENOSYS`

  Function not implemented

`ENOTBLK`

  Block device required

`ENOTCONN`

  Socket is not connected

`ENOTDIR`

  Not a directory

`ENOTEMPTY`

  Directory not empty

`ENOTRECOVERABLE`

  State not recoverable

`ENOTSOCK`

  Socket operation on non-socket

`ENOTSUP`

  Not supported

`ENOTTY`

  Not a character device

`ENXIO`

  No such device or address

`EOPNOTSUPP`

  Operation not supported on socket

`EOVERFLOW`

  Value too large for defined data type

`EOWNERDEAD`

  Previous owner died

`EPERM`

  Not owner

`EPIPE`

  Broken pipe

`EPROTO`

  Protocol error

`EPROTOTYPE`

  Protocol wrong type for socket

`EPROTONOSUPPORT`

  Unknown protocol

`ERANGE`

  Result too large

`EREMOTE`

  Resource is remote

`EROFS`

  Read-only file system

`ESHUTDOWN`

  Can’t send after socket shutdown

`ESOCKTNOSUPPORT`

  Socket type not supported

`ESPIPE`

  Illegal seek

`ESRCH`

  No such process

`ESRMNT`

  Srmount error

`ESTRPIPE`

  Strings pipe error

`ETIME`

  Stream ioctl timeout

`ETIMEDOUT`

  Connection timed out

`ETXTBSY`

  Text file busy

`EWOULDBLOCK`

  Operation would block (usually same as EAGAIN)

`EXDEV`

  Cross-device link

`_strerror_r` is a reentrant version of the above.

Returns
This function returns a pointer to a string. Your application must not modify that string.

Portability
ANSI C requires `strerror`, but does not specify the strings used for each error number.

Although this implementation of `strerror` is reentrant (depending on `_user_strerror`), ANSI C declares that subsequent calls to `strerror` may overwrite the result string; therefore portable code cannot depend on the reentrancy of this subroutine.

Although this implementation of `strerror` guarantees a non-null result with a NUL-terminator, some implementations return `NULL` on failure. Although POSIX allows `strerror` to set `errno` to EINVAL on failure, this implementation does not do so (unless you provide `_user_strerror`).

POSIX recommends that unknown errnum result in a message including that value, however it is not a requirement and this implementation does not provide that information (unless you provide `_user_strerror`).

This implementation of `strerror` provides for user-defined extensibility. `errno.h` defines __ELASTERROR, which can be used as a base for user-defined error values. If the user supplies a routine named `_user_strerror`, and errnum passed to `strerror` does not match any of the supported values, `_user_strerror` is called with three arguments. The first is of type int, and is the errnum value unknown to `strerror`. The second is of type int, and matches the internal argument of `_strerror_r`; this should be zero if called from `strerror` and non-zero if called from any other function; `_user_strerror` can use this information to satisfy the POSIX rule that no other standardized function can overwrite a static buffer reused by `strerror`. The third is of type int *, and matches the error argument of `_strerror_r`; if a non-zero value is stored into that location (usually EINVAL), then `strerror` will set `errno` to that value, and the XPG variant of `strerror_r` will return that value instead of zero or ERANGE. `_user_strerror` returns a char * value; returning NULL implies that the user function did not choose to handle errnum. The default `_user_strerror` returns NULL for all input values. Note that `_user_sterror` must be thread-safe, and only denote errors via the third argument rather than modifying `errno`, if `strerror` and `strerror_r` are are to comply with POSIX.

`strerror` requires no supporting OS subroutines.