diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -167,6 +167,7 @@ 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 diff --git a/libc/include/llvm-libc-macros/linux/unistd-macros.h b/libc/include/llvm-libc-macros/linux/unistd-macros.h --- a/libc/include/llvm-libc-macros/linux/unistd-macros.h +++ b/libc/include/llvm-libc-macros/linux/unistd-macros.h @@ -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 diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -511,6 +511,11 @@ RetValSpec, [ArgSpec, ArgSpec, ArgSpec, ArgSpec] >, + FunctionSpec< + "sysconf", + RetValSpec, + [ArgSpec] + >, FunctionSpec< "__llvm_libc_syscall", RetValSpec, diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -198,6 +198,13 @@ .${LIBC_TARGET_OS}.__llvm_libc_syscall ) +add_entrypoint_object( + sysconf + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.sysconf +) + add_entrypoint_object( truncate ALIAS diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -369,6 +369,17 @@ libc.src.errno.errno ) +add_entrypoint_object( + sysconf + SRCS + sysconf.cpp + HDRS + ../sysconf.h + DEPENDS + libc.include.unistd + libc.src.errno.errno +) + add_entrypoint_object( truncate SRCS diff --git a/libc/src/unistd/linux/sysconf.cpp b/libc/src/unistd/linux/sysconf.cpp new file mode 100644 --- /dev/null +++ b/libc/src/unistd/linux/sysconf.cpp @@ -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 +#include // For EXEC_PAGESIZE. +#include + +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 --- /dev/null +++ b/libc/src/unistd/sysconf.h @@ -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 + +namespace __llvm_libc { + +long sysconf(int name); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_UNISTD_SYSCONF_H diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -376,3 +376,15 @@ 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 --- /dev/null +++ b/libc/test/src/unistd/sysconf_test.cpp @@ -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 + +TEST(LlvmLibcSysconfTest, PagesizeTest) { + long pagesize = __llvm_libc::sysconf(_SC_PAGESIZE); + ASSERT_GT(pagesize, 0l); +}