file.odin 4.4 KB

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