#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/ main :: () { //sys_exit(-1); print("> open dummy\n"); fd, error_open := sys_open("./dummy"); 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..1 { sleep_milliseconds(1000); loop.data = *LOOPER.data[idx]; idx = (idx + 1) % LOOPER.count; print("\rlooping %", loop); } error_close := sys_close(fd); print("\r> close(%) with errno %\n", fd, error_close); print("---\n"); error :s64; fd, error = sys_open("./fail"); print("$ open(fail) returned fd % and error %\n", fd, error); error = sys_close(456); print("$ close(456) returned error %\n", error); } sys_open :: (path: string) -> file_descriptor: s64, error: s64 { #if OS == .WINDOWS { print("TODO Implement this\n"); // TODO Implement this. } else #if OS == .LINUX { SYS_OPEN :: 2; data: *s8 = xx path.data; result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM\n"); #asm SYSCALL_SYSRET { mov rax: gpr === a, SYS_OPEN; mov rdi: gpr === di, data; mov rsi: gpr === si, O_RDONLY; mov rdx: gpr === d, O_RDONLY; //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\n"); result = syscall(SYS_OPEN, data, O_RDONLY); if result < 0 return -1, errno(); // Error. else return result, 0; // OK. } } } sys_close :: (file_descriptor: s64) -> error: s64 { #if OS == .WINDOWS { print("TODO Implement this\n"); // TODO Implement this. } else #if OS == .LINUX { SYS_CLOSE :: 3; result: s64 = ---; #if CPU == .X64 { print("\r# LINUX:ASM\n"); #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\n"); result = syscall(SYS_CLOSE, file_descriptor); return ifx result < 0 then errno() else 0; } } } sys_exit :: (status: s32) { #if OS == .WINDOWS { // @Note TerminateProcess may be better, as it can't deadlock ExitProcess :: (error_code: u32) #foreign kernel32; ExitProcess(xx errno); } else #if OS == .LINUX { SYS_EXIT_GROUP :: 231; #if CPU==.X64 { print("\rLINUX-ASM\n"); #asm SYSCALL_SYSRET { mov eax: gpr === a, SYS_EXIT_GROUP; mov out: gpr === di, status; syscall t1:, t2:, eax, out; }; } else { syscall(SYS_EXIT_GROUP, status); } } }