Error Handling in C programs using errno, perror and strerror

The perror() function produces a message on standard error describing the last error encountered during a call to a system or library function.
When a system call fails, it usually returns -1 and sets the variable errno to a value describing what went wrong. (These values can be found in .) Many library functions do likewise. The function perror() serves to translate this error code into human-readable form.

If we write a simple program to demonstrate this, it could be as following,

#include <stdio.h>
#include <errno.h>
 
int main(int argc, char **argv) {
        FILE *fp = NULL;
        fp = fopen("this_is_perror_test.txt", "r");
        if (fp == NULL) {
                perror("fopen");
        }
        return 0;
}

OR this same program can also be written using strerror as,

[bash]
#include <stdio.h>
#include <errno.h>
#include <string.h>
 
int main(int argc, char **argv) {
        FILE *fp = NULL;
        fp = fopen("this_is_perror_test.txt", "r");
        if (fp == NULL) {
                fprintf(stderr, "fopen: %s\n", strerror(errno));
        }
        return 0;
}
 $ gcc -o simple_perror simple_perror.c 

If we run the program now as,

$./simple_perror 
fopen: No such file or directory 

Above program show, how an error number of ENOENT gets automatically assigned as error code and perror prints human readable message as “No such file or directory”

Below program shows some of the other probable error codes and messages as,

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {
	int i=0;
	for (i=1; i&lt;=133; i++) {
		errno = i;
		switch (i) {
			case EPERM: perror("EPERM"); break;
			case ENOENT: perror("ENOENT"); break;
			case ESRCH: perror("ESRCH"); break;
			case EINTR: perror("EINTR"); break;
			case EIO: perror("EIO"); break;
			case ENXIO: perror("ENXIO"); break;
			case E2BIG: perror("E2BIG"); break;
			case ENOEXEC: perror("ENOEXEC"); break;
			case EBADF: perror("EBADF"); break;
			case ECHILD: perror("ECHILD"); break;
			case EAGAIN: perror("EAGAIN"); break;
			case ENOMEM: perror("ENOMEM"); break;
			case EACCES: perror("EACCES"); break;
			case EFAULT: perror("EFAULT"); break;
			case ENOTBLK: perror("ENOTBLK"); break;
			case EBUSY: perror("EBUSY"); break;
			case EEXIST: perror("EEXIST"); break;
			case EXDEV: perror("EXDEV"); break;
			case ENODEV: perror("ENODEV"); break;
			case ENOTDIR: perror("ENOTDIR"); break;
			case EISDIR: perror("EISDIR"); break;
			case EINVAL: perror("EINVAL"); break;
			case ENFILE: perror("ENFILE"); break;
			case EMFILE: perror("EMFILE"); break;
			case ENOTTY: perror("ENOTTY"); break;
			case ETXTBSY: perror("ETXTBSY"); break;
			case EFBIG: perror("EFBIG"); break;
			case ENOSPC: perror("ENOSPC"); break;
			case ESPIPE: perror("ESPIPE"); break;
			case EROFS: perror("EROFS"); break;
			case EMLINK: perror("EMLINK"); break;
			case EPIPE: perror("EPIPE"); break;
			case EDOM: perror("EDOM"); break;
			case ERANGE: perror("ERANGE"); break;
			case EDEADLK: perror("EDEADLK"); break;
			case ENAMETOOLONG: perror("ENAMETOOLONG"); break;
			case ENOLCK: perror("ENOLCK"); break;
			case ENOSYS: perror("ENOSYS"); break;
			case ENOTEMPTY: perror("ENOTEMPTY"); break;
			case ELOOP: perror("ELOOP"); break;
			case ENOMSG: perror("ENOMSG"); break;
			case EIDRM: perror("EIDRM"); break;
			case ECHRNG: perror("ECHRNG"); break;
			case EL2NSYNC: perror("EL2NSYNC"); break;
			case EL3HLT: perror("EL3HLT"); break;
			case EL3RST: perror("EL3RST"); break;
			case ELNRNG: perror("ELNRNG"); break;
			case EUNATCH: perror("EUNATCH"); break;
			case ENOCSI: perror("ENOCSI"); break;
			case EL2HLT: perror("EL2HLT"); break;
			case EBADE: perror("EBADE"); break;
			case EBADR: perror("EBADR"); break;
			case EXFULL: perror("EXFULL"); break;
			case ENOANO: perror("ENOANO"); break;
			case EBADRQC: perror("EBADRQC"); break;
			case EBADSLT: perror("EBADSLT"); break;
			case EBFONT: perror("EBFONT"); break;
			case ENOSTR: perror("ENOSTR"); break;
			case ENODATA: perror("ENODATA"); break;
			case ETIME: perror("ETIME"); break;
			case ENOSR: perror("ENOSR"); break;
			case ENONET: perror("ENONET"); break;
			case ENOPKG: perror("ENOPKG"); break;
			case EREMOTE: perror("EREMOTE"); break;
			case ENOLINK: perror("ENOLINK"); break;
			case EADV: perror("EADV"); break;
			case ESRMNT: perror("ESRMNT"); break;
			case ECOMM: perror("ECOMM"); break;
			case EPROTO: perror("EPROTO"); break;
			case EMULTIHOP: perror("EMULTIHOP"); break;
			case EDOTDOT: perror("EDOTDOT"); break;
			case EBADMSG: perror("EBADMSG"); break;
			case EOVERFLOW: perror("EOVERFLOW"); break;
			case ENOTUNIQ: perror("ENOTUNIQ"); break;
			case EBADFD: perror("EBADFD"); break;
			case EREMCHG: perror("EREMCHG"); break;
			case ELIBACC: perror("ELIBACC"); break;
			case ELIBBAD: perror("ELIBBAD"); break;
			case ELIBSCN: perror("ELIBSCN"); break;
			case ELIBMAX: perror("ELIBMAX"); break;
			case ELIBEXEC: perror("ELIBEXEC"); break;
			case EILSEQ: perror("EILSEQ"); break;
			case ERESTART: perror("ERESTART"); break;
			case ESTRPIPE: perror("ESTRPIPE"); break;
			case EUSERS: perror("EUSERS"); break;
			case ENOTSOCK: perror("ENOTSOCK"); break;
			case EDESTADDRREQ: perror("EDESTADDRREQ"); break;
			case EMSGSIZE: perror("EMSGSIZE"); break;
			case EPROTOTYPE: perror("EPROTOTYPE"); break;
			case ENOPROTOOPT: perror("ENOPROTOOPT"); break;
			case EPROTONOSUPPORT: perror("EPROTONOSUPPORT"); break;
			case ESOCKTNOSUPPORT: perror("ESOCKTNOSUPPORT"); break;
			case EOPNOTSUPP: perror("EOPNOTSUPP"); break;
			case EPFNOSUPPORT: perror("EPFNOSUPPORT"); break;
			case EAFNOSUPPORT: perror("EAFNOSUPPORT"); break;
			case EADDRINUSE: perror("EADDRINUSE"); break;
			case EADDRNOTAVAIL: perror("EADDRNOTAVAIL"); break;
			case ENETDOWN: perror("ENETDOWN"); break;
			case ENETUNREACH: perror("ENETUNREACH"); break;
			case ENETRESET: perror("ENETRESET"); break;
			case ECONNABORTED: perror("ECONNABORTED"); break;
			case ECONNRESET: perror("ECONNRESET"); break;
			case ENOBUFS: perror("ENOBUFS"); break;
			case EISCONN: perror("EISCONN"); break;
			case ENOTCONN: perror("ENOTCONN"); break;
			case ESHUTDOWN: perror("ESHUTDOWN"); break;
			case ETOOMANYREFS: perror("ETOOMANYREFS"); break;
			case ETIMEDOUT: perror("ETIMEDOUT"); break;
			case ECONNREFUSED: perror("ECONNREFUSED"); break;
			case EHOSTDOWN: perror("EHOSTDOWN"); break;
			case EHOSTUNREACH: perror("EHOSTUNREACH"); break;
			case EALREADY: perror("EALREADY"); break;
			case EINPROGRESS: perror("EINPROGRESS"); break;
			case ESTALE: perror("ESTALE"); break;
			case EUCLEAN: perror("EUCLEAN"); break;
			case ENOTNAM: perror("ENOTNAM"); break;
			case ENAVAIL: perror("ENAVAIL"); break;
			case EISNAM: perror("EISNAM"); break;
			case EREMOTEIO: perror("EREMOTEIO"); break;
			case EDQUOT: perror("EDQUOT"); break;
			case ENOMEDIUM: perror("ENOMEDIUM"); break;
			case EMEDIUMTYPE: perror("EMEDIUMTYPE"); break;
			case ECANCELED: perror("ECANCELED"); break;
			case ENOKEY: perror("ENOKEY"); break;
			case EKEYEXPIRED: perror("EKEYEXPIRED"); break;
			case EKEYREVOKED: perror("EKEYREVOKED"); break;
			case EKEYREJECTED: perror("EKEYREJECTED"); break;
			case EOWNERDEAD: perror("EOWNERDEAD"); break;
			case ENOTRECOVERABLE: perror("ENOTRECOVERABLE"); break;
			case ERFKILL: perror("ERFKILL"); break;
			case EHWPOISON: perror("EHWPOISON"); break;
		}
	}
	return 0;
}

compile the program as,

 $ gcc -o perror_errno_description perror_errno_description.c 
 $ ./perror_errno_description 

The output of above execution will display the error number and its related meaningful description as,

EPERM: Operation not permitted
ENOENT: No such file or directory
ESRCH: No such process
EINTR: Interrupted system call
EIO: Input/output error
ENXIO: No such device or address
E2BIG: Argument list too long
ENOEXEC: Exec format error
EBADF: Bad file descriptor
ECHILD: No child processes
EAGAIN: Resource temporarily unavailable
ENOMEM: Cannot allocate memory
EACCES: Permission denied
EFAULT: Bad address
ENOTBLK: Block device required
EBUSY: Device or resource busy
EEXIST: File exists
EXDEV: Invalid cross-device link
ENODEV: No such device
ENOTDIR: Not a directory
EISDIR: Is a directory
EINVAL: Invalid argument
ENFILE: Too many open files in system
EMFILE: Too many open files
ENOTTY: Inappropriate ioctl for device
ETXTBSY: Text file busy
EFBIG: File too large
ENOSPC: No space left on device
ESPIPE: Illegal seek
EROFS: Read-only file system
EMLINK: Too many links
EPIPE: Broken pipe
EDOM: Numerical argument out of domain
ERANGE: Numerical result out of range
EDEADLK: Resource deadlock avoided
ENAMETOOLONG: File name too long
ENOLCK: No locks available
ENOSYS: Function not implemented
ENOTEMPTY: Directory not empty
ELOOP: Too many levels of symbolic links
ENOMSG: No message of desired type
EIDRM: Identifier removed
ECHRNG: Channel number out of range
EL2NSYNC: Level 2 not synchronized
EL3HLT: Level 3 halted
EL3RST: Level 3 reset
ELNRNG: Link number out of range
EUNATCH: Protocol driver not attached
ENOCSI: No CSI structure available
EL2HLT: Level 2 halted
EBADE: Invalid exchange
EBADR: Invalid request descriptor
EXFULL: Exchange full
ENOANO: No anode
EBADRQC: Invalid request code
EBADSLT: Invalid slot
EBFONT: Bad font file format
ENOSTR: Device not a stream
ENODATA: No data available
ETIME: Timer expired
ENOSR: Out of streams resources
ENONET: Machine is not on the network
ENOPKG: Package not installed
EREMOTE: Object is remote
ENOLINK: Link has been severed
EADV: Advertise error
ESRMNT: Srmount error
ECOMM: Communication error on send
EPROTO: Protocol error
EMULTIHOP: Multihop attempted
EDOTDOT: RFS specific error
EBADMSG: Bad message
EOVERFLOW: Value too large for defined data type
ENOTUNIQ: Name not unique on network
EBADFD: File descriptor in bad state
EREMCHG: Remote address changed
ELIBACC: Can not access a needed shared library
ELIBBAD: Accessing a corrupted shared library
ELIBSCN: .lib section in a.out corrupted
ELIBMAX: Attempting to link in too many shared libraries
ELIBEXEC: Cannot exec a shared library directly
EILSEQ: Invalid or incomplete multibyte or wide character
ERESTART: Interrupted system call should be restarted
ESTRPIPE: Streams pipe error
EUSERS: Too many users
ENOTSOCK: Socket operation on non-socket
EDESTADDRREQ: Destination address required
EMSGSIZE: Message too long
EPROTOTYPE: Protocol wrong type for socket
ENOPROTOOPT: Protocol not available
EPROTONOSUPPORT: Protocol not supported
ESOCKTNOSUPPORT: Socket type not supported
EOPNOTSUPP: Operation not supported
EPFNOSUPPORT: Protocol family not supported
EAFNOSUPPORT: Address family not supported by protocol
EADDRINUSE: Address already in use
EADDRNOTAVAIL: Cannot assign requested address
ENETDOWN: Network is down
ENETUNREACH: Network is unreachable
ENETRESET: Network dropped connection on reset
ECONNABORTED: Software caused connection abort
ECONNRESET: Connection reset by peer
ENOBUFS: No buffer space available
EISCONN: Transport endpoint is already connected
ENOTCONN: Transport endpoint is not connected
ESHUTDOWN: Cannot send after transport endpoint shutdown
ETOOMANYREFS: Too many references: cannot splice
ETIMEDOUT: Connection timed out
ECONNREFUSED: Connection refused
EHOSTDOWN: Host is down
EHOSTUNREACH: No route to host
EALREADY: Operation already in progress
EINPROGRESS: Operation now in progress
ESTALE: Stale file handle
EUCLEAN: Structure needs cleaning
ENOTNAM: Not a XENIX named type file
ENAVAIL: No XENIX semaphores available
EISNAM: Is a named type file
EREMOTEIO: Remote I/O error
EDQUOT: Disk quota exceeded
ENOMEDIUM: No medium found
EMEDIUMTYPE: Wrong medium type
ECANCELED: Operation canceled
ENOKEY: Required key not available
EKEYEXPIRED: Key has expired
EKEYREVOKED: Key has been revoked
EKEYREJECTED: Key was rejected by service
EOWNERDEAD: Owner died
ENOTRECOVERABLE: State not recoverable
ERFKILL: Operation not possible due to RF-kill
EHWPOISON: Memory page has hardware error

Leave a Comment