dir_unix.odin 1.2 KB

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