os_essence.odin 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. foreign import api "system:api"
  2. Handle :: distinct int;
  3. Errno :: distinct int;
  4. O_RDONLY :: 1;
  5. O_WRONLY :: 2;
  6. O_CREATE :: 4;
  7. O_TRUNC :: 4;
  8. OS_Node_Type :: enum i32 {
  9. File = 0,
  10. Directory = 1,
  11. }
  12. OS_Node_Information :: struct {
  13. handle: Handle,
  14. id: [16]byte,
  15. ntype: OS_Node_Type,
  16. size: i64,
  17. position: i64,
  18. }
  19. foreign api {
  20. @(link_name="OSHelloWorld") os_hello_world :: proc() ---;
  21. @(link_name="OSPrintDirect") os_print_direct :: proc(string: ^byte, length: int) ---;
  22. @(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---;
  23. @(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---;
  24. @(link_name="OSOpenNode") os_open_node :: proc(path: ^byte, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
  25. @(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---;
  26. @(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---;
  27. @(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
  28. @(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
  29. @(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---;
  30. @(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---;
  31. @(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---;
  32. }
  33. stdin := Handle(-1); // Not implemented
  34. stdout := Handle(0);
  35. stderr := Handle(0);
  36. current_thread_id :: proc() -> int {
  37. // Not implemented
  38. return -1;
  39. }
  40. heap_alloc :: proc(size: int) -> rawptr {
  41. return os_heap_allocate(size, true);
  42. }
  43. heap_free :: proc(address: rawptr) {
  44. os_heap_free(address);
  45. }
  46. heap_resize :: proc(address: rawptr, new_size: int) -> rawptr {
  47. return os_heap_reallocate(address, new_size);
  48. }
  49. open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
  50. information := new(OS_Node_Information);
  51. error := os_open_node(&path[0], len(path), u64(mode), information);
  52. if error < -1 do return 0, 1;
  53. information.position = 0;
  54. if mode&O_TRUNC==O_TRUNC {
  55. error := os_resize_file(information.handle, 0);
  56. if error < -1 do return 0, 1;
  57. }
  58. return Handle(uintptr(information)), 0;
  59. }
  60. close :: proc(fd: Handle) {
  61. information := (^OS_Node_Information)(uintptr(fd));
  62. os_close_handle(information.handle);
  63. free(information);
  64. }
  65. file_size :: proc(fd: Handle) -> (i64, Errno) {
  66. // Not (properly) implemented
  67. information := cast(^OS_Node_Information)uintptr(fd);
  68. return information.size,0;
  69. }
  70. write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
  71. if fd == 0 {
  72. os_print_direct(&data[0], len(data));
  73. return len(data), 0;
  74. } else if fd == 1 {
  75. assert(false);
  76. return 0, 1;
  77. }
  78. information := (^OS_Node_Information)(uintptr(fd));
  79. count := os_write_file_sync(information.handle, information.position, i64(len(data)), &data[0]);
  80. if count < 0 do return 0, 1;
  81. information.position += count;
  82. return int(count), 0;
  83. }
  84. read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
  85. if (fd == 0 || fd == 1) {
  86. assert(false);
  87. return 0, 1;
  88. }
  89. information := (^OS_Node_Information)(uintptr(fd));
  90. count := os_read_file_sync(information.handle, information.position, i64(len(data)), &data[0]);
  91. if count < 0 do return 0, 1;
  92. information.position += count;
  93. return int(count), 0;
  94. }
  95. os_terminate_this_process :: proc() {
  96. os_terminate_process(0x1001);
  97. }