[libc-commits] [libc] 453c85f - [libc] Add implementation of errno and define the other macros of errno.h.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Mon Dec 9 13:36:16 PST 2019


Author: Siva Chandra Reddy
Date: 2019-12-09T13:34:08-08:00
New Revision: 453c85ff0f96048ea31037fed905ef6a06ac3fcc

URL: https://github.com/llvm/llvm-project/commit/453c85ff0f96048ea31037fed905ef6a06ac3fcc
DIFF: https://github.com/llvm/llvm-project/commit/453c85ff0f96048ea31037fed905ef6a06ac3fcc.diff

LOG: [libc] Add implementation of errno and define the other macros of errno.h.

Reviewers: stanshebs, alexbrachet

Subscribers: mgorny, MaskRay, tschuett, libc-commits

Tags: #libc-project

Differential Revision: https://reviews.llvm.org/D71094

Added: 
    libc/config/linux/errno.h.in
    libc/include/errno.h.def
    libc/spec/linux.td
    libc/spec/posix.td
    libc/src/errno/CMakeLists.txt
    libc/src/errno/errno_location.cpp
    libc/src/errno/errno_test.cpp
    libc/src/errno/llvmlibc_errno.h

Modified: 
    libc/config/linux/api.td
    libc/config/public_api.td
    libc/include/CMakeLists.txt
    libc/lib/CMakeLists.txt
    libc/spec/stdc.td
    libc/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index e0d4df8324a2..7568620b7000 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -1,5 +1,7 @@
 include "config/public_api.td"
 
+include "spec/linux.td"
+include "spec/posix.td"
 include "spec/stdc.td"
 
 def FloatT : TypeDecl<"float_t"> {
@@ -28,6 +30,13 @@ def NullMacro : MacroDef<"NULL"> {
   }];
 }
 
+def ErrnoMacro : MacroDef<"errno"> {
+  let Defn = [{
+    int *__errno_location();
+    #define errno (*__errno_location())
+  }];
+}
+
 def MathAPI : PublicAPI<"math.h"> {
   let Functions = [
    "acos",
@@ -83,3 +92,22 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
     "snprintf",
   ];
 }
+
+def ErrnoAPI : PublicAPI<"errno.h"> {
+  let Macros = [
+    ErrnoMacro,
+    // We largely depend on linux/errno.h to give us the
+    // various error macro definitions. However, some libc
+    // implementations have chosen to provide definitions
+    // for some of the error macros to account for the ones
+    // missing in linux/errno.h. There is no harm in doing
+    // the same here if we define the macros only when they
+    // are not already defined.
+    MacroDefineIfNot<"ENOTSUP", "EOPNOTSUPP">,
+    MacroDefineIfNot<"ECANCELED", "125">,
+    MacroDefineIfNot<"EOWNERDEAD", "130">,
+    MacroDefineIfNot<"ENOTRECOVERABLE", "131">,
+    MacroDefineIfNot<"ERFKILL", "132">,
+    MacroDefineIfNot<"EHWPOISON", "133">,
+  ];
+}

diff  --git a/libc/config/linux/errno.h.in b/libc/config/linux/errno.h.in
new file mode 100644
index 000000000000..793f0f6affdc
--- /dev/null
+++ b/libc/config/linux/errno.h.in
@@ -0,0 +1,11 @@
+//===---------------- Linux specific errno.h definitions ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+%%begin()
+
+#include <linux/errno.h>

diff  --git a/libc/config/public_api.td b/libc/config/public_api.td
index 311833a190a8..3f409210e05c 100644
--- a/libc/config/public_api.td
+++ b/libc/config/public_api.td
@@ -10,6 +10,16 @@ class MacroDef<string name> {
   string Defn = "";
 }
 
+class SimpleMacroDef<string name, string value> : MacroDef<name> {
+  let Defn = !strconcat("#define ", name, " ", value);
+}
+
+class MacroDefineIfNot<string name, string value> : MacroDef<name> {
+  let Defn = !strconcat("#ifndef ", name, "\n",
+                        "#define " , name, " ", value, "\n",
+                        "#endif // ", name);
+}
+
 class PublicAPI<string name> {
   string HeaderName = name;
   list<MacroDef> Macros = [];

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 9069ddb0f597..8d1c53297b1b 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -28,3 +28,13 @@ add_gen_header(
   DEPENDS
     llvm_libc_common_h
 )
+
+add_gen_header(
+  errno_h
+  DEF_FILE errno.h.def
+  PARAMS
+    platform_errno=../config/${LIBC_TARGET_OS}/errno.h.in
+  GEN_HDR errno.h
+  DATA_FILES
+    ../config/${LIBC_TARGET_OS}/errno.h.in
+)

diff  --git a/libc/include/errno.h.def b/libc/include/errno.h.def
new file mode 100644
index 000000000000..e5db86ce00e1
--- /dev/null
+++ b/libc/include/errno.h.def
@@ -0,0 +1,18 @@
+//===---------------- C standard library header errno.h ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_ERRNO_H
+#define LLVM_LIBC_ERRNO_H
+
+#include <__llvm-libc-common.h>
+
+%%include_file(${platform_errno})
+
+%%public_api()
+
+#endif // LLVM_LIBC_ERRNO_H

diff  --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index 121cd1fbb77b..dd1975ba8548 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -2,8 +2,10 @@
 add_entrypoint_library(
   llvmlibc
   DEPENDS
+    # errno.h entrypoints
+    __errno_location
+
     # string.h entrypoints
-    ## C standard library entrypoints
     strcpy
     strcat
 )

diff  --git a/libc/spec/linux.td b/libc/spec/linux.td
new file mode 100644
index 000000000000..da6812f88104
--- /dev/null
+++ b/libc/spec/linux.td
@@ -0,0 +1,66 @@
+def Linux : StandardSpec<"Linux"> {
+  HeaderSpec Errno = HeaderSpec<
+      "errno.h",
+      [
+        Macro<"ENOMEDIUM">,
+        Macro<"ENOTBLK">,
+        Macro<"EMEDIUMTYPE">,
+        Macro<"EBADSLT">,
+        Macro<"ECHRNG">,
+        Macro<"ERFKILL">,
+        Macro<"EUSERS">,
+        Macro<"EBADR">,
+        Macro<"EL3HLT">,
+        Macro<"ENOTUNIQ">,
+        Macro<"EXFULL">,
+        Macro<"EHOSTDOWN">,
+        Macro<"EL3RST">,
+        Macro<"ENOPKG">,
+        Macro<"ENOCSI">,
+        Macro<"EUNATCH">,
+        Macro<"EREMCHG">,
+        Macro<"ETOOMANYREFS">,
+        Macro<"EL2HLT">,
+        Macro<"EBADFD">,
+        Macro<"EREMOTEIO">,
+        Macro<"ENAVAIL">,
+        Macro<"ELIBEXEC">,
+        Macro<"ESHUTDOWN">,
+        Macro<"ENOKEY">,
+        Macro<"ESTRPIPE">,
+        Macro<"EKEYREJECTED">,
+        Macro<"ESRMNT">,
+        Macro<"EKEYREVOKED">,
+        Macro<"EBADE">,
+        Macro<"ELIBBAD">,
+        Macro<"EISNAM">,
+        Macro<"EBFONT">,
+        Macro<"EPFNOSUPPORT">,
+        Macro<"EREMOTE">,
+        Macro<"EDEADLOCK">,
+        Macro<"ENONET">,
+        Macro<"EDOTDOT">,
+        Macro<"EKEYEXPIRED">,
+        Macro<"ELIBSCN">,
+        Macro<"ERESTART">,
+        Macro<"EBADRQC">,
+        Macro<"EUCLEAN">,
+        Macro<"ENOANO">,
+        Macro<"ELIBACC">,
+        Macro<"EHWPOISON">,
+        Macro<"ELIBMAX">,
+        Macro<"ESOCKTNOSUPPORT">,
+        Macro<"ENOTNAM">,
+        Macro<"ELNRNG">,
+        Macro<"EL2NSYNC">,
+        Macro<"EADV">,
+        Macro<"ECOMM">,
+      ],
+      [], // Types
+      []  // Functions
+  >;
+
+  let Headers = [
+    Errno,
+  ];
+}

diff  --git a/libc/spec/posix.td b/libc/spec/posix.td
new file mode 100644
index 000000000000..ce7fd43aa83e
--- /dev/null
+++ b/libc/spec/posix.td
@@ -0,0 +1,91 @@
+def POSIX : StandardSpec<"POSIX"> {
+  HeaderSpec Errno = HeaderSpec<
+      "errno.h",
+      [
+        Macro<"E2BIG">,
+        Macro<"EACCES">,
+        Macro<"EADDRINUSE">,
+        Macro<"EADDRNOTAVAIL">,
+        Macro<"EAFNOSUPPORT">,
+        Macro<"EAGAIN">,
+        Macro<"EALREADY">,
+        Macro<"EBADF">,
+        Macro<"EBADMSG">,
+        Macro<"EBUSY">,
+        Macro<"ECANCELED">,
+        Macro<"ECHILD">,
+        Macro<"ECONNABORTED">,
+        Macro<"ECONNREFUSED">,
+        Macro<"ECONNRESET">,
+        Macro<"EDEADLK">,
+        Macro<"EDESTADDRREQ">,
+        Macro<"EDQUOT">,
+        Macro<"EEXIST">,
+        Macro<"EFAULT">,
+        Macro<"EFBIG">,
+        Macro<"EHOSTUNREACH">,
+        Macro<"EIDRM">,
+        Macro<"EINPROGRESS">,
+        Macro<"EINTR">,
+        Macro<"EINVAL">,
+        Macro<"EIO">,
+        Macro<"EISCONN">,
+        Macro<"EISDIR">,
+        Macro<"ELOOP">,
+        Macro<"EMFILE">,
+        Macro<"EMLINK">,
+        Macro<"EMSGSIZE">,
+        Macro<"EMULTIHOP">,
+        Macro<"ENAMETOOLONG">,
+        Macro<"ENETDOWN">,
+        Macro<"ENETRESET">,
+        Macro<"ENETUNREACH">,
+        Macro<"ENFILE">,
+        Macro<"ENOBUFS">,
+        Macro<"ENODATA">,
+        Macro<"ENODEV">,
+        Macro<"ENOENT">,
+        Macro<"ENOEXEC">,
+        Macro<"ENOLCK">,
+        Macro<"ENOLINK">,
+        Macro<"ENOMEM">,
+        Macro<"ENOMSG">,
+        Macro<"ENOPROTOOPT">,
+        Macro<"ENOSPC">,
+        Macro<"ENOSR">,
+        Macro<"ENOSTR">,
+        Macro<"ENOSYS">,
+        Macro<"ENOTCONN">,
+        Macro<"ENOTDIR">,
+        Macro<"ENOTEMPTY">,
+        Macro<"ENOTRECOVERABLE">,
+        Macro<"ENOTSOCK">,
+        Macro<"ENOTSUP">,
+        Macro<"ENOTTY">,
+        Macro<"ENXIO">,
+        Macro<"EOPNOTSUPP">,
+        Macro<"EOVERFLOW">,
+        Macro<"EOWNERDEAD">,
+        Macro<"EPERM">,
+        Macro<"EPIPE">,
+        Macro<"EPROTO">,
+        Macro<"EPROTONOSUPPORT">,
+        Macro<"EPROTOTYPE">,
+        Macro<"EROFS">,
+        Macro<"ESPIPE">,
+        Macro<"ESRCH">,
+        Macro<"ESTALE">,
+        Macro<"ETIME">,
+        Macro<"ETIMEDOUT">,
+        Macro<"ETXTBSY">,
+        Macro<"EWOULDBLOCK">,
+        Macro<"EXDEV">,
+      ],
+      [], // Types
+      []  // Functions
+  >;
+
+  let Headers = [
+    Errno,
+  ];
+}

diff  --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 154214dc5168..a17a3872fa27 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -170,7 +170,20 @@ def StdC : StandardSpec<"stdc"> {
       ]
   >;
 
+  HeaderSpec Errno = HeaderSpec<
+      "errno.h",
+      [
+        Macro<"errno">,
+        Macro<"EDOM">,
+        Macro<"EILSEQ">,
+        Macro<"ERANGE">,
+      ],
+      [], // Types
+      []  // Functions
+  >;
+
   let Headers = [
+    Errno,
     Math,
     String,
     StdIO,

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 00df58860ff9..f9a86af7652a 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -1,4 +1,5 @@
-add_subdirectory(string)
+add_subdirectory(errno)
 add_subdirectory(math)
+add_subdirectory(string)
 
 add_subdirectory(__support)

diff  --git a/libc/src/errno/CMakeLists.txt b/libc/src/errno/CMakeLists.txt
new file mode 100644
index 000000000000..32d7262044b2
--- /dev/null
+++ b/libc/src/errno/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_entrypoint_object(
+  __errno_location
+  SRCS
+    errno_location.cpp
+  HDRS
+    llvmlibc_errno.h
+)
+
+add_custom_target(libc_errno_unittests)
+
+add_libc_unittest(
+  errno_test
+  SUITE
+    libc_errno_unittests
+  SRCS
+    errno_test.cpp
+  DEPENDS
+    __errno_location
+)

diff  --git a/libc/src/errno/errno_location.cpp b/libc/src/errno/errno_location.cpp
new file mode 100644
index 000000000000..1a1b2889c84b
--- /dev/null
+++ b/libc/src/errno/errno_location.cpp
@@ -0,0 +1,22 @@
+//===----------------- Implementation of __errno_location -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "src/__support/common.h"
+
+namespace __llvm_libc {
+
+static thread_local int __errno = 0;
+
+// __errno_location is not really an entry point but we still want it to behave
+// like an entry point because the errno macro resolves to the C symbol
+// "__errno_location".
+int *LLVM_LIBC_ENTRYPOINT(__errno_location)() { return &__errno; }
+
+} // namespace __llvm_libc

diff  --git a/libc/src/errno/errno_test.cpp b/libc/src/errno/errno_test.cpp
new file mode 100644
index 000000000000..1ca61d5c625d
--- /dev/null
+++ b/libc/src/errno/errno_test.cpp
@@ -0,0 +1,17 @@
+//===---------------------- Unittests for errno --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/errno/llvmlibc_errno.h"
+
+#include "gtest/gtest.h"
+
+TEST(ErrnoTest, Basic) {
+  int test_val = 123;
+  llvmlibc_errno = test_val;
+  ASSERT_EQ(test_val, llvmlibc_errno);
+}

diff  --git a/libc/src/errno/llvmlibc_errno.h b/libc/src/errno/llvmlibc_errno.h
new file mode 100644
index 000000000000..b5a8fdd26adc
--- /dev/null
+++ b/libc/src/errno/llvmlibc_errno.h
@@ -0,0 +1,22 @@
+//===------------------ Implementation header for errno -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
+#define LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H
+
+// Internal code should use this and not use the errno macro from the
+// public header.
+#define llvmlibc_errno (*__llvm_libc::__errno_location())
+
+namespace __llvm_libc {
+
+int *__errno_location();
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_ERRNO_LLVMLIBC_ERRNO_H


        


More information about the libc-commits mailing list