One of the C language’s universal variables is errno
. It contains a code describing details about why a particular operation failed. You can use errno
in your code to provide better, more informative error messages for your programs.
The codes and constants defined by errno
are listed in the errno.h header file. Click here to see an example of how that file may look. Each compiler may list additional code values, but the core values are consistent from machine to machine, especially for file access.
Not all the codes apply to every library function that uses errno
. For those functions that do, you can find a list of applicable errno
constants in the function’s man page reference. The rename() function lists a host of errno
constants, which you can apply to your code to provide a better error message.
The following example updates last week’s Lesson code to provide more detailed error messages:
#include <stdio.h> #include <errno.h> int main() { int result; result = rename("this.txt","that.txt"); if( result != 0 ) { printf("File renaming error: "); switch(errno) { case EPERM: printf("Operation not permitted\n"); break; case ENOENT: case ENOFILE: printf("File not found\n"); break; case EACCES: printf("Permission denied\n"); break; case ENAMETOOLONG: printf("Filename is too long\n"); break; default: printf("Unknown error\n"); } return(1); } puts("File renamed"); return(0); }
In this code, the errno.h
header file is added (Line 2). If the rename() function fails, the if statement at Line 9 catches it. Line 11 prints a generic error message, but the switch-case structure (Lines 12 to 29) scans common errno
variable values to add more detail.
This code uses defined constants, so I specified both variations on the File not found
constant, ENOENT
and ENOFILE
. The errno.h
header may define one or both. If only one, delete the undefined entry from your code. The errno
value is 2 either way.
Here’s sample output:
File renaming error: File not found
I didn’t include all the potential errno
values for the rename() function in the code’s switch-case structure. Some of the errors are unusual or rare, so I opted for the default in the switch-case structure to catch those errors with an Unknown error
message.
If all this effort seems like too much work, it is! The C language offers yet another function for displaying error messages as well as automatically looking up errno
values. I cover that function in next week’s Lesson.