os: fix binary mode read/write on windows (#6431)

pull/6434/head
Marcin 2020-09-20 16:28:45 +02:00 committed by GitHub
parent 3454677eb9
commit 34884c1631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 50 deletions

View File

@ -6,6 +6,7 @@ const (
o_wronly = 000000001 // open the file write-only.
o_rdwr = 000000002 // open the file read-write.
o_create = 000000100 // create a new file if none exists.
o_binary = 000008000 // input and output is not translated.
o_excl = 000000200 // used with o_create, file must not exist.
o_noctty = 000000400 // if file is terminal, don't make it the controller terminal
o_trunc = 000001000 // truncate regular writable file when opened.

View File

@ -100,6 +100,7 @@ const (
o_rdwr = 0x0002 // open the file read-write.
o_append = 0x0008 // append data to the file when writing.
o_create = 0x0100 // create a new file if none exists.
o_binary = 0x8000 // input and output is not translated.
o_trunc = 0x0200 // truncate regular writable file when opened.
o_excl = 0x0400 // used with o_create, file must not exist.
o_sync = 0x0000 // open for synchronous I/O (ignored on Windows)

View File

@ -267,6 +267,7 @@ pub fn open_file(path string, mode string, options ...int) ?File {
match m {
`r` { flags |= o_rdonly }
`w` { flags |= o_create | o_trunc }
`b` { flags |= o_binary }
`a` { flags |= o_create | o_append }
`s` { flags |= o_sync }
`n` { flags |= o_nonblock }

View File

@ -43,6 +43,27 @@ fn test_open_file() {
os.rm(filename)
}
fn test_open_file_binary() {
filename := './test1.dat'
hello := 'hello \n world!'
os.open_file(filename, 'r+', 0o666) or {
assert err == 'No such file or directory'
os.File{}
}
mut file := os.open_file(filename, 'wb+', 0o666) or {
panic(err)
}
bytes := hello.bytes()
file.write_bytes(bytes.data, bytes.len)
file.close()
assert hello.len == os.file_size(filename)
read_hello := os.read_bytes(filename) or {
panic('error reading file $filename')
}
assert bytes == read_hello
os.rm(filename)
}
fn test_file_get_line() {
filename := './fgetline.txt'
os.write_file(filename, 'line 1\nline 2')
@ -50,8 +71,12 @@ fn test_file_get_line() {
assert false
return
}
line1 := f.get_line() or { '' }
line2 := f.get_line() or { '' }
line1 := f.get_line() or {
''
}
line2 := f.get_line() or {
''
}
f.close()
//
// eprintln('line1: $line1')
@ -119,33 +144,25 @@ fn test_write_and_read_string_to_file() {
fn test_write_and_read_bytes() {
file_name := './byte_reader_writer.tst'
payload := [byte(`I`), `D`, `D`, `Q`, `D`]
mut file_write := os.create(os.real_path(file_name)) or {
eprintln('failed to create file $file_name')
return
}
// We use the standard write_bytes function to write the payload and
// compare the length of the array with the file size (have to match).
file_write.write_bytes(payload.data, 5)
file_write.close()
assert payload.len == os.file_size(file_name)
mut file_read := os.open(os.real_path(file_name)) or {
eprintln('failed to open file $file_name')
return
}
// We only need to test read_bytes because this function calls
// read_bytes_at with second parameter zeroed (size, 0).
rbytes := file_read.read_bytes(5)
// eprintln('rbytes: $rbytes')
// eprintln('payload: $payload')
assert rbytes == payload
// check that trying to read data from EOF doesn't error and returns 0
mut a := []byte{len: 5}
nread := file_read.read_bytes_into(5, a) or {
@ -153,7 +170,6 @@ fn test_write_and_read_bytes() {
int(-1)
}
assert nread == 0
file_read.close()
// We finally delete the test file.
os.rm(file_name)