[libc-commits] [libc] a0f6d12 - [libc][File] Fix a bug under fseek(..., SEEK_CUR).

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Wed Mar 23 09:24:31 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-03-23T16:24:15Z
New Revision: a0f6d12cd482fa37713aff2f34d1aee05766d2ca

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

LOG: [libc][File] Fix a bug under fseek(..., SEEK_CUR).

Reviewed By: lntue

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

Added: 
    

Modified: 
    libc/src/__support/File/CMakeLists.txt
    libc/src/__support/File/file.cpp
    libc/test/src/__support/File/file_test.cpp
    libc/test/src/__support/File/platform_file_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/File/CMakeLists.txt b/libc/src/__support/File/CMakeLists.txt
index 6a202649cbbad..5870ebb556a6d 100644
--- a/libc/src/__support/File/CMakeLists.txt
+++ b/libc/src/__support/File/CMakeLists.txt
@@ -25,6 +25,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}_file.cpp)
       .file
       libc.include.errno
       libc.include.fcntl
+      libc.include.stdio
       libc.include.sys_syscall
       libc.src.__support.OSUtil.osutil
       libc.src.errno.errno

diff  --git a/libc/src/__support/File/file.cpp b/libc/src/__support/File/file.cpp
index ed765f5c88321..3f2928c5c32e3 100644
--- a/libc/src/__support/File/file.cpp
+++ b/libc/src/__support/File/file.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/CPP/ArrayRef.h"
 
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 namespace __llvm_libc {
@@ -143,6 +144,11 @@ int File::seek(long offset, int whence) {
       err = true;
       return -1;
     }
+  } else if (prev_op == FileOp::READ && whence == SEEK_CUR) {
+    // More data could have been read out from the platform file than was
+    // required. So, we have to adjust the offset we pass to platform seek
+    // function. Note that read_limit >= pos is always true.
+    offset -= (read_limit - pos);
   }
   pos = read_limit = 0;
   prev_op = FileOp::SEEK;

diff  --git a/libc/test/src/__support/File/file_test.cpp b/libc/test/src/__support/File/file_test.cpp
index 0667f5f615314..d7bdeb7a2ba19 100644
--- a/libc/test/src/__support/File/file_test.cpp
+++ b/libc/test/src/__support/File/file_test.cpp
@@ -194,6 +194,27 @@ TEST(LlvmLibcFileTest, ReadOnly) {
   ASSERT_EQ(f->close(), 0);
 }
 
+TEST(LlvmLibcFileTest, ReadSeekCurAndRead) {
+  const char initial_content[] = "1234567890987654321";
+  constexpr size_t FILE_BUFFER_SIZE = sizeof(initial_content);
+  char file_buffer[FILE_BUFFER_SIZE];
+  StringFile *f = new_string_file(file_buffer, FILE_BUFFER_SIZE, 0, false, "r");
+  f->reset_and_fill(initial_content, sizeof(initial_content));
+
+  constexpr size_t READ_SIZE = 5;
+  char data[READ_SIZE];
+  data[READ_SIZE - 1] = '\0';
+  ASSERT_EQ(f->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "1234");
+  ASSERT_EQ(f->seek(5, SEEK_CUR), 0);
+  ASSERT_EQ(f->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "0987");
+  ASSERT_EQ(f->seek(-5, SEEK_CUR), 0);
+  ASSERT_EQ(f->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "9098");
+  ASSERT_EQ(f->close(), 0);
+}
+
 TEST(LlvmLibcFileTest, AppendOnly) {
   const char initial_content[] = "1234567890987654321";
   const char write_data[] = "append";

diff  --git a/libc/test/src/__support/File/platform_file_test.cpp b/libc/test/src/__support/File/platform_file_test.cpp
index 55909806fb16d..0ad0efc19cf59 100644
--- a/libc/test/src/__support/File/platform_file_test.cpp
+++ b/libc/test/src/__support/File/platform_file_test.cpp
@@ -144,6 +144,32 @@ TEST(LlvmLibcPlatformFileTest, LargeFile) {
   ASSERT_EQ(file->close(), 0);
 }
 
+TEST(LlvmLibcPlatformFileTest, ReadSeekCurAndRead) {
+  constexpr char FILENAME[] = "testdata/read_seek_cur_and_read.test";
+  File *file = __llvm_libc::openfile(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+  constexpr char CONTENT[] = "1234567890987654321";
+  ASSERT_EQ(sizeof(CONTENT) - 1, file->write(CONTENT, sizeof(CONTENT) - 1));
+  ASSERT_EQ(0, file->close());
+
+  file = __llvm_libc::openfile(FILENAME, "r");
+  ASSERT_FALSE(file == nullptr);
+
+  constexpr size_t READ_SIZE = 5;
+  char data[READ_SIZE];
+  data[READ_SIZE - 1] = '\0';
+  ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "1234");
+  ASSERT_EQ(file->seek(5, SEEK_CUR), 0);
+  ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "0987");
+  ASSERT_EQ(file->seek(-5, SEEK_CUR), 0);
+  ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
+  ASSERT_STREQ(data, "9098");
+
+  ASSERT_EQ(file->close(), 0);
+}
+
 TEST(LlvmLibcPlatformFileTest, IncorrectOperation) {
   constexpr char FILENAME[] = "testdata/incorrect_operation.test";
   char data[1] = {123};


        


More information about the libc-commits mailing list