authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-30 13:32:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-30 13:32:11-05:00
logd039fed831cfc219821b58f1d819d79ad49dc652
tree02874006e87e02473a3ad89c0259e55fa235b3c4
parent85e1e3b95f1f1699a842a5e889d8987692a829a4
signature Commit is signed but in an unrecognized format.

introduce std.fs.Dir.openFile and std.fs.Dir.createFile

These functions have flags parameters which cover all the use cases. The other functions are now deprecated.

2 files changed, 144 insertions(+), 87 deletions(-)

lib/std/fs.zig+89-14
......@@ -698,29 +698,104 @@ pub const Dir = struct {
698698 self.* = undefined;
699699 }
700700
701 /// Call `File.close` on the result when done.
702 pub fn openRead(self: Dir, sub_path: []const u8) File.OpenError!File {
701 /// Opens a file for reading or writing, without attempting to create a new file.
702 /// Call `File.close` to release the resource.
703 pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File {
703704 if (builtin.os == .windows) {
704705 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
705 return self.openReadW(&path_w);
706 return self.openFileW(&path_w, flags);
706707 }
707708 const path_c = try os.toPosixPath(sub_path);
708 return self.openReadC(&path_c);
709 return self.openFileC(&path_c, flags);
709710 }
710711
711 /// Call `File.close` on the result when done.
712 pub fn openReadC(self: Dir, sub_path: [*:0]const u8) File.OpenError!File {
712 /// Same as `openFile` but the path parameter is null-terminated.
713 pub fn openFileC(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File {
713714 if (builtin.os == .windows) {
714715 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
715 return self.openReadW(&path_w);
716 return self.openFileW(&path_w, flags);
716717 }
717718 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
718 const flags = O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;
719 const fd = try os.openatC(self.fd, sub_path, flags, 0);
720 return File.openHandle(fd);
719 const os_flags = O_LARGEFILE | os.O_CLOEXEC | if (flags.write and flags.read)
720 @as(u32, os.O_RDWR)
721 else if (flags.write)
722 @as(u32, os.O_WRONLY)
723 else
724 @as(u32, os.O_RDONLY);
725 const fd = try os.openatC(self.fd, sub_path, os_flags, 0);
726 return File{ .handle = fd };
721727 }
722728
723 pub fn openReadW(self: Dir, sub_path_w: [*:0]const u16) File.OpenError!File {
729 /// Same as `openFile` but the path parameter is WTF-16 encoded.
730 pub fn openFileW(self: Dir, sub_path_w: [*:0]const u16, flags: File.OpenFlags) File.OpenError!File {
731 const w = os.windows;
732 const access_mask = w.SYNCHRONIZE |
733 (if (flags.read) @as(u32, w.GENERIC_READ) else 0) |
734 (if (flags.write) @as(u32, w.GENERIC_WRITE) else 0);
735 return self.openFileWindows(sub_path_w, access_mask, w.FILE_OPEN);
736 }
737
738 /// Creates, opens, or overwrites a file with write access.
739 /// Call `File.close` on the result when done.
740 pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
741 if (builtin.os == .windows) {
742 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
743 return self.createFileW(&path_w, flags);
744 }
745 const path_c = try os.toPosixPath(sub_path);
746 return self.createFileC(&path_c, flags);
747 }
748
749 /// Same as `createFile` but the path parameter is null-terminated.
750 pub fn createFileC(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File {
751 if (builtin.os == .windows) {
752 const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
753 return self.createFileW(&path_w, flags);
754 }
755 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
756 const os_flags = O_LARGEFILE | os.O_CREAT | os.O_CLOEXEC |
757 (if (flags.truncate) @as(u32, os.O_TRUNC) else 0) |
758 (if (flags.read) @as(u32, os.O_RDWR) else os.O_WRONLY) |
759 (if (flags.exclusive) @as(u32, os.O_EXCL) else 0);
760 const fd = try os.openatC(self.fd, sub_path_c, os_flags, flags.mode);
761 return File{ .handle = fd };
762 }
763
764 /// Same as `createFile` but the path parameter is WTF-16 encoded.
765 pub fn createFileW(self: Dir, sub_path_w: [*:0]const u16, flags: File.CreateFlags) File.OpenError!File {
766 const w = os.windows;
767 const access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE |
768 (if (flags.read) @as(u32, w.GENERIC_READ) else 0);
769 const creation = if (flags.exclusive)
770 @as(u32, w.FILE_CREATE)
771 else if (flags.truncate)
772 @as(u32, w.FILE_OVERWRITE_IF)
773 else
774 @as(u32, w.FILE_OPEN_IF);
775 return self.openFileWindows(sub_path_w, access_mask, creation);
776 }
777
778 /// Deprecated; call `openFile` directly.
779 pub fn openRead(self: Dir, sub_path: []const u8) File.OpenError!File {
780 return self.openFile(sub_path, .{});
781 }
782
783 /// Deprecated; call `openFileC` directly.
784 pub fn openReadC(self: Dir, sub_path: [*:0]const u8) File.OpenError!File {
785 return self.openFileC(sub_path, .{});
786 }
787
788 /// Deprecated; call `openFileW` directly.
789 pub fn openReadW(self: Dir, sub_path: [*:0]const u16) File.OpenError!File {
790 return self.openFileW(sub_path, .{});
791 }
792
793 pub fn openFileWindows(
794 self: Dir,
795 sub_path_w: [*:0]const u16,
796 access_mask: os.windows.ACCESS_MASK,
797 creation: os.windows.ULONG,
798 ) File.OpenError!File {
724799 const w = os.windows;
725800
726801 var result = File{ .handle = undefined };
......@@ -750,13 +825,13 @@ pub const Dir = struct {
750825 var io: w.IO_STATUS_BLOCK = undefined;
751826 const rc = w.ntdll.NtCreateFile(
752827 &result.handle,
753 w.GENERIC_READ | w.SYNCHRONIZE,
828 access_mask,
754829 &attr,
755830 &io,
756831 null,
757832 w.FILE_ATTRIBUTE_NORMAL,
758 w.FILE_SHARE_READ,
759 w.FILE_OPEN,
833 w.FILE_SHARE_WRITE | w.FILE_SHARE_READ | w.FILE_SHARE_DELETE,
834 creation,
760835 w.FILE_NON_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT,
761836 null,
762837 0,
lib/std/fs/file.zig+55-73
......@@ -25,105 +25,87 @@ pub const File = struct {
2525
2626 pub const OpenError = windows.CreateFileError || os.OpenError;
2727
28 /// Deprecated; call `std.fs.Dir.openRead` directly.
28 /// TODO https://github.com/ziglang/zig/issues/3802
29 pub const OpenFlags = struct {
30 read: bool = true,
31 write: bool = false,
32 };
33
34 /// TODO https://github.com/ziglang/zig/issues/3802
35 pub const CreateFlags = struct {
36 /// Whether the file will be created with read access.
37 read: bool = false,
38
39 /// If the file already exists, and is a regular file, and the access
40 /// mode allows writing, it will be truncated to length 0.
41 truncate: bool = true,
42
43 /// Ensures that this open call creates the file, otherwise causes
44 /// `error.FileAlreadyExists` to be returned.
45 exclusive: bool = false,
46
47 /// For POSIX systems this is the file system mode the file will
48 /// be created with.
49 mode: Mode = default_mode,
50 };
51
52 /// Deprecated; call `std.fs.Dir.openFile` directly.
2953 pub fn openRead(path: []const u8) OpenError!File {
30 return std.fs.Dir.cwd().openRead(path);
54 return std.fs.Dir.cwd().openFile(path, .{});
3155 }
3256
33 /// Deprecated; call `std.fs.Dir.openReadC` directly.
57 /// Deprecated; call `std.fs.Dir.openFileC` directly.
3458 pub fn openReadC(path_c: [*:0]const u8) OpenError!File {
35 return std.fs.Dir.cwd().openReadC(path_c);
59 return std.fs.Dir.cwd().openFileC(path_c, .{});
3660 }
3761
38 /// Deprecated; call `std.fs.Dir.openReadW` directly.
62 /// Deprecated; call `std.fs.Dir.openFileW` directly.
3963 pub fn openReadW(path_w: [*]const u16) OpenError!File {
40 return std.fs.Dir.cwd().openReadW(path_w);
64 return std.fs.Dir.cwd().openFileW(path_w, .{});
4165 }
4266
43 /// Calls `openWriteMode` with `default_mode` for the mode.
44 /// TODO: deprecate this and move it to `std.fs.Dir`.
67 /// Deprecated; call `std.fs.Dir.createFile` directly.
4568 pub fn openWrite(path: []const u8) OpenError!File {
46 return openWriteMode(path, default_mode);
69 return std.fs.Dir.cwd().createFile(path, .{});
4770 }
4871
49 /// If the path does not exist it will be created.
50 /// If a file already exists in the destination it will be truncated.
51 /// Call close to clean up.
52 /// TODO: deprecate this and move it to `std.fs.Dir`.
72 /// Deprecated; call `std.fs.Dir.createFile` directly.
5373 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
54 if (builtin.os == .windows) {
55 const path_w = try windows.sliceToPrefixedFileW(path);
56 return openWriteModeW(&path_w, file_mode);
57 }
58 const path_c = try os.toPosixPath(path);
59 return openWriteModeC(&path_c, file_mode);
74 return std.fs.Dir.cwd().createFile(path, .{ .mode = file_mode });
6075 }
6176
62 /// Same as `openWriteMode` except `path` is null-terminated.
63 /// TODO: deprecate this and move it to `std.fs.Dir`.
64 pub fn openWriteModeC(path: [*:0]const u8, file_mode: Mode) OpenError!File {
65 if (builtin.os == .windows) {
66 const path_w = try windows.cStrToPrefixedFileW(path);
67 return openWriteModeW(&path_w, file_mode);
68 }
69 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
70 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;
71 const fd = try os.openC(path, flags, file_mode);
72 return openHandle(fd);
77 /// Deprecated; call `std.fs.Dir.createFileC` directly.
78 pub fn openWriteModeC(path_c: [*:0]const u8, file_mode: Mode) OpenError!File {
79 return std.fs.Dir.cwd().createFileC(path_c, .{ .mode = file_mode });
7380 }
7481
75 /// Same as `openWriteMode` except `path` is null-terminated and UTF16LE encoded
76 /// TODO: deprecate this and move it to `std.fs.Dir`.
82 /// Deprecated; call `std.fs.Dir.createFileW` directly.
7783 pub fn openWriteModeW(path_w: [*:0]const u16, file_mode: Mode) OpenError!File {
78 const handle = try windows.CreateFileW(
79 path_w,
80 windows.GENERIC_WRITE,
81 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
82 null,
83 windows.CREATE_ALWAYS,
84 windows.FILE_ATTRIBUTE_NORMAL,
85 null,
86 );
87 return openHandle(handle);
84 return std.fs.Dir.cwd().createFileW(path_w, .{ .mode = file_mode });
8885 }
8986
90 /// If the path does not exist it will be created.
91 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists
92 /// Call close to clean up.
93 /// TODO: deprecate this and move it to `std.fs.Dir`.
87 /// Deprecated; call `std.fs.Dir.createFile` directly.
9488 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
95 if (builtin.os == .windows) {
96 const path_w = try windows.sliceToPrefixedFileW(path);
97 return openWriteNoClobberW(&path_w, file_mode);
98 }
99 const path_c = try os.toPosixPath(path);
100 return openWriteNoClobberC(&path_c, file_mode);
89 return std.fs.Dir.cwd().createFile(path, .{
90 .mode = file_mode,
91 .exclusive = true,
92 });
10193 }
10294
103 /// TODO: deprecate this and move it to `std.fs.Dir`.
104 pub fn openWriteNoClobberC(path: [*:0]const u8, file_mode: Mode) OpenError!File {
105 if (builtin.os == .windows) {
106 const path_w = try windows.cStrToPrefixedFileW(path);
107 return openWriteNoClobberW(&path_w, file_mode);
108 }
109 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
110 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_EXCL;
111 const fd = try os.openC(path, flags, file_mode);
112 return openHandle(fd);
95 /// Deprecated; call `std.fs.Dir.createFileC` directly.
96 pub fn openWriteNoClobberC(path_c: [*:0]const u8, file_mode: Mode) OpenError!File {
97 return std.fs.Dir.cwd().createFileC(path_c, .{
98 .mode = file_mode,
99 .exclusive = true,
100 });
113101 }
114102
115 /// TODO: deprecate this and move it to `std.fs.Dir`.
103 /// Deprecated; call `std.fs.Dir.createFileW` directly.
116104 pub fn openWriteNoClobberW(path_w: [*:0]const u16, file_mode: Mode) OpenError!File {
117 const handle = try windows.CreateFileW(
118 path_w,
119 windows.GENERIC_WRITE,
120 windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
121 null,
122 windows.CREATE_NEW,
123 windows.FILE_ATTRIBUTE_NORMAL,
124 null,
125 );
126 return openHandle(handle);
105 return std.fs.Dir.cwd().createFileW(path_w, .{
106 .mode = file_mode,
107 .exclusive = true,
108 });
127109 }
128110
129111 pub fn openHandle(handle: os.fd_t) File {