os: cleanup code duplication for os.create and os.open
parent
03525843a0
commit
931c846602
|
@ -54,6 +54,9 @@ fn C.fseek() int
|
||||||
fn C.fopen() voidptr
|
fn C.fopen() voidptr
|
||||||
|
|
||||||
|
|
||||||
|
fn C.fileno(voidptr) int
|
||||||
|
|
||||||
|
|
||||||
fn C.fwrite() int
|
fn C.fwrite() int
|
||||||
|
|
||||||
|
|
||||||
|
|
113
vlib/os/os.v
113
vlib/os/os.v
|
@ -223,7 +223,10 @@ pub fn mv_by_cp(source string, target string) ?bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vfopen(path, mode string) &C.FILE {
|
// vfopen returns an opened C file, given its path and open mode.
|
||||||
|
// NB: os.vfopen is useful for compatibility with C libraries, that expect `FILE *`.
|
||||||
|
// If you write pure V code, os.create or os.open are more convenient.
|
||||||
|
pub fn vfopen(path, mode string) &C.FILE {
|
||||||
$if windows {
|
$if windows {
|
||||||
return C._wfopen(path.to_wide(), mode.to_wide())
|
return C._wfopen(path.to_wide(), mode.to_wide())
|
||||||
} $else {
|
} $else {
|
||||||
|
@ -231,6 +234,15 @@ fn vfopen(path, mode string) &C.FILE {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileno returns the file descriptor of an opened C file
|
||||||
|
pub fn fileno(cfile voidptr) int {
|
||||||
|
$if windows {
|
||||||
|
return C._fileno(cfile)
|
||||||
|
} $else {
|
||||||
|
return C.fileno(cfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read_lines reads the file in `path` into an array of lines.
|
// read_lines reads the file in `path` into an array of lines.
|
||||||
pub fn read_lines(path string) ?[]string {
|
pub fn read_lines(path string) ?[]string {
|
||||||
buf := read_file(path) or {
|
buf := read_file(path) or {
|
||||||
|
@ -1246,3 +1258,102 @@ pub fn resource_abs_path(path string) string {
|
||||||
}
|
}
|
||||||
return os.real_path(os.join_path(base_path, path))
|
return os.real_path(os.join_path(base_path, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// open tries to open a file for reading and returns back a read-only `File` object
|
||||||
|
pub fn open(path string) ?File {
|
||||||
|
/*
|
||||||
|
$if linux {
|
||||||
|
$if !android {
|
||||||
|
fd := C.syscall(sys_open, path.str, 511)
|
||||||
|
if fd == -1 {
|
||||||
|
return error('failed to open file "$path"')
|
||||||
|
}
|
||||||
|
return File{
|
||||||
|
fd: fd
|
||||||
|
opened: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
cfile := vfopen(path, 'rb')
|
||||||
|
if cfile == 0 {
|
||||||
|
return error('failed to open file "$path"')
|
||||||
|
}
|
||||||
|
fd := fileno(cfile)
|
||||||
|
return File {
|
||||||
|
cfile: cfile
|
||||||
|
fd: fd
|
||||||
|
opened: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create creates or opens a file at a specified location and returns a write-only `File` object
|
||||||
|
pub fn create(path string) ?File {
|
||||||
|
/*
|
||||||
|
// NB: android/termux/bionic is also a kind of linux,
|
||||||
|
// but linux syscalls there sometimes fail,
|
||||||
|
// while the libc version should work.
|
||||||
|
$if linux {
|
||||||
|
$if !android {
|
||||||
|
//$if macos {
|
||||||
|
// fd = C.syscall(398, path.str, 0x601, 0x1b6)
|
||||||
|
//}
|
||||||
|
//$if linux {
|
||||||
|
fd = C.syscall(sys_creat, path.str, 511)
|
||||||
|
//}
|
||||||
|
if fd == -1 {
|
||||||
|
return error('failed to create file "$path"')
|
||||||
|
}
|
||||||
|
file = File{
|
||||||
|
fd: fd
|
||||||
|
opened: true
|
||||||
|
}
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
cfile := vfopen(path, 'wb')
|
||||||
|
if cfile == 0 {
|
||||||
|
return error('failed to create file "$path"')
|
||||||
|
}
|
||||||
|
fd := fileno(cfile)
|
||||||
|
return File {
|
||||||
|
cfile: cfile
|
||||||
|
fd: fd
|
||||||
|
opened: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut f File) write(s string) {
|
||||||
|
if !f.opened {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
$if linux {
|
||||||
|
$if !android {
|
||||||
|
C.syscall(sys_write, f.fd, s.str, s.len)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
C.fputs(s.str, f.cfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut f File) writeln(s string) {
|
||||||
|
if !f.opened {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
$if linux {
|
||||||
|
$if !android {
|
||||||
|
snl := s + '\n'
|
||||||
|
C.syscall(sys_write, f.fd, snl.str, snl.len)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// TODO perf
|
||||||
|
C.fputs(s.str, f.cfile)
|
||||||
|
C.fputs('\n', f.cfile)
|
||||||
|
}
|
||||||
|
|
|
@ -66,112 +66,12 @@ pub fn is_dir(path string) bool {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// open opens a file at the specified and returns back a read-only `File` object
|
|
||||||
pub fn open(path string) ?File {
|
|
||||||
/*
|
|
||||||
$if linux {
|
|
||||||
$if !android {
|
|
||||||
fd := C.syscall(sys_open, path.str, 511)
|
|
||||||
if fd == -1 {
|
|
||||||
return error('failed to open file "$path"')
|
|
||||||
}
|
|
||||||
return File{
|
|
||||||
fd: fd
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
file := File{
|
|
||||||
cfile: C.fopen(charptr(path.str), 'rb')
|
|
||||||
fd: 0
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
if isnil(file.cfile) {
|
|
||||||
return error('failed to open file "$path"')
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
// create creates or opens a file at a specified location and returns a write-only `File` object
|
|
||||||
pub fn create(path string) ?File {
|
|
||||||
/*
|
|
||||||
// NB: android/termux/bionic is also a kind of linux,
|
|
||||||
// but linux syscalls there sometimes fail,
|
|
||||||
// while the libc version should work.
|
|
||||||
$if linux {
|
|
||||||
$if !android {
|
|
||||||
//$if macos {
|
|
||||||
// fd = C.syscall(398, path.str, 0x601, 0x1b6)
|
|
||||||
//}
|
|
||||||
//$if linux {
|
|
||||||
fd = C.syscall(sys_creat, path.str, 511)
|
|
||||||
//}
|
|
||||||
if fd == -1 {
|
|
||||||
return error('failed to create file "$path"')
|
|
||||||
}
|
|
||||||
file = File{
|
|
||||||
fd: fd
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
file := File{
|
|
||||||
cfile: C.fopen(charptr(path.str), 'wb')
|
|
||||||
fd: 0
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
if isnil(file.cfile) {
|
|
||||||
return error('failed to create file "$path"')
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn (mut f File) fseek(pos, mode int) {
|
pub fn (mut f File) fseek(pos, mode int) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
pub fn (mut f File) write(s string) {
|
|
||||||
if !f.opened {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
$if linux {
|
|
||||||
$if !android {
|
|
||||||
C.syscall(sys_write, f.fd, s.str, s.len)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
C.fputs(s.str, f.cfile)
|
|
||||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut f File) writeln(s string) {
|
|
||||||
if !f.opened {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
$if linux {
|
|
||||||
$if !android {
|
|
||||||
snl := s + '\n'
|
|
||||||
C.syscall(sys_write, f.fd, snl.str, snl.len)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// C.fwrite(s.str, 1, s.len, f.cfile)
|
|
||||||
// ss := s.clone()
|
|
||||||
// TODO perf
|
|
||||||
C.fputs(s.str, f.cfile)
|
|
||||||
// ss.free()
|
|
||||||
C.fputs('\n', f.cfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// mkdir creates a new directory with the specified path.
|
// mkdir creates a new directory with the specified path.
|
||||||
pub fn mkdir(path string) ?bool {
|
pub fn mkdir(path string) ?bool {
|
||||||
if path == '.' {
|
if path == '.' {
|
||||||
|
|
|
@ -130,47 +130,6 @@ pub fn is_dir(path string) bool {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn open(path string) ?File {
|
|
||||||
mode := 'rb'
|
|
||||||
file := File {
|
|
||||||
cfile: C._wfopen(path.to_wide(), mode.to_wide())
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
if isnil(file.cfile) {
|
|
||||||
return error('failed to open file "$path"')
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
// create creates a file at a specified location and returns a writable `File` object.
|
|
||||||
pub fn create(path string) ?File {
|
|
||||||
mode := 'wb'
|
|
||||||
file := File {
|
|
||||||
cfile: C._wfopen(path.to_wide(), mode.to_wide())
|
|
||||||
opened: true
|
|
||||||
}
|
|
||||||
if isnil(file.cfile) {
|
|
||||||
return error('failed to create file "$path"')
|
|
||||||
}
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut f File) write(s string) {
|
|
||||||
if !f.opened {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
C.fputs(s.str, f.cfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut f File) writeln(s string) {
|
|
||||||
if !f.opened {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// TODO perf
|
|
||||||
C.fputs(s.str, f.cfile)
|
|
||||||
C.fputs('\n', f.cfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// mkdir creates a new directory with the specified path.
|
// mkdir creates a new directory with the specified path.
|
||||||
pub fn mkdir(path string) ?bool {
|
pub fn mkdir(path string) ?bool {
|
||||||
|
@ -185,12 +144,11 @@ pub fn mkdir(path string) ?bool {
|
||||||
// Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019
|
// Ref - https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=vs-2019
|
||||||
// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor.
|
// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor.
|
||||||
pub fn get_file_handle(path string) HANDLE {
|
pub fn get_file_handle(path string) HANDLE {
|
||||||
mode := 'rb'
|
cfile := vfopen(path, 'rb')
|
||||||
fd := C._wfopen(path.to_wide(), mode.to_wide())
|
if cfile == 0 {
|
||||||
if fd == 0 {
|
|
||||||
return HANDLE(INVALID_HANDLE_VALUE)
|
return HANDLE(INVALID_HANDLE_VALUE)
|
||||||
}
|
}
|
||||||
handle := HANDLE(C._get_osfhandle(C._fileno(fd))) // CreateFile? - hah, no -_-
|
handle := HANDLE(C._get_osfhandle(fileno(cfile))) // CreateFile? - hah, no -_-
|
||||||
return handle
|
return handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue