os: fix binary mode read/write on windows (#6431)
parent
3454677eb9
commit
34884c1631
|
@ -6,6 +6,7 @@ const (
|
||||||
o_wronly = 000000001 // open the file write-only.
|
o_wronly = 000000001 // open the file write-only.
|
||||||
o_rdwr = 000000002 // open the file read-write.
|
o_rdwr = 000000002 // open the file read-write.
|
||||||
o_create = 000000100 // create a new file if none exists.
|
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_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_noctty = 000000400 // if file is terminal, don't make it the controller terminal
|
||||||
o_trunc = 000001000 // truncate regular writable file when opened.
|
o_trunc = 000001000 // truncate regular writable file when opened.
|
||||||
|
|
|
@ -100,6 +100,7 @@ const (
|
||||||
o_rdwr = 0x0002 // open the file read-write.
|
o_rdwr = 0x0002 // open the file read-write.
|
||||||
o_append = 0x0008 // append data to the file when writing.
|
o_append = 0x0008 // append data to the file when writing.
|
||||||
o_create = 0x0100 // create a new file if none exists.
|
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_trunc = 0x0200 // truncate regular writable file when opened.
|
||||||
o_excl = 0x0400 // used with o_create, file must not exist.
|
o_excl = 0x0400 // used with o_create, file must not exist.
|
||||||
o_sync = 0x0000 // open for synchronous I/O (ignored on Windows)
|
o_sync = 0x0000 // open for synchronous I/O (ignored on Windows)
|
||||||
|
|
|
@ -267,6 +267,7 @@ pub fn open_file(path string, mode string, options ...int) ?File {
|
||||||
match m {
|
match m {
|
||||||
`r` { flags |= o_rdonly }
|
`r` { flags |= o_rdonly }
|
||||||
`w` { flags |= o_create | o_trunc }
|
`w` { flags |= o_create | o_trunc }
|
||||||
|
`b` { flags |= o_binary }
|
||||||
`a` { flags |= o_create | o_append }
|
`a` { flags |= o_create | o_append }
|
||||||
`s` { flags |= o_sync }
|
`s` { flags |= o_sync }
|
||||||
`n` { flags |= o_nonblock }
|
`n` { flags |= o_nonblock }
|
||||||
|
|
|
@ -4,23 +4,23 @@ const (
|
||||||
// tfolder will contain all the temporary files/subfolders made by
|
// tfolder will contain all the temporary files/subfolders made by
|
||||||
// the different tests. It would be removed in testsuite_end(), so
|
// the different tests. It would be removed in testsuite_end(), so
|
||||||
// individual os tests do not need to clean up after themselves.
|
// individual os tests do not need to clean up after themselves.
|
||||||
tfolder = os.join_path( os.temp_dir(), 'v', 'tests', 'os_test')
|
tfolder = os.join_path(os.temp_dir(), 'v', 'tests', 'os_test')
|
||||||
)
|
)
|
||||||
|
|
||||||
fn testsuite_begin() {
|
fn testsuite_begin() {
|
||||||
eprintln('testsuite_begin, tfolder = $tfolder')
|
eprintln('testsuite_begin, tfolder = $tfolder')
|
||||||
os.rmdir_all( tfolder )
|
os.rmdir_all(tfolder)
|
||||||
assert !os.is_dir( tfolder )
|
assert !os.is_dir(tfolder)
|
||||||
os.mkdir_all( tfolder )
|
os.mkdir_all(tfolder)
|
||||||
os.chdir( tfolder )
|
os.chdir(tfolder)
|
||||||
assert os.is_dir( tfolder )
|
assert os.is_dir(tfolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testsuite_end() {
|
fn testsuite_end() {
|
||||||
os.chdir( os.wd_at_startup )
|
os.chdir(os.wd_at_startup)
|
||||||
os.rmdir_all( tfolder )
|
os.rmdir_all(tfolder)
|
||||||
assert !os.is_dir( tfolder )
|
assert !os.is_dir(tfolder)
|
||||||
//eprintln('testsuite_end , tfolder = $tfolder removed.')
|
// eprintln('testsuite_end , tfolder = $tfolder removed.')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_open_file() {
|
fn test_open_file() {
|
||||||
|
@ -43,6 +43,27 @@ fn test_open_file() {
|
||||||
os.rm(filename)
|
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() {
|
fn test_file_get_line() {
|
||||||
filename := './fgetline.txt'
|
filename := './fgetline.txt'
|
||||||
os.write_file(filename, 'line 1\nline 2')
|
os.write_file(filename, 'line 1\nline 2')
|
||||||
|
@ -50,12 +71,16 @@ fn test_file_get_line() {
|
||||||
assert false
|
assert false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
line1 := f.get_line() or { '' }
|
line1 := f.get_line() or {
|
||||||
line2 := f.get_line() or { '' }
|
''
|
||||||
|
}
|
||||||
|
line2 := f.get_line() or {
|
||||||
|
''
|
||||||
|
}
|
||||||
f.close()
|
f.close()
|
||||||
//
|
//
|
||||||
//eprintln('line1: $line1')
|
// eprintln('line1: $line1')
|
||||||
//eprintln('line2: $line2')
|
// eprintln('line2: $line2')
|
||||||
assert line1 == 'line 1\n'
|
assert line1 == 'line 1\n'
|
||||||
assert line2 == 'line 2'
|
assert line2 == 'line 2'
|
||||||
}
|
}
|
||||||
|
@ -74,9 +99,9 @@ fn test_create_file() {
|
||||||
|
|
||||||
fn test_is_file() {
|
fn test_is_file() {
|
||||||
// Setup
|
// Setup
|
||||||
work_dir := os.join_path(os.getwd(),'is_file_test')
|
work_dir := os.join_path(os.getwd(), 'is_file_test')
|
||||||
os.mkdir_all(work_dir)
|
os.mkdir_all(work_dir)
|
||||||
tfile := os.join_path(work_dir,'tmp_file')
|
tfile := os.join_path(work_dir, 'tmp_file')
|
||||||
// Test things that shouldn't be a file
|
// Test things that shouldn't be a file
|
||||||
assert os.is_file(work_dir) == false
|
assert os.is_file(work_dir) == false
|
||||||
assert os.is_file('non-existent_file.tmp') == false
|
assert os.is_file('non-existent_file.tmp') == false
|
||||||
|
@ -88,7 +113,7 @@ fn test_is_file() {
|
||||||
$if windows {
|
$if windows {
|
||||||
assert true
|
assert true
|
||||||
} $else {
|
} $else {
|
||||||
dsymlink := os.join_path(work_dir,'dir_symlink')
|
dsymlink := os.join_path(work_dir, 'dir_symlink')
|
||||||
os.system('ln -s $work_dir $dsymlink')
|
os.system('ln -s $work_dir $dsymlink')
|
||||||
assert os.is_file(dsymlink) == false
|
assert os.is_file(dsymlink) == false
|
||||||
}
|
}
|
||||||
|
@ -96,7 +121,7 @@ fn test_is_file() {
|
||||||
$if windows {
|
$if windows {
|
||||||
assert true
|
assert true
|
||||||
} $else {
|
} $else {
|
||||||
fsymlink := os.join_path(work_dir,'file_symlink')
|
fsymlink := os.join_path(work_dir, 'file_symlink')
|
||||||
os.system('ln -s $tfile $fsymlink')
|
os.system('ln -s $tfile $fsymlink')
|
||||||
assert os.is_file(fsymlink)
|
assert os.is_file(fsymlink)
|
||||||
}
|
}
|
||||||
|
@ -117,35 +142,27 @@ fn test_write_and_read_string_to_file() {
|
||||||
// test_write_and_read_bytes checks for regressions made in the functions
|
// test_write_and_read_bytes checks for regressions made in the functions
|
||||||
// read_bytes, read_bytes_at and write_bytes.
|
// read_bytes, read_bytes_at and write_bytes.
|
||||||
fn test_write_and_read_bytes() {
|
fn test_write_and_read_bytes() {
|
||||||
file_name := './byte_reader_writer.tst'
|
file_name := './byte_reader_writer.tst'
|
||||||
payload := [byte(`I`), `D`, `D`, `Q`, `D`]
|
payload := [byte(`I`), `D`, `D`, `Q`, `D`]
|
||||||
|
|
||||||
mut file_write := os.create(os.real_path(file_name)) or {
|
mut file_write := os.create(os.real_path(file_name)) or {
|
||||||
eprintln('failed to create file $file_name')
|
eprintln('failed to create file $file_name')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// We use the standard write_bytes function to write the payload and
|
// 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).
|
// compare the length of the array with the file size (have to match).
|
||||||
file_write.write_bytes(payload.data, 5)
|
file_write.write_bytes(payload.data, 5)
|
||||||
|
|
||||||
file_write.close()
|
file_write.close()
|
||||||
|
|
||||||
assert payload.len == os.file_size(file_name)
|
assert payload.len == os.file_size(file_name)
|
||||||
|
|
||||||
mut file_read := os.open(os.real_path(file_name)) or {
|
mut file_read := os.open(os.real_path(file_name)) or {
|
||||||
eprintln('failed to open file $file_name')
|
eprintln('failed to open file $file_name')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only need to test read_bytes because this function calls
|
// We only need to test read_bytes because this function calls
|
||||||
// read_bytes_at with second parameter zeroed (size, 0).
|
// read_bytes_at with second parameter zeroed (size, 0).
|
||||||
rbytes := file_read.read_bytes(5)
|
rbytes := file_read.read_bytes(5)
|
||||||
|
|
||||||
// eprintln('rbytes: $rbytes')
|
// eprintln('rbytes: $rbytes')
|
||||||
// eprintln('payload: $payload')
|
// eprintln('payload: $payload')
|
||||||
assert rbytes == payload
|
assert rbytes == payload
|
||||||
|
|
||||||
// check that trying to read data from EOF doesn't error and returns 0
|
// check that trying to read data from EOF doesn't error and returns 0
|
||||||
mut a := []byte{len: 5}
|
mut a := []byte{len: 5}
|
||||||
nread := file_read.read_bytes_into(5, a) or {
|
nread := file_read.read_bytes_into(5, a) or {
|
||||||
|
@ -153,7 +170,6 @@ fn test_write_and_read_bytes() {
|
||||||
int(-1)
|
int(-1)
|
||||||
}
|
}
|
||||||
assert nread == 0
|
assert nread == 0
|
||||||
|
|
||||||
file_read.close()
|
file_read.close()
|
||||||
// We finally delete the test file.
|
// We finally delete the test file.
|
||||||
os.rm(file_name)
|
os.rm(file_name)
|
||||||
|
@ -212,42 +228,42 @@ fn test_cp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_mv() {
|
fn test_mv() {
|
||||||
work_dir := os.join_path(os.getwd(),'mv_test')
|
work_dir := os.join_path(os.getwd(), 'mv_test')
|
||||||
os.mkdir_all(work_dir)
|
os.mkdir_all(work_dir)
|
||||||
// Setup test files
|
// Setup test files
|
||||||
tfile1 := os.join_path(work_dir,'file')
|
tfile1 := os.join_path(work_dir, 'file')
|
||||||
tfile2 := os.join_path(work_dir,'file.test')
|
tfile2 := os.join_path(work_dir, 'file.test')
|
||||||
tfile3 := os.join_path(work_dir,'file.3')
|
tfile3 := os.join_path(work_dir, 'file.3')
|
||||||
tfile_content := 'temporary file'
|
tfile_content := 'temporary file'
|
||||||
os.write_file(tfile1, tfile_content)
|
os.write_file(tfile1, tfile_content)
|
||||||
os.write_file(tfile2, tfile_content)
|
os.write_file(tfile2, tfile_content)
|
||||||
// Setup test dirs
|
// Setup test dirs
|
||||||
tdir1 := os.join_path(work_dir,'dir')
|
tdir1 := os.join_path(work_dir, 'dir')
|
||||||
tdir2 := os.join_path(work_dir,'dir2')
|
tdir2 := os.join_path(work_dir, 'dir2')
|
||||||
tdir3 := os.join_path(work_dir,'dir3')
|
tdir3 := os.join_path(work_dir, 'dir3')
|
||||||
mkdir(tdir1)
|
mkdir(tdir1)
|
||||||
mkdir(tdir2)
|
mkdir(tdir2)
|
||||||
// Move file with no extension to dir
|
// Move file with no extension to dir
|
||||||
os.mv(tfile1,tdir1)
|
os.mv(tfile1, tdir1)
|
||||||
mut expected := os.join_path(tdir1,'file')
|
mut expected := os.join_path(tdir1, 'file')
|
||||||
assert os.exists(expected) && !is_dir(expected) == true
|
assert os.exists(expected) && !is_dir(expected) == true
|
||||||
// Move dir with contents to other dir
|
// Move dir with contents to other dir
|
||||||
os.mv(tdir1,tdir2)
|
os.mv(tdir1, tdir2)
|
||||||
expected = os.join_path(tdir2,'dir')
|
expected = os.join_path(tdir2, 'dir')
|
||||||
assert os.exists(expected) && is_dir(expected) == true
|
assert os.exists(expected) && is_dir(expected) == true
|
||||||
expected = os.join_path(tdir2,'dir','file')
|
expected = os.join_path(tdir2, 'dir', 'file')
|
||||||
assert os.exists(expected) && !is_dir(expected) == true
|
assert os.exists(expected) && !is_dir(expected) == true
|
||||||
// Move dir with contents to other dir (by renaming)
|
// Move dir with contents to other dir (by renaming)
|
||||||
os.mv(os.join_path(tdir2,'dir'),tdir3)
|
os.mv(os.join_path(tdir2, 'dir'), tdir3)
|
||||||
expected = tdir3
|
expected = tdir3
|
||||||
assert os.exists(expected) && is_dir(expected) == true
|
assert os.exists(expected) && is_dir(expected) == true
|
||||||
assert os.is_dir_empty(tdir2) == true
|
assert os.is_dir_empty(tdir2) == true
|
||||||
// Move file with extension to dir
|
// Move file with extension to dir
|
||||||
os.mv(tfile2,tdir2)
|
os.mv(tfile2, tdir2)
|
||||||
expected = os.join_path(tdir2,'file.test')
|
expected = os.join_path(tdir2, 'file.test')
|
||||||
assert os.exists(expected) && !is_dir(expected) == true
|
assert os.exists(expected) && !is_dir(expected) == true
|
||||||
// Move file to dir (by renaming)
|
// Move file to dir (by renaming)
|
||||||
os.mv(os.join_path(tdir2,'file.test'),tfile3)
|
os.mv(os.join_path(tdir2, 'file.test'), tfile3)
|
||||||
expected = tfile3
|
expected = tfile3
|
||||||
assert os.exists(expected) && !is_dir(expected) == true
|
assert os.exists(expected) && !is_dir(expected) == true
|
||||||
}
|
}
|
||||||
|
@ -415,9 +431,9 @@ fn test_is_abs() {
|
||||||
|
|
||||||
fn test_join() {
|
fn test_join() {
|
||||||
$if windows {
|
$if windows {
|
||||||
assert os.join_path('v','vlib','os') == 'v\\vlib\\os'
|
assert os.join_path('v', 'vlib', 'os') == 'v\\vlib\\os'
|
||||||
} $else {
|
} $else {
|
||||||
assert os.join_path('v','vlib','os') == 'v/vlib/os'
|
assert os.join_path('v', 'vlib', 'os') == 'v/vlib/os'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,8 +485,8 @@ fn test_write_file_array_bytes() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
assert arr == rarr
|
assert arr == rarr
|
||||||
//eprintln(arr.str())
|
// eprintln(arr.str())
|
||||||
//eprintln(rarr.str())
|
// eprintln(rarr.str())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_write_file_array_structs() {
|
fn test_write_file_array_structs() {
|
||||||
|
@ -483,5 +499,5 @@ fn test_write_file_array_structs() {
|
||||||
rarr := os.read_file_array<IntPoint>(fpath)
|
rarr := os.read_file_array<IntPoint>(fpath)
|
||||||
assert rarr == arr
|
assert rarr == arr
|
||||||
assert rarr.len == maxn
|
assert rarr.len == maxn
|
||||||
//eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n'))
|
// eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n'))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue