【问题标题】:How to set errno value?如何设置errno值?
【发布时间】:2012-07-26 19:52:27
【问题描述】:

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

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

  }

}

还有第二种方法:

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

  }

}
  1. 当我将errno 设置为某个值时,它会做什么?只是错误检查?

  2. 如何将上述方法中的errnofunc1func2设置为EEXISTENOENT

谢谢

【问题讨论】:

    标签: c linux error-handling errno


    【解决方案1】:

    出于所有实际目的,您可以将errno 视为一个全局变量(尽管通常不是)。所以包括 errno.h 并使用它:

    errno = ENOENT;
    

    您应该问问自己,errno 是否是最适合您的错误报告机制。函数可以设计为自己返回错误代码吗?

    【讨论】:

    • 通常,errno 用于报告系统错误。你觉得你的库或你的代码是系统的一部分吗?如果没有,请使用其他机制来报告错误。
    • 不一定,像 strtol() 这样的实用函数似乎也返回 ERANGE,例如,这并不是真正的系统错误
    • 一个可能适合设置 errno 的位置示例是在传递给 funopen() 的读取或写入函数回调中。在这种情况下,您的实现应与系统调用(read() 或 write())的约定相匹配,因此在发生错误时返回 -1 并将 errno 设置为特定错误是有意义的。
    • MSVS 定义了errno_t __cdecl _set_errno(_In_ int _Value);_get_errno——它们有什么价值吗?
    • @BasileStarynkevitch,在某些库函数调用之前将 errno 设置为零是通常的做法(例如,请参阅 readdirgetpriority)。在运行时库或程序函数中使用 errno 并没有什么不好。这是标准机制,如果你的函数是扩展一些已经使用 errno 的库函数实现的包装器,为什么你不应该使用 errno。
    【解决方案2】:

    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)
    

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

    【讨论】:

      【解决方案3】:
      #include <errno.h>
      void func1() 
      {
        // do something 
        if (fail) 
        {
          errno = ENOENT;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多