在可能的多线程环境中的Errno描述

时间:2015-12-10 13:25:06

标签: c linux multithreading

http://linux.die.net/man/3/strerror_r

这些功能很奇怪。为什么我不能简单地获得一个指向字符串文字(const char*)的指针并完成它?

为什么要乱用一个隐藏的静态缓冲区来创建线程和信号问题,或者用户分配的缓冲区你猜哪个好大小是因为你不知道而且手册页不会告诉你?

我还没有得到什么? 简单的线程是不相关的strerror实现,例如?:

,这有什么问题
#include <errno.h>
#define E(n,s) case n: return s;
const char* strerror(int n){
  switch(n){
    //stole these messages from libc
    E(EILSEQ,       "Illegal byte sequence")
    E(EDOM,         "Domain error")
    E(ERANGE,       "Result not representable")

    E(ENOTTY,       "Not a tty")
    E(EACCES,       "Permission denied")
    E(EPERM,        "Operation not permitted")
    E(ENOENT,       "No such file or directory")
    E(ESRCH,        "No such process")
    E(EEXIST,       "File exists")

    E(EOVERFLOW,    "Value too large for data type")
    E(ENOSPC,       "No space left on device")
    E(ENOMEM,       "Out of memory")

    E(EBUSY,        "Resource busy")
    E(EINTR,        "Interrupted system call")
    E(EAGAIN,       "Resource temporarily unavailable")
    E(ESPIPE,       "Invalid seek")

    E(EXDEV,        "Cross-device link")
    E(EROFS,        "Read-only file system")
    E(ENOTEMPTY,    "Directory not empty")

    E(ECONNRESET,   "Connection reset by peer")
    E(ETIMEDOUT,    "Operation timed out")
    E(ECONNREFUSED, "Connection refused")
    E(EHOSTDOWN,    "Host is down")
    E(EHOSTUNREACH, "Host is unreachable")
    E(EADDRINUSE,   "Address in use")

    E(EPIPE,        "Broken pipe")
    E(EIO,          "I/O error")
    E(ENXIO,        "No such device or address")
    E(ENOTBLK,      "Block device required")
    E(ENODEV,       "No such device")
    E(ENOTDIR,      "Not a directory")
    E(EISDIR,       "Is a directory")
    E(ETXTBSY,      "Text file busy")
    E(ENOEXEC,      "Exec format error")

    E(EINVAL,       "Invalid argument")

    E(E2BIG,        "Argument list too long")
    E(ELOOP,        "Symbolic link loop")
    E(ENAMETOOLONG, "Filename too long")
    E(ENFILE,       "Too many open files in system")
    E(EMFILE,       "No file descriptors available")
    E(EBADF,        "Bad file descriptor")
    E(ECHILD,       "No child process")
    E(EFAULT,       "Bad address")
    E(EFBIG,        "File too large")
    E(EMLINK,       "Too many links")
    E(ENOLCK,       "No locks available")

    E(EDEADLK,      "Resource deadlock would occur")
    E(ENOTRECOVERABLE, "State not recoverable")
    E(EOWNERDEAD,   "Previous owner died")
    E(ECANCELED,    "Operation canceled")
    E(ENOSYS,       "Function not implemented")
    E(ENOMSG,       "No message of desired type")
    E(EIDRM,        "Identifier removed")
    E(ENOSTR,       "Device not a stream")
    E(ENODATA,      "No data available")
    E(ETIME,        "Device timeout")
    E(ENOSR,        "Out of streams resources")
    E(ENOLINK,      "Link has been severed")
    E(EPROTO,       "Protocol error")
    E(EBADMSG,      "Bad message")
    E(EBADFD,       "File descriptor in bad state")
    E(ENOTSOCK,     "Not a socket")
    E(EDESTADDRREQ, "Destination address required")
    E(EMSGSIZE,     "Message too large")
    E(EPROTOTYPE,   "Protocol wrong type for socket")
    E(ENOPROTOOPT,  "Protocol not available")
    E(EPROTONOSUPPORT,"Protocol not supported")
    E(ESOCKTNOSUPPORT,"Socket type not supported")
    E(ENOTSUP,      "Not supported")
    E(EPFNOSUPPORT, "Protocol family not supported")
    E(EAFNOSUPPORT, "Address family not supported by protocol")
    E(EADDRNOTAVAIL,"Address not available")
    E(ENETDOWN,     "Network is down")
    E(ENETUNREACH,  "Network unreachable")
    E(ENETRESET,    "Connection reset by network")
    E(ECONNABORTED, "Connection aborted")
    E(ENOBUFS,      "No buffer space available")
    E(EISCONN,      "Socket is connected")
    E(ENOTCONN,     "Socket not connected")
    E(ESHUTDOWN,    "Cannot send after socket shutdown")
    E(EALREADY,     "Operation already in progress")
    E(EINPROGRESS,  "Operation in progress")
    E(ESTALE,       "Stale file handle")
    E(EREMOTEIO,    "Remote I/O error")
    E(EDQUOT,       "Quota exceeded")
    E(ENOMEDIUM,    "No medium found")
    E(EMEDIUMTYPE,  "Wrong medium type")
    E(0,            "No error information")
  }
  return "";
}
#undef E

1 个答案:

答案 0 :(得分:2)

您对strerror的实施是正确的。但是C标准库中的标准库可能是语言环境感知(请参阅locale(7)),这使得它不可重入。

实际上,errno今天(通常)是一个扩展到某个函数调用的宏。

在我的/usr/include/x86_64-linux-gnu/bits/errno.h 内部标题中,有:

extern int *__errno_location (void) __THROW __attribute__ ((__const__));
#   define errno (*__errno_location ())

strerror_r存在于填充缓冲区(必须是特定于线程的)来自某个错误编号。