[libc-commits] [libc] 441606f - [libc] Add implementations of fopen, flose, fread, fwrite and fseek.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Wed Mar 23 21:20:40 PDT 2022
Author: Siva Chandra Reddy
Date: 2022-03-24T04:20:12Z
New Revision: 441606f5ff8e4dd884e106a0b6f86f9037c946c4
URL: https://github.com/llvm/llvm-project/commit/441606f5ff8e4dd884e106a0b6f86f9037c946c4
DIFF: https://github.com/llvm/llvm-project/commit/441606f5ff8e4dd884e106a0b6f86f9037c946c4.diff
LOG: [libc] Add implementations of fopen, flose, fread, fwrite and fseek.
A follow up patch will add feof and ferror.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D122327
Added:
libc/src/stdio/fclose.cpp
libc/src/stdio/fclose.h
libc/src/stdio/fopen.cpp
libc/src/stdio/fopen.h
libc/src/stdio/fread.cpp
libc/src/stdio/fread.h
libc/src/stdio/fseek.cpp
libc/src/stdio/fseek.h
libc/test/src/stdio/fileop_test.cpp
libc/test/src/stdio/testdata/CMakeLists.txt
Modified:
libc/config/linux/x86_64/entrypoints.txt
libc/spec/stdc.td
libc/src/stdio/CMakeLists.txt
libc/src/stdio/fwrite.cpp
libc/src/stdio/fwrite.h
libc/test/src/stdio/CMakeLists.txt
Removed:
libc/src/stdio/FILE.h
libc/test/src/stdio/fwrite_test.cpp
################################################################################
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e83bddafb984c..5aa64a8dc7dfd 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -229,6 +229,13 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.stdlib.exit
libc.src.stdlib.getenv
+ # stdio.h entrypoints
+ libc.src.stdio.fclose
+ libc.src.stdio.fopen
+ libc.src.stdio.fread
+ libc.src.stdio.fseek
+ libc.src.stdio.fwrite
+
# signal.h entrypoints
# TODO: Enable signal.h entrypoints after fixing signal.h
# libc.src.signal.raise
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index f7b377d7f70f1..7f57a2ddfab02 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -481,13 +481,39 @@ def StdC : StandardSpec<"stdc"> {
],
[], // Enumerations
[
+ FunctionSpec<
+ "fclose",
+ RetValSpec<IntType>,
+ [ArgSpec<FILEPtr>]
+ >,
+ FunctionSpec<
+ "fopen",
+ RetValSpec<FILEPtr>,
+ [ArgSpec<ConstCharPtr>,
+ ArgSpec<ConstCharPtr>]
+ >,
+ FunctionSpec<
+ "fread",
+ RetValSpec<SizeTType>,
+ [ArgSpec<VoidRestrictedPtr>,
+ ArgSpec<SizeTType>,
+ ArgSpec<SizeTType>,
+ ArgSpec<FILERestrictedPtr>]
+ >,
+ FunctionSpec<
+ "fseek",
+ RetValSpec<IntType>,
+ [ArgSpec<FILEPtr>,
+ ArgSpec<LongType>,
+ ArgSpec<IntType>]
+ >,
FunctionSpec<
"fwrite",
RetValSpec<SizeTType>,
[ArgSpec<ConstVoidRestrictedPtr>,
- ArgSpec<SizeTType>,
- ArgSpec<SizeTType>,
- ArgSpec<FILERestrictedPtr>]
+ ArgSpec<SizeTType>,
+ ArgSpec<SizeTType>,
+ ArgSpec<FILERestrictedPtr>]
>,
]
>;
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 337ee22c533dc..2a50f798e3c98 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -1,3 +1,39 @@
+add_entrypoint_object(
+ fopen
+ SRCS
+ fopen.cpp
+ HDRS
+ fopen.h
+ DEPENDS
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ fclose
+ SRCS
+ fclose.cpp
+ HDRS
+ fclose.h
+ DEPENDS
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ fread
+ SRCS
+ fread.cpp
+ HDRS
+ fread.h
+ DEPENDS
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
add_entrypoint_object(
fwrite
SRCS
@@ -5,6 +41,19 @@ add_entrypoint_object(
HDRS
fwrite.h
DEPENDS
- libc.src.threads.mtx_lock
- libc.src.threads.mtx_unlock
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
+)
+
+add_entrypoint_object(
+ fseek
+ SRCS
+ fseek.cpp
+ HDRS
+ fseek.h
+ DEPENDS
+ libc.include.stdio
+ libc.src.__support.File.file
+ libc.src.__support.File.platform_file
)
diff --git a/libc/src/stdio/fclose.cpp b/libc/src/stdio/fclose.cpp
new file mode 100644
index 0000000000000..48803e33acb3d
--- /dev/null
+++ b/libc/src/stdio/fclose.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fclose ------------------------------------------===//
+//
+// 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/stdio/fclose.h"
+#include "src/__support/File/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fclose, (::FILE * stream)) {
+ return reinterpret_cast<__llvm_libc::File *>(stream)->close();
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/fclose.h b/libc/src/stdio/fclose.h
new file mode 100644
index 0000000000000..21ffa4350391e
--- /dev/null
+++ b/libc/src/stdio/fclose.h
@@ -0,0 +1,20 @@
+//===-- Implementation header of fclose -------------------------*- 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_STDIO_FCLOSE_H
+#define LLVM_LIBC_SRC_STDIO_FCLOSE_H
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+int fclose(::FILE *stream);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_FCLOSE_H
diff --git a/libc/src/stdio/fopen.cpp b/libc/src/stdio/fopen.cpp
new file mode 100644
index 0000000000000..f34b4ed96999a
--- /dev/null
+++ b/libc/src/stdio/fopen.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of fopen -------------------------------------------===//
+//
+// 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/stdio/fopen.h"
+#include "src/__support/File/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(::FILE *, fopen,
+ (const char *__restrict name, const char *__restrict mode)) {
+ return reinterpret_cast<::FILE *>(__llvm_libc::openfile(name, mode));
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/fopen.h b/libc/src/stdio/fopen.h
new file mode 100644
index 0000000000000..f8ab0542d2a6f
--- /dev/null
+++ b/libc/src/stdio/fopen.h
@@ -0,0 +1,20 @@
+//===-- Implementation header of fopen --------------------------*- 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_STDIO_FOPEN_H
+#define LLVM_LIBC_SRC_STDIO_FOPEN_H
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+::FILE *fopen(const char *__restrict name, const char *__restrict mode);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_FOPEN_H
diff --git a/libc/src/stdio/fread.cpp b/libc/src/stdio/fread.cpp
new file mode 100644
index 0000000000000..c6a16e24beef6
--- /dev/null
+++ b/libc/src/stdio/fread.cpp
@@ -0,0 +1,23 @@
+//===-- Implementation of fread -------------------------------------------===//
+//
+// 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/stdio/fread.h"
+#include "src/__support/File/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(size_t, fread,
+ (void *__restrict buffer, size_t size, size_t nmemb,
+ ::FILE *stream)) {
+ return reinterpret_cast<__llvm_libc::File *>(stream)->read(buffer,
+ size * nmemb);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/FILE.h b/libc/src/stdio/fread.h
similarity index 51%
rename from libc/src/stdio/FILE.h
rename to libc/src/stdio/fread.h
index 54bc9b2c87311..995367cda4560 100644
--- a/libc/src/stdio/FILE.h
+++ b/libc/src/stdio/fread.h
@@ -1,4 +1,4 @@
-//===-- Internal definition of FILE -----------------------------*- C++ -*-===//
+//===-- Implementation header of fread --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,22 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC_STDIO_FILE_H
-#define LLVM_LIBC_SRC_STDIO_FILE_H
+#ifndef LLVM_LIBC_SRC_STDIO_FREAD_H
+#define LLVM_LIBC_SRC_STDIO_FREAD_H
-#include "include/threads.h"
-#include <stddef.h>
+#include <stdio.h>
namespace __llvm_libc {
-struct FILE {
- mtx_t lock;
-
- using write_function_t = size_t(FILE *, const char *, size_t);
-
- write_function_t *write;
-};
+size_t fread(void *__restrict buffer, size_t size, size_t nmemb,
+ ::FILE *stream);
} // namespace __llvm_libc
-#endif // LLVM_LIBC_SRC_STDIO_FILE_H
+#endif // LLVM_LIBC_SRC_STDIO_FREAD_H
diff --git a/libc/src/stdio/fseek.cpp b/libc/src/stdio/fseek.cpp
new file mode 100644
index 0000000000000..296acffdd9413
--- /dev/null
+++ b/libc/src/stdio/fseek.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of fseek -------------------------------------------===//
+//
+// 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/stdio/fseek.h"
+#include "src/__support/File/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fseek, (::FILE * stream, long offset, int whence)) {
+ return reinterpret_cast<__llvm_libc::File *>(stream)->seek(offset, whence);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/fseek.h b/libc/src/stdio/fseek.h
new file mode 100644
index 0000000000000..f3865c4efd23f
--- /dev/null
+++ b/libc/src/stdio/fseek.h
@@ -0,0 +1,20 @@
+//===-- Implementation header of fseek --------------------------*- 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_STDIO_FSEEK_H
+#define LLVM_LIBC_SRC_STDIO_FSEEK_H
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+int fseek(::FILE *stream, long offset, int whence);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_FSEEK_H
diff --git a/libc/src/stdio/fwrite.cpp b/libc/src/stdio/fwrite.cpp
index 80cf50ca376e4..0ea0611370dc3 100644
--- a/libc/src/stdio/fwrite.cpp
+++ b/libc/src/stdio/fwrite.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of fwrite and fwrite_unlocked ------------*- C++ -*-===//
+//===-- Implementation of fwrite ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,24 +7,17 @@
//===----------------------------------------------------------------------===//
#include "src/stdio/fwrite.h"
-#include "src/stdio/FILE.h"
-#include "src/threads/mtx_lock.h"
-#include "src/threads/mtx_unlock.h"
+#include "src/__support/File/file.h"
-namespace __llvm_libc {
+#include <stdio.h>
-size_t fwrite_unlocked(const void *__restrict ptr, size_t size, size_t nmeb,
- __llvm_libc::FILE *__restrict stream) {
- return stream->write(stream, reinterpret_cast<const char *>(ptr),
- size * nmeb);
-}
+namespace __llvm_libc {
-size_t fwrite(const void *__restrict ptr, size_t size, size_t nmeb,
- __llvm_libc::FILE *__restrict stream) {
- __llvm_libc::mtx_lock(&stream->lock);
- size_t written = fwrite_unlocked(ptr, size, nmeb, stream);
- __llvm_libc::mtx_unlock(&stream->lock);
- return written;
+LLVM_LIBC_FUNCTION(size_t, fwrite,
+ (const void *__restrict buffer, size_t size, size_t nmemb,
+ ::FILE *stream)) {
+ return reinterpret_cast<__llvm_libc::File *>(stream)->write(buffer,
+ size * nmemb);
}
} // namespace __llvm_libc
diff --git a/libc/src/stdio/fwrite.h b/libc/src/stdio/fwrite.h
index 8a71ca105bb08..eb258fcec33b7 100644
--- a/libc/src/stdio/fwrite.h
+++ b/libc/src/stdio/fwrite.h
@@ -9,13 +9,12 @@
#ifndef LLVM_LIBC_SRC_STDIO_FWRITE_H
#define LLVM_LIBC_SRC_STDIO_FWRITE_H
-#include "src/stdio/FILE.h"
-#include <stddef.h>
+#include <stdio.h>
namespace __llvm_libc {
-size_t fwrite(const void *__restrict ptr, size_t size, size_t nmeb,
- __llvm_libc::FILE *__restrict stream);
+size_t fwrite(const void *__restrict ptr, size_t size, size_t nmemb,
+ ::FILE *__restrict stream);
} // namespace __llvm_libc
diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
index f178eca3c778b..7cb524e2b0800 100644
--- a/libc/test/src/stdio/CMakeLists.txt
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -1,11 +1,17 @@
add_libc_testsuite(libc_stdio_unittests)
add_libc_unittest(
- fwrite_test
+ fileop_test
SUITE
libc_stdio_unittests
SRCS
- fwrite_test.cpp
+ fileop_test.cpp
DEPENDS
+ libc.src.stdio.fclose
+ libc.src.stdio.fopen
+ libc.src.stdio.fread
+ libc.src.stdio.fseek
libc.src.stdio.fwrite
)
+
+add_subdirectory(testdata)
diff --git a/libc/test/src/stdio/fileop_test.cpp b/libc/test/src/stdio/fileop_test.cpp
new file mode 100644
index 0000000000000..e515a62a5e768
--- /dev/null
+++ b/libc/test/src/stdio/fileop_test.cpp
@@ -0,0 +1,43 @@
+//===-- Unittests for file operations like fopen, flcose etc --------------===//
+//
+// 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/stdio/fclose.h"
+#include "src/stdio/fopen.h"
+#include "src/stdio/fread.h"
+#include "src/stdio/fseek.h"
+#include "src/stdio/fwrite.h"
+#include "utils/UnitTest/Test.h"
+
+#include <stdio.h>
+
+TEST(LlvmLibcStdio, SimpleOperations) {
+ constexpr char FILENAME[] = "testdata/simple_operations.test";
+ ::FILE *file = __llvm_libc::fopen(FILENAME, "w");
+ ASSERT_FALSE(file == nullptr);
+ constexpr char CONTENT[] = "1234567890987654321";
+ ASSERT_EQ(sizeof(CONTENT) - 1,
+ __llvm_libc::fwrite(CONTENT, 1, sizeof(CONTENT) - 1, file));
+ ASSERT_EQ(0, __llvm_libc::fclose(file));
+
+ file = __llvm_libc::fopen(FILENAME, "r");
+ ASSERT_FALSE(file == nullptr);
+
+ constexpr size_t READ_SIZE = 5;
+ char data[READ_SIZE];
+ data[READ_SIZE - 1] = '\0';
+ ASSERT_EQ(__llvm_libc::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);
+ ASSERT_STREQ(data, "1234");
+ ASSERT_EQ(__llvm_libc::fseek(file, 5, SEEK_CUR), 0);
+ ASSERT_EQ(__llvm_libc::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);
+ ASSERT_STREQ(data, "0987");
+ ASSERT_EQ(__llvm_libc::fseek(file, -5, SEEK_CUR), 0);
+ ASSERT_EQ(__llvm_libc::fread(data, 1, READ_SIZE - 1, file), READ_SIZE - 1);
+ ASSERT_STREQ(data, "9098");
+
+ ASSERT_EQ(__llvm_libc::fclose(file), 0);
+}
diff --git a/libc/test/src/stdio/fwrite_test.cpp b/libc/test/src/stdio/fwrite_test.cpp
deleted file mode 100644
index 9d38d84f160ba..0000000000000
--- a/libc/test/src/stdio/fwrite_test.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//===-- Unittests for fwrite ----------------------------------------------===//
-//
-// 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/__support/CPP/Array.h"
-#include "src/stdio/FILE.h"
-#include "src/stdio/fwrite.h"
-#include "utils/UnitTest/Test.h"
-
-TEST(LlvmLibcStdio, FWriteBasic) {
- struct StrcpyFile : __llvm_libc::FILE {
- char *buf;
- } f;
- char array[6];
- f.buf = array;
- f.write = +[](__llvm_libc::FILE *file, const char *ptr, size_t size) {
- StrcpyFile *strcpyFile = static_cast<StrcpyFile *>(file);
- for (size_t i = 0; i < size; ++i)
- strcpyFile->buf[i] = ptr[i];
- return size;
- };
- EXPECT_EQ(fwrite("hello", 1, 6, &f), 6UL);
- EXPECT_STREQ(array, "hello");
-}
diff --git a/libc/test/src/stdio/testdata/CMakeLists.txt b/libc/test/src/stdio/testdata/CMakeLists.txt
new file mode 100644
index 0000000000000..e69de29bb2d1d
More information about the libc-commits
mailing list