Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix File#pos, File#seek and File#truncate over 2G on Windows #9015

Merged
merged 1 commit into from
Apr 9, 2020
Merged

Fix File#pos, File#seek and File#truncate over 2G on Windows #9015

merged 1 commit into from
Apr 9, 2020

Conversation

kubo
Copy link
Contributor

@kubo kubo commented Apr 8, 2020

_lseek and _chsize cannot handle files bigger than 2G because they use Long, whose maximum size is 2G on Windows. This commit uses _lseeki64 and _chsize_s instead.

@straight-shoota straight-shoota added platform:windows Windows support based on the MSVC toolchain / Win32 API topic:stdlib:files labels Apr 8, 2020
@@ -212,8 +212,8 @@ module Crystal::System::File
end
end

private def system_truncate(size : Int) : Nil
if LibC._chsize(fd, size) != 0
private def system_truncate(size) : Nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the Int restriction gone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because I'm a newbie about crystal and I didn't know that Int was the base type of all integer types.

I thought that Int was 32-bit by analogy with C and changed the restriction from Int to Int64 at first because the size argument is passed to the Int64 argument of LibC._chsize_s(). However I got an error by the following code.

File.open("test-file.txt", "w") do |file|
  file << "123456789012345678901234567890"
  file.truncate(20)
end
$ ./crystal/.build/crystal build --cross-compile --target x86_64-pc-windows-msvc "$@" trunc-test.cr 
Showing last frame. Use --error-trace for full trace.

In crystal/src/file.cr:763:5

 763 | system_truncate(size)
       ^--------------
Error: no overload matches 'File#system_truncate' with type Int32

Overloads are:
 - Crystal::System::File#system_truncate(size : Int64)

I could not imagine the error reason. I checked the definition of system_truncate in src/crystal/system/unix/file.cr and found that it didn't have such restriction. So I removed the restriction and it worked. I made a pull request after that.

I just now checked that it worked with the Int restriction. Should I revert the change at the line and push a commit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please!

Int is not well named, it should be named Integer. I hope we can rename it in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed 5c20b89. Is it Okay?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, thank you!

_lseek and _chsize cannot handle files bigger than 2G because they
use Long, whose maximum size is 2G on Windows.
This commit uses _lseeki64 and _chsize_s instead.
@RX14 RX14 added this to the 0.35.0 milestone Apr 9, 2020
@RX14 RX14 merged commit 7e2e840 into crystal-lang:master Apr 9, 2020
carlhoerberg pushed a commit to carlhoerberg/crystal that referenced this pull request Apr 29, 2020
…-lang#9015)

_lseek and _chsize cannot handle files bigger than 2G because they
use Long, whose maximum size is 2G on Windows.
This commit uses _lseeki64 and _chsize_s instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform:windows Windows support based on the MSVC toolchain / Win32 API topic:stdlib:files
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants