[#106355] [Ruby master Bug#18373] RBS build failure: '/include/x86_64-linux/ruby/config.h', needed by 'constants.o'. — "vo.x (Vit Ondruch)" <noreply@...>
Issue #18373 has been reported by vo.x (Vit Ondruch).
28 messages
2021/12/01
[ruby-core:106493] [Ruby master Bug#18388] IO.copy_stream incompatibility between Ruby 2 and Ruby 3
From:
"yaojingguo (Jingguo Yao)" <noreply@...>
Date:
2021-12-05 08:23:24 UTC
List:
ruby-core #106493
Issue #18388 has been reported by yaojingguo (Jingguo Yao).
----------------------------------------
Bug #18388: IO.copy_stream incompatibility between Ruby 2 and Ruby 3
https://bugs.ruby-lang.org/issues/18388
* Author: yaojingguo (Jingguo Yao)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.0dev (2021-12-04T07:20:30Z hack 4a6ca12904) [x86_64-darwin19]
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
Put `test.rb`, `src` and dst in the same directory:
`test.rb` file:
``` ruby
src = "src"
dst = "dst"
File.open(dst, "ab", 0644) do |dst|
File.open(src, 'rb', 0644) do |src|
puts "src size: #{src.size()}, dst size: #{dst.size()}"
count = IO.copy_stream(src, dst)
puts "count: #{count}"
end
end
```
`src` file (file size is 3):
```
789
```
`dst` file (file size is 1):
```
2
```
Run `test.rb` with Ruby 2.6, the content of the resulted `dst` is:
```
2789
```
So the content of `src` is appended to `dst` with Ruby 2.6. In other words,
Open mode "a" is honored.
Run `test.rb` with Ruby 3, the content of the resulted `dst` is:
```
278
```
This behavior is different from Ruby 2.6.
The cause of the problem is `IO.copy_stream` uses `fcopyfile` function for Ruby 3.
If the following code from `io.c` is commented out, Ruby 3 has the same behavior
as Ruby 2.6.
```C
#ifdef HAVE_FCOPYFILE
ret = nogvl_fcopyfile(stp);
if (ret != 0)
goto finish; /* error or success */
#endif
```
[copyfile](https://keith.github.io/xcode-man-pages/copyfile.3.html):
```C
int fcopyfile(int from, int to, copyfile_state_t state, copyfile_flags_t flags);
```
`fcopyfile` appends `src` to `to` and then truncates `to` to it's original size.
The following code shows this behavior:
```C
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <copyfile.h>
int main() {
copyfile_state_t state;
state = copyfile_state_alloc();
int to;
to = open("to", O_APPEND | O_WRONLY, 0644);
if (to < 0) {
perror("open to");
return 1;
}
int from;
from = open("from", O_RDONLY);
if (from < 0) {
perror("open from");
return 1;
}
int ret;
ret = fcopyfile(from, to, state, COPYFILE_DATA);
if (ret != 0) {
perror("fcopyfile");
return 1;
}
off_t copied;
ret = copyfile_state_get(state, COPYFILE_STATE_COPIED, &copied);
if (ret != 0) {
perror("copyfile_state_get");
return 1;
}
printf("copied: %lld\n", copied);
copyfile_state_free(state);
}
```
The following table summarizes the results after running the above code:
|`from` | `to` | `to` after `fcopyfile` |
|--|--|--|
| 789 | 2 | 278 |
| 1 | 2 | 2 |
| 1 | 234 | 2 |
If this problem should be fixed, I am willing to do it provided with some
guidance from the community.
Here is the detailed version information:
- Ruby 2.6 version:
```
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]
```
- Ruby 3 version
```
ruby 3.1.0dev (2021-12-04T07:20:30Z master 4a6ca12904) [x86_64-darwin19]
```
- OS: macOS 10.15.5
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>