Index: include/lldb/Host/File.h =================================================================== --- include/lldb/Host/File.h +++ include/lldb/Host/File.h @@ -265,51 +265,6 @@ off_t SeekFromStart(off_t offset, Error *error_ptr = nullptr); //------------------------------------------------------------------ - /// Seek to an offset relative to the current file position. - /// - /// NOTE: This function is NOT thread safe, other threads that - /// access this object might also change the current file position. - /// For thread safe reads and writes see the following functions: - /// @see File::Read (void *, size_t, off_t &) - /// @see File::Write (const void *, size_t, off_t &) - /// - /// @param[in] offset - /// The offset to seek to within the file relative to the - /// current file position. - /// - /// @param[in] error_ptr - /// A pointer to a lldb_private::Error object that will be - /// filled in if non-nullptr. - /// - /// @return - /// The resulting seek offset, or -1 on error. - //------------------------------------------------------------------ - off_t SeekFromCurrent(off_t offset, Error *error_ptr = nullptr); - - //------------------------------------------------------------------ - /// Seek to an offset relative to the end of the file. - /// - /// NOTE: This function is NOT thread safe, other threads that - /// access this object might also change the current file position. - /// For thread safe reads and writes see the following functions: - /// @see File::Read (void *, size_t, off_t &) - /// @see File::Write (const void *, size_t, off_t &) - /// - /// @param[in,out] offset - /// The offset to seek to within the file relative to the - /// end of the file which gets filled in with the resulting - /// absolute file offset. - /// - /// @param[in] error_ptr - /// A pointer to a lldb_private::Error object that will be - /// filled in if non-nullptr. - /// - /// @return - /// The resulting seek offset, or -1 on error. - //------------------------------------------------------------------ - off_t SeekFromEnd(off_t offset, Error *error_ptr = nullptr); - - //------------------------------------------------------------------ /// Read bytes from a file from the specified file offset. /// /// NOTE: This function is thread safe in that clients manager their @@ -403,15 +358,6 @@ Error Flush(); //------------------------------------------------------------------ - /// Sync to disk. - /// - /// @return - /// An error object that indicates success or the reason for - /// failure. - //------------------------------------------------------------------ - Error Sync(); - - //------------------------------------------------------------------ /// Get the permissions for a this file. /// /// @return Index: source/Host/common/File.cpp =================================================================== --- source/Host/common/File.cpp +++ source/Host/common/File.cpp @@ -367,58 +367,6 @@ return result; } -off_t File::SeekFromCurrent(off_t offset, Error *error_ptr) { - off_t result = -1; - if (DescriptorIsValid()) { - result = ::lseek(m_descriptor, offset, SEEK_CUR); - - if (error_ptr) { - if (result == -1) - error_ptr->SetErrorToErrno(); - else - error_ptr->Clear(); - } - } else if (StreamIsValid()) { - result = ::fseek(m_stream, offset, SEEK_CUR); - - if (error_ptr) { - if (result == -1) - error_ptr->SetErrorToErrno(); - else - error_ptr->Clear(); - } - } else if (error_ptr) { - error_ptr->SetErrorString("invalid file handle"); - } - return result; -} - -off_t File::SeekFromEnd(off_t offset, Error *error_ptr) { - off_t result = -1; - if (DescriptorIsValid()) { - result = ::lseek(m_descriptor, offset, SEEK_END); - - if (error_ptr) { - if (result == -1) - error_ptr->SetErrorToErrno(); - else - error_ptr->Clear(); - } - } else if (StreamIsValid()) { - result = ::fseek(m_stream, offset, SEEK_END); - - if (error_ptr) { - if (result == -1) - error_ptr->SetErrorToErrno(); - else - error_ptr->Clear(); - } - } else if (error_ptr) { - error_ptr->SetErrorString("invalid file handle"); - } - return result; -} - Error File::Flush() { Error error; if (StreamIsValid()) { @@ -435,218 +383,103 @@ return error; } -Error File::Sync() { - Error error; - if (DescriptorIsValid()) { -#ifdef _WIN32 - int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor)); - if (err == 0) - error.SetErrorToGenericError(); -#else - int err = 0; - do { - err = ::fsync(m_descriptor); - } while (err == -1 && errno == EINTR); - - if (err == -1) - error.SetErrorToErrno(); -#endif - } else { - error.SetErrorString("invalid file handle"); - } - return error; -} - #if defined(__APPLE__) // Darwin kernels only can read/write <= INT_MAX bytes -#define MAX_READ_SIZE INT_MAX -#define MAX_WRITE_SIZE INT_MAX +constexpr size_t MAX_READ_SIZE = INT_MAX; +constexpr size_t MAX_WRITE_SIZE = INT_MAX; +#elif defined(LLVM_ON_WIN32) +constexpr size_t MAX_READ_SIZE = ULONG_MAX; +constexpr size_t MAX_WRITE_SIZE = ULONG_MAX; +#else +constexpr size_t MAX_READ_SIZE = SIZE_MAX; +constexpr size_t MAX_WRITE_SIZE = SIZE_MAX; #endif Error File::Read(void *buf, size_t &num_bytes) { - Error error; - -#if defined(MAX_READ_SIZE) - if (num_bytes > MAX_READ_SIZE) { - uint8_t *p = (uint8_t *)buf; - size_t bytes_left = num_bytes; - // Init the num_bytes read to zero + int fd = GetDescriptor(); + if (fd == kInvalidDescriptor) { num_bytes = 0; - - while (bytes_left > 0) { - size_t curr_num_bytes; - if (bytes_left > MAX_READ_SIZE) - curr_num_bytes = MAX_READ_SIZE; - else - curr_num_bytes = bytes_left; - - error = Read(p + num_bytes, curr_num_bytes); - - // Update how many bytes were read - num_bytes += curr_num_bytes; - if (bytes_left < curr_num_bytes) - bytes_left = 0; - else - bytes_left -= curr_num_bytes; - - if (error.Fail()) - break; - } - return error; + return Error("invalid file handle"); } -#endif - - ssize_t bytes_read = -1; - if (DescriptorIsValid()) { - do { - bytes_read = ::read(m_descriptor, buf, num_bytes); - } while (bytes_read < 0 && errno == EINTR); - - if (bytes_read == -1) { - error.SetErrorToErrno(); - num_bytes = 0; - } else - num_bytes = bytes_read; - } else if (StreamIsValid()) { - bytes_read = ::fread(buf, 1, num_bytes, m_stream); - if (bytes_read == 0) { - if (::feof(m_stream)) - error.SetErrorString("feof"); - else if (::ferror(m_stream)) - error.SetErrorString("ferror"); - num_bytes = 0; - } else - num_bytes = bytes_read; - } else { - num_bytes = 0; - error.SetErrorString("invalid file handle"); - } - return error; + off_t offset = lseek(fd, 0, SEEK_CUR); + return Read(buf, num_bytes, offset); } Error File::Write(const void *buf, size_t &num_bytes) { - Error error; - -#if defined(MAX_WRITE_SIZE) - if (num_bytes > MAX_WRITE_SIZE) { - const uint8_t *p = (const uint8_t *)buf; - size_t bytes_left = num_bytes; - // Init the num_bytes written to zero + int fd = GetDescriptor(); + if (fd == kInvalidDescriptor) { num_bytes = 0; - - while (bytes_left > 0) { - size_t curr_num_bytes; - if (bytes_left > MAX_WRITE_SIZE) - curr_num_bytes = MAX_WRITE_SIZE; - else - curr_num_bytes = bytes_left; - - error = Write(p + num_bytes, curr_num_bytes); - - // Update how many bytes were read - num_bytes += curr_num_bytes; - if (bytes_left < curr_num_bytes) - bytes_left = 0; - else - bytes_left -= curr_num_bytes; - - if (error.Fail()) - break; - } - return error; + return Error("invalid file handle"); } -#endif - ssize_t bytes_written = -1; - if (DescriptorIsValid()) { - do { - bytes_written = ::write(m_descriptor, buf, num_bytes); - } while (bytes_written < 0 && errno == EINTR); - - if (bytes_written == -1) { - error.SetErrorToErrno(); - num_bytes = 0; - } else - num_bytes = bytes_written; - } else if (StreamIsValid()) { - bytes_written = ::fwrite(buf, 1, num_bytes, m_stream); - - if (bytes_written == 0) { - if (::feof(m_stream)) - error.SetErrorString("feof"); - else if (::ferror(m_stream)) - error.SetErrorString("ferror"); - num_bytes = 0; - } else - num_bytes = bytes_written; - - } else { - num_bytes = 0; - error.SetErrorString("invalid file handle"); + off_t offset = lseek(fd, 0, SEEK_CUR); + if (m_options & File::eOpenOptionAppend) { + struct stat S; + if (::fstat(fd, &S) != 0) + return Error("Invalid file handle!"); + offset = S.st_size; } - - return error; + return Write(buf, num_bytes, offset); } Error File::Read(void *buf, size_t &num_bytes, off_t &offset) { Error error; - -#if defined(MAX_READ_SIZE) - if (num_bytes > MAX_READ_SIZE) { - uint8_t *p = (uint8_t *)buf; - size_t bytes_left = num_bytes; - // Init the num_bytes read to zero + size_t bytes_left = num_bytes; + int fd = GetDescriptor(); + if (fd == kInvalidDescriptor) { num_bytes = 0; - - while (bytes_left > 0) { - size_t curr_num_bytes; - if (bytes_left > MAX_READ_SIZE) - curr_num_bytes = MAX_READ_SIZE; - else - curr_num_bytes = bytes_left; - - error = Read(p + num_bytes, curr_num_bytes, offset); - - // Update how many bytes were read - num_bytes += curr_num_bytes; - if (bytes_left < curr_num_bytes) - bytes_left = 0; - else - bytes_left -= curr_num_bytes; - - if (error.Fail()) - break; - } - return error; + return Error("invalid file handle"); } -#endif + uint8_t *dest = static_cast(buf); #ifndef _WIN32 - int fd = GetDescriptor(); - if (fd != kInvalidDescriptor) { - ssize_t bytes_read = -1; + ssize_t bytes_read = -1; + size_t bytes_to_read = std::min(MAX_READ_SIZE, bytes_left); + while (bytes_left != 0 && bytes_read != 0) { do { - bytes_read = ::pread(fd, buf, num_bytes, offset); + bytes_read = ::pread(fd, dest, num_bytes, offset); } while (bytes_read < 0 && errno == EINTR); if (bytes_read < 0) { num_bytes = 0; error.SetErrorToErrno(); - } else { - offset += bytes_read; - num_bytes = bytes_read; + return error; } - } else { - num_bytes = 0; - error.SetErrorString("invalid file handle"); + + dest += bytes_read; + offset += bytes_read; + bytes_left -= bytes_read; } + num_bytes -= bytes_left; #else - long cur = ::lseek(m_descriptor, 0, SEEK_CUR); - SeekFromStart(offset); - error = Read(buf, num_bytes); - if (!error.Fail()) - SeekFromStart(cur); + HANDLE H = reinterpret_cast(_get_osfhandle(fd)); + if (!H || H == INVALID_HANDLE_VALUE) + return Error("invalid file handle"); + + LARGE_INTEGER large_off; + large_off.QuadPart = offset; + + OVERLAPPED OV = {}; + OV.Offset = large_off.LowPart; + OV.OffsetHigh = large_off.HighPart; + + while (bytes_left != 0) { + DWORD req_size = static_cast(std::min(MAX_READ_SIZE, bytes_left)); + DWORD actual_size = 0; + BOOL result = ::ReadFile(H, dest, req_size, &actual_size, &OV); + if (!result) { + error.SetError(GetLastError(), eErrorTypeWin32); + return error; + } + if (actual_size == 0) { + // EOF was reached. + break; + } + dest += actual_size; + bytes_left -= actual_size; + } + num_bytes -= bytes_left; #endif return error; } @@ -697,66 +530,56 @@ Error File::Write(const void *buf, size_t &num_bytes, off_t &offset) { Error error; - -#if defined(MAX_WRITE_SIZE) - if (num_bytes > MAX_WRITE_SIZE) { - const uint8_t *p = (const uint8_t *)buf; - size_t bytes_left = num_bytes; - // Init the num_bytes written to zero + size_t bytes_left = num_bytes; + int fd = GetDescriptor(); + if (fd == kInvalidDescriptor) { num_bytes = 0; - - while (bytes_left > 0) { - size_t curr_num_bytes; - if (bytes_left > MAX_WRITE_SIZE) - curr_num_bytes = MAX_WRITE_SIZE; - else - curr_num_bytes = bytes_left; - - error = Write(p + num_bytes, curr_num_bytes, offset); - - // Update how many bytes were read - num_bytes += curr_num_bytes; - if (bytes_left < curr_num_bytes) - bytes_left = 0; - else - bytes_left -= curr_num_bytes; - - if (error.Fail()) - break; - } - return error; + return Error("invalid file handle"); } -#endif - int fd = GetDescriptor(); - if (fd != kInvalidDescriptor) { + const uint8_t *src = static_cast(buf); #ifndef _WIN32 - ssize_t bytes_written = -1; + ssize_t bytes_written = -1; + size_t bytes_to_write = std::min(MAX_WRITE_SIZE, bytes_left); + while (bytes_left != 0) { do { - bytes_written = ::pwrite(m_descriptor, buf, num_bytes, offset); + bytes_written = ::pwrite(fd, src, num_bytes, offset); } while (bytes_written < 0 && errno == EINTR); if (bytes_written < 0) { num_bytes = 0; error.SetErrorToErrno(); - } else { - offset += bytes_written; - num_bytes = bytes_written; + return error; } -#else - long cur = ::lseek(m_descriptor, 0, SEEK_CUR); - error = Write(buf, num_bytes); - long after = ::lseek(m_descriptor, 0, SEEK_CUR); - if (!error.Fail()) - SeekFromStart(cur); - - offset = after; -#endif - } else { - num_bytes = 0; - error.SetErrorString("invalid file handle"); + src += bytes_written; + offset += bytes_written; + bytes_left -= bytes_written; } +#else + HANDLE H = reinterpret_cast(_get_osfhandle(fd)); + if (!H || H == INVALID_HANDLE_VALUE) + return Error("invalid file handle"); + + LARGE_INTEGER large_off; + large_off.QuadPart = offset; + + OVERLAPPED OV = {}; + OV.Offset = large_off.LowPart; + OV.OffsetHigh = large_off.HighPart; + + while (bytes_left != 0) { + DWORD req_size = static_cast(std::min(MAX_WRITE_SIZE, bytes_left)); + DWORD actual_size = 0; + BOOL result = ::WriteFile(H, src, req_size, &actual_size, &OV); + if (!result) { + error.SetError(GetLastError(), eErrorTypeWin32); + return error; + } + src += actual_size; + bytes_left -= actual_size; + } +#endif return error; }