os: syscalls

pull/3285/head
Alexander Medvednikov 2019-12-31 07:53:53 +00:00
parent 80da2341aa
commit f9cc419dba
4 changed files with 182 additions and 61 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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))

View File

@ -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.