From 15d9f50be9c0e2ff02eefc16b1a57ceb54372b53 Mon Sep 17 00:00:00 2001 From: Bastian Buck <59334447+bstnbuck@users.noreply.github.com> Date: Tue, 30 Mar 2021 11:40:23 +0200 Subject: [PATCH] os: add x64 mode for struct and raw read/write (#9512) --- vlib/os/file.c.v | 139 ++++++++++++++++++++++++++++++++++++++--------- vlib/os/os_c.v | 2 - 2 files changed, 113 insertions(+), 28 deletions(-) diff --git a/vlib/os/file.c.v b/vlib/os/file.c.v index 5d0aa68e0c..1d05d95067 100644 --- a/vlib/os/file.c.v +++ b/vlib/os/file.c.v @@ -448,7 +448,7 @@ pub fn (mut f File) read_struct(mut t T) ? { } // read_struct_at reads a single struct of type `T` at position specified in file -pub fn (mut f File) read_struct_at(mut t T, pos int) ? { +pub fn (mut f File) read_struct_at(mut t T, pos u64) ? { if !f.is_opened { return none } @@ -457,9 +457,23 @@ pub fn (mut f File) read_struct_at(mut t T, pos int) ? { return none } C.errno = 0 - C.fseek(f.cfile, pos, C.SEEK_SET) - nbytes := int(C.fread(t, 1, tsize, f.cfile)) - C.fseek(f.cfile, 0, C.SEEK_END) + mut nbytes := 0 + $if x64 { + $if windows { + C._fseeki64(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fread(t, 1, tsize, f.cfile)) + C._fseeki64(f.cfile, 0, C.SEEK_END) + } $else { + C.fseeko(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fread(t, 1, tsize, f.cfile)) + C.fseeko(f.cfile, 0, C.SEEK_END) + } + } + $if x32 { + C.fseek(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fread(t, 1, tsize, f.cfile)) + C.fseek(f.cfile, 0, C.SEEK_END) + } if C.errno != 0 { return error(posix_get_error_msg(C.errno)) } @@ -490,7 +504,7 @@ pub fn (mut f File) read_raw() ?T { } // read_raw_at reads and returns a single instance of type `T` starting at file byte offset `pos` -pub fn (mut f File) read_raw_at(pos int) ?T { +pub fn (mut f File) read_raw_at(pos u64) ?T { if !f.is_opened { return none } @@ -499,17 +513,46 @@ pub fn (mut f File) read_raw_at(pos int) ?T { return none } C.errno = 0 - if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 { - return error(posix_get_error_msg(C.errno)) - } + mut nbytes := 0 mut t := T{} - nbytes := int(C.fread(&t, 1, tsize, f.cfile)) - if C.errno != 0 { - return error(posix_get_error_msg(C.errno)) + $if x64 { + $if windows { + if C._fseeki64(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fread(&t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C._fseeki64(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } + } $else { + if C.fseeko(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fread(&t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C.fseeko(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } + } } - if C.fseek(f.cfile, 0, C.SEEK_END) != 0 { - return error(posix_get_error_msg(C.errno)) + $if x32 { + if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fread(&t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C.fseek(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } } + if nbytes != tsize { return error_with_code('incomplete struct read', nbytes) } @@ -536,7 +579,7 @@ pub fn (mut f File) write_struct(t &T) ? { } // write_struct_at writes a single struct of type `T` at position specified in file -pub fn (mut f File) write_struct_at(t &T, pos int) ? { +pub fn (mut f File) write_struct_at(t &T, pos u64) ? { if !f.is_opened { return error('file is not opened') } @@ -545,9 +588,23 @@ pub fn (mut f File) write_struct_at(t &T, pos int) ? { return error('struct size is 0') } C.errno = 0 - C.fseek(f.cfile, pos, C.SEEK_SET) - nbytes := int(C.fwrite(t, 1, tsize, f.cfile)) - C.fseek(f.cfile, 0, C.SEEK_END) + mut nbytes := 0 + $if x64 { + $if windows { + C._fseeki64(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + C._fseeki64(f.cfile, 0, C.SEEK_END) + } $else { + C.fseeko(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + C.fseeko(f.cfile, 0, C.SEEK_END) + } + } + $if x32 { + C.fseek(f.cfile, pos, C.SEEK_SET) + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + C.fseek(f.cfile, 0, C.SEEK_END) + } if C.errno != 0 { return error(posix_get_error_msg(C.errno)) } @@ -578,7 +635,7 @@ pub fn (mut f File) write_raw(t &T) ? { } // write_raw_at writes a single instance of type `T` starting at file byte offset `pos` -pub fn (mut f File) write_raw_at(t &T, pos int) ? { +pub fn (mut f File) write_raw_at(t &T, pos u64) ? { if !f.is_opened { return error('file is not opened') } @@ -586,16 +643,46 @@ pub fn (mut f File) write_raw_at(t &T, pos int) ? { if tsize == 0 { return error('struct size is 0') } - if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 { - return error(posix_get_error_msg(C.errno)) + mut nbytes := 0 + + $if x64 { + $if windows { + if C._fseeki64(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C._fseeki64(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } + } $else { + if C.fseeko(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C.fseeko(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } + } } - nbytes := int(C.fwrite(t, 1, tsize, f.cfile)) - if C.errno != 0 { - return error(posix_get_error_msg(C.errno)) - } - if C.fseek(f.cfile, 0, C.SEEK_END) != 0 { - return error(posix_get_error_msg(C.errno)) + $if x32 { + if C.fseek(f.cfile, pos, C.SEEK_SET) != 0 { + return error(posix_get_error_msg(C.errno)) + } + nbytes = int(C.fwrite(t, 1, tsize, f.cfile)) + if C.errno != 0 { + return error(posix_get_error_msg(C.errno)) + } + if C.fseek(f.cfile, 0, C.SEEK_END) != 0 { + return error(posix_get_error_msg(C.errno)) + } } + if nbytes != tsize { return error_with_code('incomplete struct write', nbytes) } diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index 5f5242f0eb..ee3782702b 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -25,8 +25,6 @@ fn C.CopyFile(&u32, &u32, int) int fn C.execvp(file charptr, argv &charptr) int -// fn C.lstat(charptr, voidptr) u64 - fn C._wstat64(charptr, voidptr) u64 // fn C.proc_pidpath(int, byteptr, int) int