[libc] add sysconf with pagesize
authorMichael Jones <michaelrj@google.com>
Thu, 22 Sep 2022 20:35:49 +0000 (13:35 -0700)
committerMichael Jones <michaelrj@google.com>
Mon, 10 Oct 2022 21:51:45 +0000 (14:51 -0700)
The sysconf function has many options, this patch adds the basic funtion
and the pagesize option. More options will be added in future patches.

Reviewed By: sivachandra

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

libc/config/linux/x86_64/entrypoints.txt
libc/include/llvm-libc-macros/linux/unistd-macros.h
libc/spec/posix.td
libc/src/unistd/CMakeLists.txt
libc/src/unistd/linux/CMakeLists.txt
libc/src/unistd/linux/sysconf.cpp [new file with mode: 0644]
libc/src/unistd/sysconf.h [new file with mode: 0644]
libc/test/src/unistd/CMakeLists.txt
libc/test/src/unistd/sysconf_test.cpp [new file with mode: 0644]

index 7fd11a3..32ceb8f 100644 (file)
@@ -167,6 +167,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.unistd.rmdir
     libc.src.unistd.symlink
     libc.src.unistd.symlinkat
+    libc.src.unistd.sysconf
     libc.src.unistd.truncate
     libc.src.unistd.unlink
     libc.src.unistd.unlinkat
index 9fbb9ae..cfdfb9a 100644 (file)
@@ -15,6 +15,9 @@
 #define W_OK 2
 #define R_OK 4
 
+#define _SC_PAGESIZE 1
+#define _SC_PAGE_SIZE _SC_PAGESIZE
+
 // Macro to set up the call to the __llvm_libc_syscall function
 // This is to prevent the call from having fewer than 6 arguments, since six
 // arguments are always passed to the syscall. Unnecessary arguments are
index fc7ac25..61e7e4d 100644 (file)
@@ -512,6 +512,11 @@ def POSIX : StandardSpec<"POSIX"> {
           [ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<IntType>, ArgSpec<ConstCharPtr>]
         >,
         FunctionSpec<
+          "sysconf",
+          RetValSpec<IntType>,
+          [ArgSpec<IntType>]
+        >,
+        FunctionSpec<
           "__llvm_libc_syscall",
           RetValSpec<LongType>,
           [ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>]
index a9d88ee..ae53763 100644 (file)
@@ -199,6 +199,13 @@ add_entrypoint_object(
 )
 
 add_entrypoint_object(
+  sysconf
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.sysconf
+)
+
+add_entrypoint_object(
   truncate
   ALIAS
   DEPENDS
index c81b921..2a6a0e6 100644 (file)
@@ -370,6 +370,17 @@ add_entrypoint_object(
 )
 
 add_entrypoint_object(
+  sysconf
+  SRCS
+    sysconf.cpp
+  HDRS
+    ../sysconf.h
+  DEPENDS
+    libc.include.unistd
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
   truncate
   SRCS
     truncate.cpp
diff --git a/libc/src/unistd/linux/sysconf.cpp b/libc/src/unistd/linux/sysconf.cpp
new file mode 100644 (file)
index 0000000..b4a9cd1
--- /dev/null
@@ -0,0 +1,33 @@
+//===-- Linux implementation of sysconf -----------------------------------===//
+//
+// 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/unistd/sysconf.h"
+
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <unistd.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(long, sysconf, (int name)) {
+  long ret = 0;
+  if (name == _SC_PAGESIZE) {
+    // TODO: get this information from the auxvector.
+    return EXEC_PAGESIZE;
+  }
+  // TODO: Complete the rest of the sysconf options.
+  if (ret < 0) {
+    errno = EINVAL;
+    return -1;
+  }
+  return ret;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/unistd/sysconf.h b/libc/src/unistd/sysconf.h
new file mode 100644 (file)
index 0000000..b704edb
--- /dev/null
@@ -0,0 +1,20 @@
+//===-- Implementation header for sysconf -----------------------*- C++ -*-===//
+//
+// 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_UNISTD_SYSCONF_H
+#define LLVM_LIBC_SRC_UNISTD_SYSCONF_H
+
+#include <unistd.h>
+
+namespace __llvm_libc {
+
+long sysconf(int name);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_UNISTD_SYSCONF_H
index 448116e..3b99aca 100644 (file)
@@ -376,3 +376,15 @@ add_libc_unittest(
     libc.include.sys_syscall
     libc.test.errno_setter_matcher
 )
+
+
+add_libc_unittest(
+  sysconf_test
+  SUITE
+    libc_unistd_unittests
+  SRCS
+    sysconf_test.cpp
+  DEPENDS
+    libc.include.unistd
+    libc.src.unistd.sysconf
+)
diff --git a/libc/test/src/unistd/sysconf_test.cpp b/libc/test/src/unistd/sysconf_test.cpp
new file mode 100644 (file)
index 0000000..9f93746
--- /dev/null
@@ -0,0 +1,17 @@
+//===-- Unittests for sysconf ---------------------------------------------===//
+//
+// 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/unistd/sysconf.h"
+#include "utils/UnitTest/Test.h"
+
+#include <unistd.h>
+
+TEST(LlvmLibcSysconfTest, PagesizeTest) {
+  long pagesize = __llvm_libc::sysconf(_SC_PAGESIZE);
+  ASSERT_GT(pagesize, 0l);
+}