Error Handling

来源:互联网 发布:知乐的小说 编辑:程序博客网 时间:2024/04/30 11:20
Programmers should always check the error codes returned by system-level functions. There are many subtle ways that things can go wrong, and it only makes sense to use the status information that the kernel is able to provide us. Unfortunately, programmers are often reluctant to do error checking because it clutters their code, turning a single line of code into a multi-line conditional statement. Error checking is also confusing because different functions indicate errors in different ways.
     To make our code concise and simple to read, we have adopted an approach based on error-handling wrappers that was pioneered by W. Richard Stevens. The idea is that given some base system-level function  foo, we define a wrapper function Foo with identical arguments, but with the first letter capitalized. The wrapper calls the base function and checks for errors. If it detects an error, the wrapper prints an informative message and terminates the process. Otherwise it returns to the caller. Notice that if there are no errors, the wrapper behaves exactly like the base function. Put another way, if a program runs correctly with wrappers, it will run correctly if we render the first letter of each wrapper in lowercase and recompile.
     The systems-level function calls use three different styles for returning errors:Unix-style,Posix-style, and DNS-style. The code for the error-reporting functions is showed below.
void unix_error(char *msg) // Unix-style error {fprintf(stderr, "%s: %s\n", msg, strerror(errno));exit(0);}void posix_error(int code, char *msg) // Posix-style error{fprintf(stderr, "%s: %s\n", msg, strerror(code)); exit(0);}void dns_error(char *msg) // DNS-style error{fprintf(stderr, "%s: %s\n", msg, hstrerror(h_errno)); exit(0);}void app_error(char *msg) // application error{fprintf(stderr, "%s\n", msg); exit(0);}
     Based on the above error-reporting functions, here are some examples of the different error-handling wrappers:
// Wrapper for Unix-style wait functionpid_t Wait(int *status){pid_t pid;if ((pid = wait(status)) < 0)unix_error("Wait error");return pid;}// Wrapper for Unix-style kill function, // unlike Wait, returns void on successvoid Kill(pid_t pid, int signum){int rc;if ((rc = kill(pid, signum)) < 0)unix_error("Kill error");}// Wrapper for Posix-style pthread_detach function, void Pthread_detach(pthread_t tid){int rc;if ((rc = pthread_detach(tid)) != 0)posix_error(rc, "Pthread_detach error");}// Wrapper for DNS-style gethostbyname function, struct hostent *Gethostbyname(const char *name){struct hostent *p;if ((p = gethostbyname(name)) == NULL)dns_error("Gethostbyname error");return p;}
0 0
原创粉丝点击