dir_posix.odin 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //+private
  2. //+build darwin, netbsd, freebsd, openbsd
  3. package os2
  4. import "base:runtime"
  5. import "core:sys/posix"
  6. @(private)
  7. _read_directory :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files: []File_Info, err: Error) {
  8. if f == nil || f.impl == nil {
  9. err = .Invalid_File
  10. return
  11. }
  12. n := n
  13. if n == 0 {
  14. return
  15. }
  16. impl := (^File_Impl)(f)
  17. dir := posix.fdopendir(impl.fd)
  18. if dir == nil {
  19. err = _get_platform_error()
  20. return
  21. }
  22. defer posix.closedir(dir)
  23. dfiles: [dynamic]File_Info
  24. dfiles.allocator = allocator
  25. defer if err != nil {
  26. file_info_slice_delete(dfiles[:], allocator)
  27. }
  28. for {
  29. posix.set_errno(.NONE)
  30. entry := posix.readdir(dir)
  31. if entry == nil {
  32. if errno := posix.errno(); errno != .NONE {
  33. err = _get_platform_error()
  34. return
  35. } else {
  36. break
  37. }
  38. }
  39. cname := cstring(raw_data(entry.d_name[:]))
  40. if cname == "." || cname == ".." {
  41. continue
  42. }
  43. stat: posix.stat_t
  44. if posix.fstatat(posix.dirfd(dir), cname, &stat, { .SYMLINK_NOFOLLOW }) != .OK {
  45. err = _get_platform_error()
  46. return
  47. }
  48. fullpath := concatenate({impl.name, "/", string(cname)}, allocator) or_return
  49. fi := internal_stat(stat, fullpath)
  50. append(&dfiles, fi) or_return
  51. n -= 1
  52. if n == 0 {
  53. break
  54. }
  55. }
  56. files = dfiles[:]
  57. return
  58. }