os_linux.c (2354B)
1 /* See LICENSE for license details. */ 2 #define OS_PATH_SEPARATOR_CHAR '/' 3 #define OS_PATH_SEPARATOR "/" 4 5 #include "util.h" 6 7 #include <fcntl.h> 8 #include <poll.h> 9 #include <sys/inotify.h> 10 #include <sys/mman.h> 11 #include <sys/stat.h> 12 #include <unistd.h> 13 14 function OS_WRITE_FILE_FN(os_write_file) 15 { 16 while (raw.len) { 17 sz r = write(file, raw.data, raw.len); 18 if (r < 0) return 0; 19 raw = str8_cut_head(raw, r); 20 } 21 return 1; 22 } 23 24 function void __attribute__((noreturn)) 25 os_exit(s32 code) 26 { 27 _exit(code); 28 unreachable(); 29 } 30 31 function void __attribute__((noreturn)) 32 os_fatal(str8 msg) 33 { 34 os_write_file(STDERR_FILENO, msg); 35 os_exit(1); 36 unreachable(); 37 } 38 39 function OS_ALLOC_ARENA_FN(os_alloc_arena) 40 { 41 Arena result = {0}; 42 sz pagesize = sysconf(_SC_PAGESIZE); 43 if (capacity % pagesize != 0) 44 capacity += pagesize - capacity % pagesize; 45 46 void *beg = mmap(0, capacity, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); 47 if (beg != MAP_FAILED) { 48 result.beg = beg; 49 result.end = result.beg + capacity; 50 } 51 return result; 52 } 53 54 function OS_READ_WHOLE_FILE_FN(os_read_whole_file) 55 { 56 str8 result = str8(""); 57 58 struct stat sb; 59 s32 fd = open(file, O_RDONLY); 60 if (fd >= 0 && fstat(fd, &sb) >= 0) { 61 result = str8_alloc(arena, sb.st_size); 62 sz rlen = read(fd, result.data, result.len); 63 if (rlen != result.len) 64 result = str8(""); 65 } 66 if (fd >= 0) close(fd); 67 68 return result; 69 } 70 71 function OS_WRITE_NEW_FILE_FN(os_write_new_file) 72 { 73 b32 result = 0; 74 sptr fd = open(fname, O_WRONLY|O_TRUNC|O_CREAT, 0600); 75 if (fd != INVALID_FILE) { 76 result = os_write_file(fd, raw); 77 close(fd); 78 } 79 return result; 80 } 81 82 function OS_ADD_FILE_WATCH_FN(os_add_file_watch) 83 { 84 str8 directory = path; 85 directory.len = str8_scan_backwards(path, '/'); 86 if (directory.len < 0) { 87 directory = str8("."); 88 } else { 89 path = str8_cut_head(path, directory.len + 1); 90 } 91 92 u64 hash = str8_hash(directory); 93 FileWatchContext *fwctx = &os->file_watch_context; 94 FileWatchDirectory *dir = lookup_file_watch_directory(fwctx, hash); 95 if (!dir) { 96 dir = da_push(a, fwctx); 97 dir->hash = hash; 98 dir->name = push_str8_zero(a, directory); 99 s32 mask = IN_MOVED_TO|IN_CLOSE_WRITE; 100 dir->handle = inotify_add_watch(fwctx->handle, (c8 *)dir->name.data, mask); 101 } 102 103 FileWatch *fw = da_push(a, dir); 104 fw->user_data = user_data; 105 fw->callback = callback; 106 fw->hash = str8_hash(path); 107 }