如何设置errno值?

JAN*_*JAN 29 c linux error-handling errno

我有两种不同方法的调用:

void func1() 
{
  // do something 
  if (fail) 
  {
    // then set errno to EEXIST

  }

}
Run Code Online (Sandbox Code Playgroud)

第二种方法:

void func2() 
{
  // do something 
  if (fail) 
  {
    // then set errno to ENOENT

  }

}
Run Code Online (Sandbox Code Playgroud)
  1. 当我设置errno为某个值时,它会做什么?只是错误检查?

  2. 我怎样才能设置errno在上面的方法func1,并func2以EEXIST和ENOENT

谢谢

cni*_*tar 56

出于所有实际目的,您可以errno像对待全局变量一样对待(尽管通常不会).所以包括errno.h并使用它:

errno = ENOENT;
Run Code Online (Sandbox Code Playgroud)

您应该问自己,errno对于您的目的,是否是最好的错误报告机制.功能是否可以设计为自己返回错误代码?

  • 通常,`errno`用于报告*系统错误*.你觉得你的图书馆或你的代码是系统的一部分吗?如果没有,请使用其他机制报告错误. (15认同)
  • 不一定,像strtol()这样的实用函数似乎也返回ERANGE,例如,它实际上不是_system error_. (3认同)
  • 一个可能适合设置 errno 的示例是在传递给 funopen() 的读或写函数回调中。在这种情况下,您的实现应与系统调用(read() 或 write())的约定匹配,因此在出现错误时返回 -1 并使用特定错误设置 errno 是有意义的。 (3认同)
  • @BasileStarynkevitch,在某些库函数调用之前将 errno 设置为零是通常的做法(例如参见 [​​readdir](http://man7.org/linux/man-pages/man3/readdir.3.html) 或 [getpriority] (http://man7.org/linux/man-pages/man2/getpriority.2.html))。在运行时库或程序函数中使用 errno 没有什么不好。这是标准机制,如果您的函数是扩展一些已经使用 errno 的库函数实现的包装器,那么为什么您不应该使用 errno。 (3认同)

coa*_*nor 9

IMO,errno为系统级设计的标准.我的经验是不污染他们.如果要模拟C标准errno机制,可以执行以下定义:

/* your_errno.c */
__thread int g_your_error_code;

/* your_errno.h */
extern __thread int g_your_error_code
#define set_your_errno(err) (g_your_error_code = (err))
#define your_errno (g_your_error_code)
Run Code Online (Sandbox Code Playgroud)

而且你仍然可以实现your_perror(err_code).更多信息,请参考glibc的实现.


per*_*eal 5

#include <errno.h>
void func1() 
{
  // do something 
  if (fail) 
  {
    errno = ENOENT;
  }
}
Run Code Online (Sandbox Code Playgroud)