aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-21 09:51:55 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-21 09:51:55 +0800
commit3b09142a4df8e415e670b64d4839cd3195f87d0d (patch)
treecc37aa5290c9245dd26ff2b68ad9c84af16e911c
parent540a12380e825f3135f3b0dd97bc18967ddae1d0 (diff)
downloadrcc-project-3b09142a4df8e415e670b64d4839cd3195f87d0d.tar.gz
rcc-project-3b09142a4df8e415e670b64d4839cd3195f87d0d.tar.xz
[Support] Add errno support
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
-rw-r--r--rcc/include/rcc/Support/Errno.h63
-rw-r--r--rcc/lib/Support/Errno.cc77
2 files changed, 140 insertions, 0 deletions
diff --git a/rcc/include/rcc/Support/Errno.h b/rcc/include/rcc/Support/Errno.h
new file mode 100644
index 0000000..70d3873
--- /dev/null
+++ b/rcc/include/rcc/Support/Errno.h
@@ -0,0 +1,63 @@
+/*
+ RCC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option) any
+ later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ RCC-Project; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>.
+*/
+
+// This implementation is based on llvm/include/llvm/Support/Errno.h.
+
+#ifndef RCC_SUPPORT_ERRNO_H
+#define RCC_SUPPORT_ERRNO_H
+
+#include "rcc/Support/Compiler.h"
+
+#include <cerrno>
+#include <string>
+
+namespace rcc {
+namespace sys {
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available. Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+RCC_ABI std::string
+StrError ();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+RCC_ABI std::string
+StrError (int errnum);
+
+template <typename FailT, typename Fun, typename... Args>
+inline decltype(auto)
+RetryAfterSignal (const FailT &Fail, const Fun &F, const Args &...As)
+{
+ decltype(F (As...)) Res;
+ do
+ {
+ errno = 0;
+ Res = F (As...);
+ }
+ while (Res == Fail && errno == EINTR);
+ return Res;
+}
+
+} // namespace sys
+} // namespace rcc
+
+#endif // RCC_SUPPORT_ERRNO_H
diff --git a/rcc/lib/Support/Errno.cc b/rcc/lib/Support/Errno.cc
new file mode 100644
index 0000000..05ddd07
--- /dev/null
+++ b/rcc/lib/Support/Errno.cc
@@ -0,0 +1,77 @@
+/*
+ RCC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option) any
+ later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ RCC-Project; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>.
+*/
+
+// This implementation is based on llvm/lib/Support/Errno.cpp.
+
+#include "rcc/Support/Errno.h"
+#include "rcc/Config/config.h"
+
+#include <cstring>
+#include <errno.h>
+
+namespace rcc {
+namespace sys {
+
+std::string
+StrError ()
+{
+ return StrError (errno);
+}
+
+std::string
+StrError (int errnum)
+{
+ std::string str;
+ if (errnum == 0)
+ {
+ return str;
+ }
+
+#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
+ const int MaxErrStrLen = 2000;
+ char buffer[MaxErrStrLen];
+ buffer[0] = '\0';
+#endif
+
+#ifdef HAVE_STRERROR_R
+ // strerror_r is thread-safe.
+#if defined(__GLIBC__) && defined(_GNU_SOURCE)
+ // glibc defines its own incompatible version of strerror_r which may not
+ // use the buffer supplied.
+ str = strerror_r (errnum, buffer, MaxErrStrLen - 1);
+#else
+ strerror_r (errnum, buffer, MaxErrStrLen - 1);
+ str = buffer;
+#endif
+#elif HAVE_DECL_STRERROR_S
+ // Windows Secure API.
+ strerror_s (buffer, MaxErrStrLen - 1, errnum);
+ str = buffer;
+#else
+ // Copy the thread-unsafe result of strerror into the buffer as fast as
+ // possible to minimize the impact of collisions in multiple threads.
+ str = strerror (errnum);
+#endif
+ return str;
+}
+
+} // namespace sys
+} // namespace rcc