2
0

os_x.odin 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #import "fmt.odin";
  2. Handle :: i32;
  3. File_Time :: u64;
  4. Errno :: int;
  5. // INVALID_HANDLE: Handle : -1;
  6. O_RDONLY :: 0x00000;
  7. O_WRONLY :: 0x00001;
  8. O_RDWR :: 0x00002;
  9. O_CREAT :: 0x00040;
  10. O_EXCL :: 0x00080;
  11. O_NOCTTY :: 0x00100;
  12. O_TRUNC :: 0x00200;
  13. O_NONBLOCK :: 0x00800;
  14. O_APPEND :: 0x00400;
  15. O_SYNC :: 0x01000;
  16. O_ASYNC :: 0x02000;
  17. O_CLOEXEC :: 0x80000;
  18. // ERROR_NONE: Errno : 0;
  19. // ERROR_FILE_NOT_FOUND: Errno : 2;
  20. // ERROR_PATH_NOT_FOUND: Errno : 3;
  21. // ERROR_ACCESS_DENIED: Errno : 5;
  22. // ERROR_NO_MORE_FILES: Errno : 18;
  23. // ERROR_HANDLE_EOF: Errno : 38;
  24. // ERROR_NETNAME_DELETED: Errno : 64;
  25. // ERROR_FILE_EXISTS: Errno : 80;
  26. // ERROR_BROKEN_PIPE: Errno : 109;
  27. // ERROR_BUFFER_OVERFLOW: Errno : 111;
  28. // ERROR_INSUFFICIENT_BUFFER: Errno : 122;
  29. // ERROR_MOD_NOT_FOUND: Errno : 126;
  30. // ERROR_PROC_NOT_FOUND: Errno : 127;
  31. // ERROR_DIR_NOT_EMPTY: Errno : 145;
  32. // ERROR_ALREADY_EXISTS: Errno : 183;
  33. // ERROR_ENVVAR_NOT_FOUND: Errno : 203;
  34. // ERROR_MORE_DATA: Errno : 234;
  35. // ERROR_OPERATION_ABORTED: Errno : 995;
  36. // ERROR_IO_PENDING: Errno : 997;
  37. // ERROR_NOT_FOUND: Errno : 1168;
  38. // ERROR_PRIVILEGE_NOT_HELD: Errno : 1314;
  39. // WSAEACCES: Errno : 10013;
  40. // WSAECONNRESET: Errno : 10054;
  41. // Windows reserves errors >= 1<<29 for application use
  42. // ERROR_FILE_IS_PIPE: Errno : 1<<29 + 0;
  43. #foreign_system_library libc "c";
  44. unix_open :: proc(path: ^u8, mode: int, perm: u32) -> Handle #foreign libc "open";
  45. unix_close :: proc(handle: Handle) #foreign libc "close";
  46. unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int #foreign libc "read";
  47. unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int #foreign libc "write";
  48. unix_gettid :: proc() -> u64 #foreign libc "gettid";
  49. unix_malloc :: proc(size: int) -> rawptr #foreign libc "malloc";
  50. unix_free :: proc(ptr: rawptr) #foreign libc "free";
  51. unix_realloc :: proc(ptr: rawptr, size: int) -> rawptr #foreign libc "realloc";
  52. unix_exit :: proc(status: int) #foreign libc "exit";
  53. open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
  54. return unix_open(path.data, mode, perm), 0;
  55. }
  56. close :: proc(fd: Handle) {
  57. unix_close(fd);
  58. }
  59. write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
  60. return unix_write(fd, data.data, data.count), 0;
  61. }
  62. read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
  63. return unix_read(fd, data.data, data.count), 0;
  64. }
  65. seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
  66. /*
  67. using win32;
  68. w: u32;
  69. match whence {
  70. case 0: w = FILE_BEGIN;
  71. case 1: w = FILE_CURRENT;
  72. case 2: w = FILE_END;
  73. }
  74. hi := cast(i32)(offset>>32);
  75. lo := cast(i32)(offset);
  76. ft := GetFileType(cast(HANDLE)fd);
  77. if ft == FILE_TYPE_PIPE {
  78. return 0, ERROR_FILE_IS_PIPE;
  79. }
  80. dw_ptr := SetFilePointer(cast(HANDLE)fd, lo, ^hi, w);
  81. if dw_ptr == INVALID_SET_FILE_POINTER {
  82. err := GetLastError();
  83. return 0, cast(Errno)err;
  84. }
  85. return cast(i64)hi<<32 + cast(i64)dw_ptr, ERROR_NONE;
  86. */
  87. return 0, 0;
  88. }
  89. // NOTE(bill): Uses startup to initialize it
  90. stdin: Handle = 0; // get_std_handle(win32.STD_INPUT_HANDLE);
  91. stdout: Handle = 1; // get_std_handle(win32.STD_OUTPUT_HANDLE);
  92. stderr: Handle = 2; // get_std_handle(win32.STD_ERROR_HANDLE);
  93. /*
  94. get_std_handle :: proc(h: int) -> Handle {
  95. fd := win32.GetStdHandle(cast(i32)h);
  96. win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
  97. return cast(Handle)fd;
  98. }
  99. last_write_time :: proc(fd: Handle) -> File_Time {
  100. file_info: win32.BY_HANDLE_FILE_INFORMATION;
  101. win32.GetFileInformationByHandle(cast(win32.HANDLE)fd, ^file_info);
  102. lo := cast(File_Time)file_info.last_write_time.lo;
  103. hi := cast(File_Time)file_info.last_write_time.hi;
  104. return lo | hi << 32;
  105. }
  106. last_write_time_by_name :: proc(name: string) -> File_Time {
  107. last_write_time: win32.FILETIME;
  108. data: win32.FILE_ATTRIBUTE_DATA;
  109. buf: [1024]byte;
  110. assert(buf.count > name.count);
  111. copy(buf[:], cast([]byte)name);
  112. if win32.GetFileAttributesExA(^buf[0], win32.GetFileExInfoStandard, ^data) != 0 {
  113. last_write_time = data.last_write_time;
  114. }
  115. l := cast(File_Time)last_write_time.lo;
  116. h := cast(File_Time)last_write_time.hi;
  117. return l | h << 32;
  118. }
  119. read_entire_file :: proc(name: string) -> ([]byte, bool) {
  120. buf: [300]byte;
  121. copy(buf[:], cast([]byte)name);
  122. fd, err := open(name, O_RDONLY, 0);
  123. if err != ERROR_NONE {
  124. return nil, false;
  125. }
  126. defer close(fd);
  127. length: i64;
  128. file_size_ok := win32.GetFileSizeEx(cast(win32.HANDLE)fd, ^length) != 0;
  129. if !file_size_ok {
  130. return nil, false;
  131. }
  132. data := new_slice(u8, length);
  133. if data.data == nil {
  134. return nil, false;
  135. }
  136. single_read_length: i32;
  137. total_read: i64;
  138. for total_read < length {
  139. remaining := length - total_read;
  140. to_read: u32;
  141. MAX :: 1<<32-1;
  142. if remaining <= MAX {
  143. to_read = cast(u32)remaining;
  144. } else {
  145. to_read = MAX;
  146. }
  147. win32.ReadFile(cast(win32.HANDLE)fd, ^data[total_read], to_read, ^single_read_length, nil);
  148. if single_read_length <= 0 {
  149. free(data);
  150. return nil, false;
  151. }
  152. total_read += cast(i64)single_read_length;
  153. }
  154. return data, true;
  155. }
  156. */
  157. heap_alloc :: proc(size: int) -> rawptr {
  158. assert(size > 0);
  159. return unix_malloc(size);
  160. }
  161. heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
  162. return unix_realloc(ptr, new_size);
  163. }
  164. heap_free :: proc(ptr: rawptr) {
  165. unix_free(ptr);
  166. }
  167. exit :: proc(code: int) {
  168. unix_exit(code);
  169. }
  170. current_thread_id :: proc() -> int {
  171. // return cast(int) unix_gettid();
  172. return 0;
  173. }