diff --git a/vlib/builtin/builtin_nix.v b/vlib/builtin/builtin_nix.v index 4425cace72..883108a4b1 100644 --- a/vlib/builtin/builtin_nix.v +++ b/vlib/builtin/builtin_nix.v @@ -3,8 +3,34 @@ // that can be found in the LICENSE file. module builtin + +//pub fn vsyscall(id int +// + +/* +pub const ( + sys_write = 1 + sys_mkdir = 83 +) +const ( + stdin_value = 0 + stdout_value = 1 + stderr_value = 2 +) + +fn C.puts(charptr) +*/ + pub fn println(s string) { - C.printf('%.*s\n', s.len, s.str) + /* + $if linux { + snl := s + '\n' + C.syscall(sys_write, stdout_value, snl.str, s.len+1) + } + $else { + */ + C.printf('%.*s\n', s.len, s.str) + //} } fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool { @@ -96,8 +122,8 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { // C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) return true } $else { - C.printf('backtrace_symbols_fd is missing, so printing backtraces is not available.\n') - C.printf('Some libc implementations like musl simply do not provide it.\n') + println('backtrace_symbols_fd is missing, so printing backtraces is not available.\n') + println('Some libc implementations like musl simply do not provide it.') } } return false diff --git a/vlib/os/os.v b/vlib/os/os.v index 1c7b524a1d..f83052ba0f 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -31,6 +31,7 @@ pub const ( pub struct File { cfile voidptr // Using void* instead of FILE* + fd int mut: opened bool } @@ -269,49 +270,6 @@ fn read_ulines(path string) ?[]ustring { return ulines } -pub fn open(path string) ?File { - mut file := File{} - $if windows { - wpath := path.to_wide() - mode := 'rb' - file = File{ - cfile: C._wfopen(wpath, mode.to_wide()) - } - } $else { - cpath := path.str - file = File{ - cfile: C.fopen(charptr(cpath), 'rb') - } - } - if isnil(file.cfile) { - return error('failed to open file "$path"') - } - file.opened = true - return file -} - -// create creates a file at a specified location and returns a writable `File` object. -pub fn create(path string) ?File { - mut file := File{} - $if windows { - wpath := path.replace('/', '\\').to_wide() - mode := 'wb' - file = File{ - cfile: C._wfopen(wpath, mode.to_wide()) - } - } $else { - cpath := path.str - file = File{ - cfile: C.fopen(charptr(cpath), 'wb') - } - } - if isnil(file.cfile) { - return error('failed to create file "$path"') - } - file.opened = true - return file -} - pub fn open_append(path string) ?File { mut file := File{} $if windows { @@ -333,10 +291,6 @@ pub fn open_append(path string) ?File { return file } -pub fn (f mut File) write(s string) { - C.fputs(s.str, f.cfile) - // C.fwrite(s.str, 1, s.len, f.cfile) -} // convert any value to []byte (LittleEndian) and write it // for example if we have write(7, 4), "07 00 00 00" gets written // write(0x1234, 2) => "34 12" @@ -350,17 +304,6 @@ pub fn (f mut File) write_bytes_at(data voidptr, size, pos int) { C.fseek(f.cfile, 0, C.SEEK_END) } -pub fn (f mut File) writeln(s string) { - if !f.opened { - 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) -} pub fn (f mut File) flush() { if !f.opened { @@ -374,6 +317,10 @@ pub fn (f mut File) close() { return } f.opened = false + $if linux { + C.syscall(sys_close, f.fd) + return + } C.fflush(f.cfile) C.fclose(f.cfile) } diff --git a/vlib/os/os_nix.v b/vlib/os/os_nix.v index c6e6101535..1156c5fef5 100644 --- a/vlib/os/os_nix.v +++ b/vlib/os/os_nix.v @@ -6,6 +6,20 @@ pub const ( path_separator = '/' ) +pub const ( + sys_write = 1 + sys_open = 2 + sys_close = 3 + sys_mkdir = 83 + sys_creat = 85 +) + +const ( + stdin_value = 0 + stdout_value = 1 + stderr_value = 2 +) + fn C.symlink(charptr, charptr) int pub fn init_os_args(argc int, argv &byteptr) []string { @@ -61,12 +75,101 @@ pub fn is_dir(path string) bool { } */ +pub fn open(path string) ?File { + $if linux { + fd := C.syscall(sys_open, path.str, 511) + if fd == -1 { + return error('failed to open file "$path"') + } + return File{ + fd: fd + opened: true + } + } + $else { + cpath := path.str + file := File{ + cfile: C.fopen(charptr(cpath), 'rb') + 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 { + $if linux { + fd := C.syscall(sys_creat, path.str, 511) + //////println('Fd=$fd') + if fd == -1 { + return error('failed to create file "$path"') + } + return File{ + fd: fd + opened: true + } + + } + mut file := File{ + cfile: C.fopen(charptr(path.str), 'wb') + opened: true + } + if isnil(file.cfile) { + return error('failed to create file "$path"') + } + return file +} + +pub fn (f mut File) write(s string) { + if !f.opened { + return + } + $if linux { + 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 (f mut File) writeln(s string) { + if !f.opened { + return + } + $if linux { + 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. pub fn mkdir(path string) ?bool { if path == '.' { return true } apath := os.realpath(path) + $if linux { + ret := C.syscall(sys_mkdir, apath.str, 511) + if ret == -1 { + return error(get_error_msg(C.errno)) + } + return true + } r := C.mkdir(apath.str, 511) if r == -1 { return error(get_error_msg(C.errno)) diff --git a/vlib/os/os_windows.v b/vlib/os/os_windows.v index d67da058c7..125c851f31 100644 --- a/vlib/os/os_windows.v +++ b/vlib/os/os_windows.v @@ -128,6 +128,51 @@ pub fn is_dir(path string) bool { } */ +pub fn open(path string) ?File { + mut file := File{} + wpath := path.to_wide() + mode := 'rb' + file = File{ + cfile: C._wfopen(wpath, mode.to_wide()) + } + if isnil(file.cfile) { + return error('failed to open file "$path"') + } + file.opened = true + return file +} + + + +// create creates a file at a specified location and returns a writable `File` object. +pub fn create(path string) ?File { + wpath := path.replace('/', '\\').to_wide() + mode := 'wb' + file := File{ + cfile: C._wfopen(wpath, mode.to_wide()) + opened: true + } + if isnil(file.cfile) { + return error('failed to create file "$path"') + } + return file +} + +pub fn (f mut File) write(s string) { + if !f.opened { + return + } + C.fputs(s.str, f.cfile) +} + +pub fn (f mut 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.