authorgravatar for gereeter+code@gmail.comJonathan S <gereeter+code@gmail.com> 2019-11-22 15:40:46-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-25 23:46:47-05:00
log17bc1f62a51ad5fc44dc97acf6ddb33e6d00b0c4
tree23da0acda6763db992cb729110761c756d5fa0f2
parentf96d818770fa8264b7b87e55ef7e01ff5df44c77

Split `std.fs.Dir.openDir` into `openDirList` and `openDirTraverse` to clarify what directories can be iterated. Closes ziglang/zig#3741.

The Windows-inspired nomenclature of "List" and "Traverse" was chosen over POSIX-style "Read" and "Path" (from `O_PATH`) for clarity. Using "Path" makes it look like the function is manipulating strings, and the generic "Read" ending isn't useful when there is no generic read method. Even in implementation details, `read` is never used. Actual exploitation of the difference between the two functions will come in a later commit.

1 files changed, 56 insertions(+), 14 deletions(-)

lib/std/fs.zig+56-14
...@@ -657,8 +657,8 @@ pub const Dir = struct {...@@ -657,8 +657,8 @@ pub const Dir = struct {
657 }657 }
658 }658 }
659659
660 /// Returns an open handle to the current working directory.660 /// Returns an handle to the current working directory that is open for traversal.
661 /// Closing the returned `Dir` is checked illegal behavior.661 /// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior.
662 /// On POSIX targets, this function is comptime-callable.662 /// On POSIX targets, this function is comptime-callable.
663 pub fn cwd() Dir {663 pub fn cwd() Dir {
664 if (builtin.os == .windows) {664 if (builtin.os == .windows) {
...@@ -683,14 +683,14 @@ pub const Dir = struct {...@@ -683,14 +683,14 @@ pub const Dir = struct {
683 DeviceBusy,683 DeviceBusy,
684 } || os.UnexpectedError;684 } || os.UnexpectedError;
685685
686 /// Call `close` to free the directory handle.686 /// Deprecated; call `Dir.cwd().openDirList` directly.
687 pub fn open(dir_path: []const u8) OpenError!Dir {687 pub fn open(dir_path: []const u8) OpenError!Dir {
688 return cwd().openDir(dir_path);688 return cwd().openDirList(dir_path);
689 }689 }
690690
691 /// Same as `open` except the parameter is null-terminated.691 /// Deprecated; call `Dir.cwd().openDirListC` directly.
692 pub fn openC(dir_path_c: [*:0]const u8) OpenError!Dir {692 pub fn openC(dir_path_c: [*:0]const u8) OpenError!Dir {
693 return cwd().openDirC(dir_path_c);693 return cwd().openDirListC(dir_path_c);
694 }694 }
695695
696 pub fn close(self: *Dir) void {696 pub fn close(self: *Dir) void {
...@@ -775,22 +775,57 @@ pub const Dir = struct {...@@ -775,22 +775,57 @@ pub const Dir = struct {
775 }775 }
776 }776 }
777777
778 /// Call `close` on the result when done.778 /// Deprecated; call `openDirList` directly.
779 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {779 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {
780 return self.openDirList(sub_path);
781 }
782
783 /// Deprecated; call `openDirListC` directly.
784 pub fn openDirC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir {
785 return self.openDirListC(sub_path_c);
786 }
787
788 /// Opens a directory at the given path with the ability to access subpaths
789 /// of the result. Calling `iterate` on the result is illegal behavior; to
790 /// list the contents of a directory, open it with `openDirList`.
791 ///
792 /// Call `close` on the result when done.
793 pub fn openDirTraverse(self: Dir, sub_path: []const u8) OpenError!Dir {
780 if (builtin.os == .windows) {794 if (builtin.os == .windows) {
781 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);795 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
782 return self.openDirW(&sub_path_w);796 return self.openDirTraverseW(&sub_path_w);
783 }797 }
784798
785 const sub_path_c = try os.toPosixPath(sub_path);799 const sub_path_c = try os.toPosixPath(sub_path);
786 return self.openDirC(&sub_path_c);800 return self.openDirTraverseC(&sub_path_c);
787 }801 }
788802
789 /// Same as `openDir` except the parameter is null-terminated.803 /// Opens a directory at the given path with the ability to access subpaths and list contents
790 pub fn openDirC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir {804 /// of the result. If the ability to list contents is unneeded, `openDirTraverse` acts the
805 /// same and may be more efficient.
806 ///
807 /// Call `close` on the result when done.
808 pub fn openDirList(self: Dir, sub_path: []const u8) OpenError!Dir {
809 if (builtin.os == .windows) {
810 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
811 return self.openDirListW(&sub_path_w);
812 }
813
814 const sub_path_c = try os.toPosixPath(sub_path);
815 return self.openDirListC(&sub_path_c);
816 }
817
818 /// Same as `openDirTraverse` except the parameter is null-terminated.
819 pub fn openDirTraverseC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir {
820 // TODO: use O_PATH where supported
821 return self.openDirListC(sub_path_c);
822 }
823
824 /// Same as `openDirList` except the parameter is null-terminated.
825 pub fn openDirListC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir {
791 if (builtin.os == .windows) {826 if (builtin.os == .windows) {
792 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);827 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
793 return self.openDirW(&sub_path_w);828 return self.openDirListW(&sub_path_w);
794 }829 }
795830
796 const flags = os.O_RDONLY | os.O_DIRECTORY | os.O_CLOEXEC;831 const flags = os.O_RDONLY | os.O_DIRECTORY | os.O_CLOEXEC;
...@@ -804,9 +839,16 @@ pub const Dir = struct {...@@ -804,9 +839,16 @@ pub const Dir = struct {
804 return Dir{ .fd = fd };839 return Dir{ .fd = fd };
805 }840 }
806841
807 /// Same as `openDir` except the path parameter is UTF16LE, NT-prefixed.842 /// Same as `openDirTraverse` except the path parameter is UTF16LE, NT-prefixed.
843 /// This function is Windows-only.
844 pub fn openDirTraverseW(self: Dir, sub_path_w: [*:0]const u16) OpenError!Dir {
845 // TODO: open without FILE_LIST_DIRECTORY
846 return self.openDirListW(sub_path_w);
847 }
848
849 /// Same as `openDirList` except the path parameter is UTF16LE, NT-prefixed.
808 /// This function is Windows-only.850 /// This function is Windows-only.
809 pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16) OpenError!Dir {851 pub fn openDirListW(self: Dir, sub_path_w: [*:0]const u16) OpenError!Dir {
810 const w = os.windows;852 const w = os.windows;
811853
812 var result = Dir{854 var result = Dir{