| ... | ... | @@ -297,40 +297,6 @@ pub fn makeDirW(dir_path: [*:0]const u16) !void { |
| 297 | 297 | return os.mkdirW(dir_path, default_new_dir_mode); |
| 298 | 298 | } |
| 299 | 299 | |
| 300 | | /// Calls makeDir recursively to make an entire path. Returns success if the path |
| 301 | | /// already exists and is a directory. |
| 302 | | /// This function is not atomic, and if it returns an error, the file system may |
| 303 | | /// have been modified regardless. |
| 304 | | pub fn makePath(full_path: []const u8) !void { |
| 305 | | var end_index: usize = full_path.len; |
| 306 | | while (true) { |
| 307 | | cwd().makeDir(full_path[0..end_index]) catch |err| switch (err) { |
| 308 | | error.PathAlreadyExists => { |
| 309 | | // TODO stat the file and return an error if it's not a directory |
| 310 | | // this is important because otherwise a dangling symlink |
| 311 | | // could cause an infinite loop |
| 312 | | if (end_index == full_path.len) return; |
| 313 | | }, |
| 314 | | error.FileNotFound => { |
| 315 | | if (end_index == 0) return err; |
| 316 | | // march end_index backward until next path component |
| 317 | | while (true) { |
| 318 | | end_index -= 1; |
| 319 | | if (path.isSep(full_path[end_index])) break; |
| 320 | | } |
| 321 | | continue; |
| 322 | | }, |
| 323 | | else => return err, |
| 324 | | }; |
| 325 | | if (end_index == full_path.len) return; |
| 326 | | // march end_index forward until next path component |
| 327 | | while (true) { |
| 328 | | end_index += 1; |
| 329 | | if (end_index == full_path.len or path.isSep(full_path[end_index])) break; |
| 330 | | } |
| 331 | | } |
| 332 | | } |
| 333 | | |
| 334 | 300 | /// Returns `error.DirNotEmpty` if the directory is not empty. |
| 335 | 301 | /// To delete a directory recursively, see `deleteTree`. |
| 336 | 302 | pub fn deleteDir(dir_path: []const u8) !void { |
| ... | ... | @@ -885,6 +851,40 @@ pub const Dir = struct { |
| 885 | 851 | try os.mkdiratC(self.fd, sub_path, default_new_dir_mode); |
| 886 | 852 | } |
| 887 | 853 | |
| 854 | /// Calls makeDir recursively to make an entire path. Returns success if the path |
| 855 | /// already exists and is a directory. |
| 856 | /// This function is not atomic, and if it returns an error, the file system may |
| 857 | /// have been modified regardless. |
| 858 | pub fn makePath(self: Dir, sub_path: []const u8) !void { |
| 859 | var end_index: usize = sub_path.len; |
| 860 | while (true) { |
| 861 | self.makeDir(sub_path[0..end_index]) catch |err| switch (err) { |
| 862 | error.PathAlreadyExists => { |
| 863 | // TODO stat the file and return an error if it's not a directory |
| 864 | // this is important because otherwise a dangling symlink |
| 865 | // could cause an infinite loop |
| 866 | if (end_index == sub_path.len) return; |
| 867 | }, |
| 868 | error.FileNotFound => { |
| 869 | if (end_index == 0) return err; |
| 870 | // march end_index backward until next path component |
| 871 | while (true) { |
| 872 | end_index -= 1; |
| 873 | if (path.isSep(sub_path[end_index])) break; |
| 874 | } |
| 875 | continue; |
| 876 | }, |
| 877 | else => return err, |
| 878 | }; |
| 879 | if (end_index == sub_path.len) return; |
| 880 | // march end_index forward until next path component |
| 881 | while (true) { |
| 882 | end_index += 1; |
| 883 | if (end_index == sub_path.len or path.isSep(sub_path[end_index])) break; |
| 884 | } |
| 885 | } |
| 886 | } |
| 887 | |
| 888 | 888 | pub fn changeTo(self: Dir) !void { |
| 889 | 889 | try os.fchdir(self.fd); |
| 890 | 890 | } |