2
0

dir_unix.odin 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #+build darwin, linux, netbsd, freebsd, openbsd, haiku
  2. package os
  3. import "core:strings"
  4. @(require_results)
  5. read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) {
  6. context.allocator = allocator
  7. dupfd := _dup(fd) or_return
  8. dirp := _fdopendir(dupfd) or_return
  9. defer _closedir(dirp)
  10. dirpath := absolute_path_from_handle(dupfd) or_return
  11. defer delete(dirpath)
  12. n := n
  13. size := n
  14. if n <= 0 {
  15. n = -1
  16. size = 100
  17. }
  18. dfi := make([dynamic]File_Info, 0, size, allocator) or_return
  19. defer if err != nil {
  20. for fi_ in dfi {
  21. file_info_delete(fi_, allocator)
  22. }
  23. delete(dfi)
  24. }
  25. for {
  26. entry: Dirent
  27. end_of_stream: bool
  28. entry, err, end_of_stream = _readdir(dirp)
  29. if err != nil {
  30. return
  31. } else if end_of_stream {
  32. break
  33. }
  34. fi_: File_Info
  35. filename := string(cstring(&entry.name[0]))
  36. if filename == "." || filename == ".." {
  37. continue
  38. }
  39. fullpath := strings.join({ dirpath, filename }, "/", allocator)
  40. s: OS_Stat
  41. s, err = _lstat(fullpath)
  42. if err != nil {
  43. delete(fullpath, allocator)
  44. return
  45. }
  46. _fill_file_info_from_stat(&fi_, s)
  47. fi_.fullpath = fullpath
  48. fi_.name = path_base(fi_.fullpath)
  49. append(&dfi, fi_)
  50. }
  51. return dfi[:], nil
  52. }