diff --git a/vlib/os/const_nix.c.v b/vlib/os/const_nix.c.v index 70311303ae..dcacdd22da 100644 --- a/vlib/os/const_nix.c.v +++ b/vlib/os/const_nix.c.v @@ -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. diff --git a/vlib/os/const_windows.c.v b/vlib/os/const_windows.c.v index d7b2436ee8..985458ac07 100644 --- a/vlib/os/const_windows.c.v +++ b/vlib/os/const_windows.c.v @@ -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) diff --git a/vlib/os/os.v b/vlib/os/os.v index f3115e005e..93db502168 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -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 } diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index b84c924004..b97a4171ca 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -4,23 +4,23 @@ const ( // tfolder will contain all the temporary files/subfolders made by // the different tests. It would be removed in testsuite_end(), so // 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() { eprintln('testsuite_begin, tfolder = $tfolder') - os.rmdir_all( tfolder ) - assert !os.is_dir( tfolder ) - os.mkdir_all( tfolder ) - os.chdir( tfolder ) - assert os.is_dir( tfolder ) + os.rmdir_all(tfolder) + assert !os.is_dir(tfolder) + os.mkdir_all(tfolder) + os.chdir(tfolder) + assert os.is_dir(tfolder) } fn testsuite_end() { - os.chdir( os.wd_at_startup ) - os.rmdir_all( tfolder ) - assert !os.is_dir( tfolder ) - //eprintln('testsuite_end , tfolder = $tfolder removed.') + os.chdir(os.wd_at_startup) + os.rmdir_all(tfolder) + assert !os.is_dir(tfolder) + // eprintln('testsuite_end , tfolder = $tfolder removed.') } fn test_open_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,12 +71,16 @@ 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') - //eprintln('line2: $line2') + // eprintln('line1: $line1') + // eprintln('line2: $line2') assert line1 == 'line 1\n' assert line2 == 'line 2' } @@ -74,9 +99,9 @@ fn test_create_file() { fn test_is_file() { // 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) - tfile := os.join_path(work_dir,'tmp_file') + tfile := os.join_path(work_dir, 'tmp_file') // Test things that shouldn't be a file assert os.is_file(work_dir) == false assert os.is_file('non-existent_file.tmp') == false @@ -88,7 +113,7 @@ fn test_is_file() { $if windows { assert true } $else { - dsymlink := os.join_path(work_dir,'dir_symlink') + dsymlink := os.join_path(work_dir, 'dir_symlink') os.system('ln -s $work_dir $dsymlink') assert os.is_file(dsymlink) == false } @@ -96,7 +121,7 @@ fn test_is_file() { $if windows { assert true } $else { - fsymlink := os.join_path(work_dir,'file_symlink') + fsymlink := os.join_path(work_dir, 'file_symlink') os.system('ln -s $tfile $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 // read_bytes, read_bytes_at and write_bytes. fn test_write_and_read_bytes() { - file_name := './byte_reader_writer.tst' - payload := [byte(`I`), `D`, `D`, `Q`, `D`] - + 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) @@ -212,42 +228,42 @@ fn test_cp() { } 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) // Setup test files - tfile1 := os.join_path(work_dir,'file') - tfile2 := os.join_path(work_dir,'file.test') - tfile3 := os.join_path(work_dir,'file.3') + tfile1 := os.join_path(work_dir, 'file') + tfile2 := os.join_path(work_dir, 'file.test') + tfile3 := os.join_path(work_dir, 'file.3') tfile_content := 'temporary file' os.write_file(tfile1, tfile_content) os.write_file(tfile2, tfile_content) // Setup test dirs - tdir1 := os.join_path(work_dir,'dir') - tdir2 := os.join_path(work_dir,'dir2') - tdir3 := os.join_path(work_dir,'dir3') + tdir1 := os.join_path(work_dir, 'dir') + tdir2 := os.join_path(work_dir, 'dir2') + tdir3 := os.join_path(work_dir, 'dir3') mkdir(tdir1) mkdir(tdir2) // Move file with no extension to dir - os.mv(tfile1,tdir1) - mut expected := os.join_path(tdir1,'file') + os.mv(tfile1, tdir1) + mut expected := os.join_path(tdir1, 'file') assert os.exists(expected) && !is_dir(expected) == true // Move dir with contents to other dir - os.mv(tdir1,tdir2) - expected = os.join_path(tdir2,'dir') + os.mv(tdir1, tdir2) + expected = os.join_path(tdir2, 'dir') 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 // 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 assert os.exists(expected) && is_dir(expected) == true assert os.is_dir_empty(tdir2) == true // Move file with extension to dir - os.mv(tfile2,tdir2) - expected = os.join_path(tdir2,'file.test') + os.mv(tfile2, tdir2) + expected = os.join_path(tdir2, 'file.test') assert os.exists(expected) && !is_dir(expected) == true // 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 assert os.exists(expected) && !is_dir(expected) == true } @@ -415,9 +431,9 @@ fn test_is_abs() { fn test_join() { $if windows { - assert os.join_path('v','vlib','os') == 'v\\vlib\\os' + assert os.join_path('v', 'vlib', 'os') == 'v\\vlib\\os' } $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) } assert arr == rarr - //eprintln(arr.str()) - //eprintln(rarr.str()) + // eprintln(arr.str()) + // eprintln(rarr.str()) } fn test_write_file_array_structs() { @@ -483,5 +499,5 @@ fn test_write_file_array_structs() { rarr := os.read_file_array(fpath) assert rarr == arr assert rarr.len == maxn - //eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n')) + // eprintln( rarr.str().replace('\n', ' ').replace('},', '},\n')) }