Error Handling

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 function
pid_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 success
void 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值