diff --git a/vlib/os/os.v b/vlib/os/os.v index ee225125fc..bfa316b12b 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -71,6 +71,8 @@ fn C.ftell(fp voidptr) int fn C.getenv(byteptr) byteptr fn C.sigaction(int, voidptr, int) +fn C.GetLastError() u32 + // read_bytes reads an amount of bytes from the beginning of the file pub fn (f File) read_bytes(size int) []byte { return f.read_bytes_at(size, 0) @@ -126,13 +128,25 @@ pub fn mv(old, new string) { } } -// TODO implement actual cp() -pub fn cp(old, new string) { +fn C.CopyFile(&u32, &u32, int) int + +// TODO implement actual cp for linux +pub fn cp(old, new string) ?bool { $if windows { - panic('not implemented') - } $else { + _old := old.replace('/', '\\') + _new := new.replace('/', '\\') + C.CopyFile(_old.to_wide(), _new.to_wide(), false) + + result := C.GetLastError() + if result == 0 { + return true + } else { + return error_with_code('failed to copy $old to $new', int(result)) + } + } $else { os.system('cp $old $new') - } + return true // TODO make it return true or error when cp for linux is implemented + } } fn vfopen(path, mode string) *C.FILE { diff --git a/vlib/os/os_test.v b/vlib/os/os_test.v index b551c60e83..9fa5a11c31 100644 --- a/vlib/os/os_test.v +++ b/vlib/os/os_test.v @@ -113,6 +113,23 @@ fn test_walk() { os.rmdir(folder) } +fn test_cp() { + $if windows { + old_file_name := './example.txt' + new_file_name := './new_example.txt' + + os.write_file(old_file_name, 'Test data 1 2 3, V is awesome #$%^[]!~⭐') + result := os.cp(old_file_name, new_file_name) or { panic('$err: errcode: $errcode') } + + old_file := os.read_file(old_file_name) or { panic(err) } + new_file := os.read_file(new_file_name) or { panic(err) } + assert old_file == new_file + + os.rm(old_file_name) + os.rm(new_file_name) + } +} + //fn test_fork() { // pid := os.fork() // if pid == 0 { diff --git a/vlib/os/os_windows.v b/vlib/os/os_windows.v index 28b8e19505..a06d04b1b1 100644 --- a/vlib/os/os_windows.v +++ b/vlib/os/os_windows.v @@ -61,7 +61,7 @@ pub fn ls(path string) ?[]string { // } // C.FindClose(h_find_dir) if !dir_exists(path) { - return error('ls() couldnt open dir "$path"') + return error('ls() couldnt open dir "$path": directory does not exist') } // NOTE: Should eventually have path struct & os dependant path seperator (eg os.PATH_SEPERATOR) // we need to add files to path eg. c:\windows\*.dll or :\windows\*