#include "error_handling.h" #include #include /* for NULL */ #include /* for fprintf */ #include static void print_error(int code, const char * action, const char *dirname, const char *basename, const char * constant, const char * description) { fprintf(stderr, "Error %s(%i) occured when %s \"%s/%s\": %s\n", constant, code, action, dirname, basename ? basename : "", description); } static void default_error(const char ** constant, const char ** description) { *constant = "E???"; *description = "Unknown error"; } static void describe_opendir_error(int code, const char ** constant, const char ** description) { /* http://opengroup.org/onlinepubs/007908799/xsh/opendir.html */ switch (code) { case EACCES: *constant = "EACCES"; *description = "Search permission is denied for the component of the path prefix of dirname or read permission is denied for dirname."; return; case ELOOP: *constant = "ELOOP"; *description = "Too many symbolic links were encountered in resolving path."; return; case ENOENT: *constant = "ENOENT"; *description = "A component of dirname does not name an existing directory or dirname is an empty string."; return; case ENOTDIR: *constant = "ENOTDIR"; *description = "A component of dirname is not a directory."; return; case EMFILE: *constant = "EMFILE"; *description = "{OPEN_MAX} file descriptors are currently open in the calling process. "; return; case ENAMETOOLONG: *constant = "ENAMETOOLONG"; *description = "Pathname resolution of a symbolic link produced an intermediate result whose length exceeds {PATH_MAX}."; return; case ENFILE: *constant = "ENFILE"; *description = "Too many files are currently open in the system."; return; default: default_error(constant, description); return; } assert(0); } static void describe_readdir_error(int code, const char ** constant, const char ** description) { /* http://www.opengroup.org/onlinepubs/009695399/functions/readdir.html */ switch (code) { case EOVERFLOW: *constant = "EOVERFLOW"; *description = "One of the values in the structure to be returned cannot be represented correctly."; return; case EBADF: *constant = "EBADF"; *description = "The dirp argument does not refer to an open directory stream."; return; case ENOENT: *constant = "ENOENT"; *description = "The current position of the directory stream is invalid."; return; default: default_error(constant, description); return; } assert(0); } static void describe_stat_error(int code, const char ** constant, const char ** description) { /* http://www.opengroup.org/onlinepubs/000095399/functions/stat.html */ switch (code) { case EACCES: *constant = "EACCES"; *description = "Search permission is denied for a component of the path prefix."; return; case EIO: *constant = "EIO"; *description = "An error occurred while reading from the file system."; return; case ENOENT: *constant = "ENOENT"; *description = "A component of path does not name an existing file or path is an empty string."; return; case ENOTDIR: *constant = "ENOTDIR"; *description = "A component of the path prefix is not a directory."; return; case ELOOP: *constant = "ELOOP"; *description = "More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument."; return; case ENAMETOOLONG: *constant = "ENAMETOOLONG"; *description = "As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded {PATH_MAX}."; return; case EOVERFLOW: *constant = "EOVERFLOW"; *description = "A value to be stored would overflow one of the members of the stat structure. "; return; default: default_error(constant, description); return; } assert(0); } void handle_opendir_error(int code, const char *dirname) { const char * constant = NULL; const char * description = NULL; describe_opendir_error(code, &constant, &description); print_error(code, "opening", dirname, NULL, constant, description); } void handle_readdir_error(int code, const char *dirname) { const char * constant = NULL; const char * description = NULL; describe_readdir_error(code, &constant, &description); print_error(code, "reading", dirname, NULL, constant, description); } void handle_stat_error(int code, const char *dirname, const char *basename) { const char * constant = NULL; const char * description = NULL; describe_stat_error(code, &constant, &description); print_error(code, "statting", dirname, basename, constant, description); }