#import "Basic"; #import "POSIX"; // This prototype is suposed to allow me to use the "open" posix syscall // that returns a file-descriptor (fd) that can then be used by the mmap // syscall that allows to map a file to memory. // // Syscall info: https://filippo.io/linux-syscall-table/ // TODO // - On mmap_file and munmap_file use get_error_string as in the windows version. This is defined in ./modules/System.jai. // - Check if the strings being passed to these syscalls require any processing to be a C_string. // - Check what's the best return type for syscalls... is it OS dependent? // - File structure // modules/POSIX - where a lot of POSIX stuff (constants and structs) is defined, e.g.: `SYS_open :: 5;` // modules/System - where "Windows" or "POSIX" or "Objective -> macos" modules are imported... I suspect we import "System" if trying to target all OSes. // modules/Linux - defines some unix stuff (constants and structs) and then imports "POSIX". // // Seems that, each functionality may directly implement for all OSes, instead of using a OS independent layer. main :: () { //sys_exit(-1); size_stat, error_stat := sys_stat("./dummy"); print("> dymmy has stat size % widh error %\n", size_stat.st_size, error_stat); fd, error_open := sys_open("./dummy", O_RDONLY, O_RDONLY); print("> opened dummy with fd % and errno %\n", fd, error_open); if fd < 0 return; //LOOPER :: "\\|/-"; //idx := 0; //loop: string; //loop.count = 1; //for 0..3 { //sleep_milliseconds(1000); //loop.data = *LOOPER.data[idx]; //idx = (idx + 1) % LOOPER.count; //print("\rlooping %", loop); //} size_lseek, error_lseek := sys_lseek(fd, 0, SEEK_END); print("\r> dummy has lseek size % with error %\n", size_lseek, error_lseek); size_fstat, error_fstat := sys_fstat(fd); print("\r> dummy has fstat size % with error %\n", size_fstat.st_size, error_fstat); error_close := sys_close(fd); print("\r> close(%) with errno %\n", fd, error_close); print("---\n"); error :s64; fd, error = sys_open("./fail", O_RDONLY, O_RDONLY); print("$ open(fail) returned fd % and error %\n", fd, error); error = sys_close(456); print("$ close(456) returned error %\n", error); } /* #import "Basic"; sys_stat :: (path: string) -> result: stat_t, error: s64{ #assert(OS != .MACOS); // Not yet tested on MACOS. Remove assert to proceed. stats: stat_t = ---; result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM:STAT\n"); // TODO path_p: *s8 = xx path.data; stats_p := *stats; #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_stat; mov rdi: gpr === di, path_p; mov rsi: gpr === si, stats_p; syscall rcx: gpr === c, // Implicitly used by syscall to store RIP r11: gpr === 11, // Implicitly used by syscall to store RFLAGS rax, rdi, rsi; mov result, rax; } if result < 0 return .{}, -result; // Error. else return stats, 0; // OK. } else { print("\r# LINUX:LIBC:STAT\n"); // TODO path_p: *s8 = xx path.data; error := syscall(SYS_stat, path_p, *stats); if error < 0 return .{}, errno(); // Error. else return stats, 0; // OK. } } sys_fstat :: (file_descriptor: s64) -> result: stat_t, error: s64{ #assert(OS != .MACOS); // Not yet tested on MACOS. Remove assert to proceed. stats: stat_t = ---; stats_p := *stats; result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM:FSTAT\n"); // TODO #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_fstat; mov rdi: gpr === di, file_descriptor; mov rsi: gpr === si, stats_p; syscall rcx: gpr === c, // Implicitly used by syscall to store RIP r11: gpr === 11, // Implicitly used by syscall to store RFLAGS rax, rdi, rsi; mov result, rax; } if result < 0 return .{}, -result; // Error. else return stats, 0; // OK. } else { print("\r# LINUX:LIBC:FSTAT\n"); // TODO error := syscall(SYS_fstat, file_descriptor, *result); if error < 0 return .{}, errno(); // Error. else return stats, 0; // OK. } } sys_lseek :: (file_descriptor: s64, offset: s64, whence: s64) -> offset_location: s64, error: s64 { #assert(OS != .MACOS); // Not yet tested on MACOS. Remove assert to proceed. result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM:LSEEK\n"); // TODO #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_lseek; mov rdi: gpr === di, file_descriptor; mov rsi: gpr === si, offset; mov rdx: gpr === d, whence; //syscall rcx, r11, rax, rdi, rsi, rdx; // TODO Cleanup? syscall rcx: gpr === c, // Implicitly used by syscall to store RIP r11: gpr === 11, // Implicitly used by syscall to store RFLAGS rax, rdi, rsi, rdx; mov result, rax; } if result < 0 return -1, -result; // Error. else return result, 0; // OK. } else { print("\r# LINUX:LIBC:LSEEK\n"); // TODO result = syscall(SYS_lseek, file_descriptor, offset, whence); if result < 0 return -1, errno(); // Error. else return result, 0; // OK. } } sys_open :: (path: string, flags: s64, mode: s64) -> file_descriptor: s64, error: s64 { #assert(OS != .MACOS); // Not yet tested on MACOS. Remove assert to proceed. data: *s8 = xx path.data; result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM:OPEN\n"); // TODO #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_open; mov rdi: gpr === di, data; mov rsi: gpr === si, flags; mov rdx: gpr === d, mode; // TODO Is this really used? //syscall rcx, r11, rax, rdi, rsi, rdx; // TODO Cleanup? syscall rcx: gpr === c, // Implicitly used by syscall to store RIP r11: gpr === 11, // Implicitly used by syscall to store RFLAGS rax, rdi, rsi, rdx; mov result, rax; } if result < 0 return -1, -result; // Error. else return result, 0; // OK. } else { print("\r# LINUX:LIBC:OPEN\n"); // TODO result = syscall(SYS_open, data, flags, mode); if result < 0 return -1, errno(); // Error. else return result, 0; // OK. } } sys_close :: (file_descriptor: s64) -> error: s64 { #assert(OS != .MACOS); // Not yet tested on MACOS. Remove assert to proceed. result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM:CLOSE\n"); // TODO #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_close; mov rdi: gpr === di, file_descriptor; syscall rcx: gpr === c, // Implicitly used by syscall to store RIP r11: gpr === 11, // Implicitly used by syscall to store RFLAGS rax, rdi; mov result, rax; } return ifx result < 0 then -result else 0; } else { print("\r# LINUX:LIBC:CLOSE\n"); // TODO result = syscall(SYS_close, file_descriptor); return ifx result < 0 then errno() else 0; } } */