file.odin 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package os2
  2. import "core:io"
  3. import "core:time"
  4. import "core:runtime"
  5. File :: struct {
  6. impl: _File,
  7. }
  8. File_Mode :: distinct u32
  9. File_Mode_Dir :: File_Mode(1<<16)
  10. File_Mode_Named_Pipe :: File_Mode(1<<17)
  11. File_Mode_Device :: File_Mode(1<<18)
  12. File_Mode_Char_Device :: File_Mode(1<<19)
  13. File_Mode_Sym_Link :: File_Mode(1<<20)
  14. File_Mode_Perm :: File_Mode(0o777) // Unix permision bits
  15. File_Flags :: distinct bit_set[File_Flag; uint]
  16. File_Flag :: enum {
  17. Read,
  18. Write,
  19. Append,
  20. Create,
  21. Excl,
  22. Sync,
  23. Trunc,
  24. Sparse,
  25. Close_On_Exec,
  26. Unbuffered_IO,
  27. }
  28. O_RDONLY :: File_Flags{.Read}
  29. O_WRONLY :: File_Flags{.Write}
  30. O_RDWR :: File_Flags{.Read, .Write}
  31. O_APPEND :: File_Flags{.Append}
  32. O_CREATE :: File_Flags{.Create}
  33. O_EXCL :: File_Flags{.Excl}
  34. O_SYNC :: File_Flags{.Sync}
  35. O_TRUNC :: File_Flags{.Trunc}
  36. O_SPARSE :: File_Flags{.Sparse}
  37. O_CLOEXEC :: File_Flags{.Close_On_Exec}
  38. stdin: ^File = nil // OS-Specific
  39. stdout: ^File = nil // OS-Specific
  40. stderr: ^File = nil // OS-Specific
  41. create :: proc(name: string) -> (^File, Error) {
  42. return open(name, {.Read, .Write, .Create}, File_Mode(0o777))
  43. }
  44. open :: proc(name: string, flags := File_Flags{.Read}, perm := File_Mode(0o777)) -> (^File, Error) {
  45. return _open(name, flags, perm)
  46. }
  47. new_file :: proc(handle: uintptr, name: string) -> ^File {
  48. return _new_file(handle, name)
  49. }
  50. fd :: proc(f: ^File) -> uintptr {
  51. return _fd(f)
  52. }
  53. name :: proc(f: ^File) -> string {
  54. return _name(f)
  55. }
  56. close :: proc(f: ^File) -> Error {
  57. if f != nil {
  58. return io.close(f.impl.stream)
  59. }
  60. return nil
  61. }
  62. seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) {
  63. if f != nil {
  64. return io.seek(f.impl.stream, offset, whence)
  65. }
  66. return 0, .Invalid_File
  67. }
  68. read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) {
  69. if f != nil {
  70. return io.read(f.impl.stream, p)
  71. }
  72. return 0, .Invalid_File
  73. }
  74. read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) {
  75. if f != nil {
  76. return io.read_at(f.impl.stream, p, offset)
  77. }
  78. return 0, .Invalid_File
  79. }
  80. write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) {
  81. if f != nil {
  82. return io.write(f.impl.stream, p)
  83. }
  84. return 0, .Invalid_File
  85. }
  86. write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) {
  87. if f != nil {
  88. return io.write_at(f.impl.stream, p, offset)
  89. }
  90. return 0, .Invalid_File
  91. }
  92. file_size :: proc(f: ^File) -> (n: i64, err: Error) {
  93. if f != nil {
  94. return io.size(f.impl.stream)
  95. }
  96. return 0, .Invalid_File
  97. }
  98. flush :: proc(f: ^File) -> Error {
  99. if f != nil {
  100. return io.flush(f.impl.stream)
  101. }
  102. return nil
  103. }
  104. sync :: proc(f: ^File) -> Error {
  105. return _sync(f)
  106. }
  107. truncate :: proc(f: ^File, size: i64) -> Error {
  108. return _truncate(f, size)
  109. }
  110. remove :: proc(name: string) -> Error {
  111. return _remove(name)
  112. }
  113. rename :: proc(old_path, new_path: string) -> Error {
  114. return _rename(old_path, new_path)
  115. }
  116. link :: proc(old_name, new_name: string) -> Error {
  117. return _link(old_name, new_name)
  118. }
  119. symlink :: proc(old_name, new_name: string) -> Error {
  120. return _symlink(old_name, new_name)
  121. }
  122. read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error) {
  123. return _read_link(name,allocator)
  124. }
  125. chdir :: proc(name: string) -> Error {
  126. return _chdir(name)
  127. }
  128. chmod :: proc(name: string, mode: File_Mode) -> Error {
  129. return _chmod(name, mode)
  130. }
  131. chown :: proc(name: string, uid, gid: int) -> Error {
  132. return _chown(name, uid, gid)
  133. }
  134. fchdir :: proc(f: ^File) -> Error {
  135. return _fchdir(f)
  136. }
  137. fchmod :: proc(f: ^File, mode: File_Mode) -> Error {
  138. return _fchmod(f, mode)
  139. }
  140. fchown :: proc(f: ^File, uid, gid: int) -> Error {
  141. return _fchown(f, uid, gid)
  142. }
  143. lchown :: proc(name: string, uid, gid: int) -> Error {
  144. return _lchown(name, uid, gid)
  145. }
  146. chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
  147. return _chtimes(name, atime, mtime)
  148. }
  149. fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
  150. return _fchtimes(f, atime, mtime)
  151. }
  152. exists :: proc(path: string) -> bool {
  153. return _exists(path)
  154. }
  155. is_file :: proc(path: string) -> bool {
  156. return _is_file(path)
  157. }
  158. is_dir :: proc(path: string) -> bool {
  159. return _is_dir(path)
  160. }
  161. copy_file :: proc(dst_path, src_path: string) -> Error {
  162. src := open(src_path) or_return
  163. defer close(src)
  164. info := fstat(src, _file_allocator()) or_return
  165. defer file_info_delete(info, _file_allocator())
  166. if info.is_dir {
  167. return .Invalid_File
  168. }
  169. dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & File_Mode_Perm) or_return
  170. defer close(dst)
  171. _, err := io.copy(to_writer(dst), to_reader(src))
  172. return err
  173. }