天下有 Linux —— 第一章:那个全局的错误码 errno,我用错了

问题

前些日子在查找网络 Socket 问题时遇到了一个较为特殊的错误打印:errno = 2,该错误码指向的意思是 No such file or directory,那么问题来了…
先看代码片段

#define NET_Debug(fmt, arg...) fprintf(stdout, " %s-%d "fmt" ", __FILE__, __LINE__, ##arg)
...
iHaveRecv = ::recv(m_iSockFd, pMsgBuf, iBufLen, 0);
if (0 > iHaveRecv )
{ 
    NET_Debug("errno = %d, %s\n", errno, strerror(errno));
}
...

上面的代码想要捕获 recv 函数错误的原因,通过 NET_Debug 函数打印错误码 errno,然后进行错误分析,解决问题。但是,该 errno 打印出来的结果与实际却不相符,从而误导了方向。
为何会如此呢?
errno 是 Linux 系统里的一个全局变量,保存最近一次的出错信息代号。因为是全局的,所以他是可能会被其他函数修改的。而上述代码中,fprintf 函数就会修改 errno 的值,从而使得问题的方向被带偏。

解决

正确的写法有两种:
一、出错后立马判断 errno 的值,并进行相应的处理,同时这些处理不会再使用 errno 的值。
二、出错后立马保存 errno 的值(个人喜欢并推荐),使用保存值进行相应的判断与处理。
以下为方法二的一种写法

#define NET_Debug(fmt, arg...) fprintf(stdout, " %s-%d "fmt" ", __FILE__, __LINE__, ##arg)
...
iHaveRecv = ::recv(m_iSockFd, pMsgBuf, iBufLen, 0);
int iTmpErrno = errno;
if (0 > iHaveRecv )
{ 
    NET_Debug("errno = %d, %s\n", iTmpErrno , strerror(iTmpErrno ));
}
...

这个问题对于一般 Linux 新手工程师来说可能都不会意识到吧…
假装陷入沉思中…

齐烟九点 意尽天明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值