diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-02-09 18:27:50 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-02-09 18:27:50 -0500 |
| commit | a2bd9f8912ade5149855dc6e2371aaae49093660 (patch) | |
| tree | 04dab23f1d6d730b5266506422daf820124fa139 /std/os | |
| parent | e7bf8f3f04efc280a76a3a38b4e6d470d279e41a (diff) | |
| download | zig-a2bd9f8912ade5149855dc6e2371aaae49093660.tar.gz zig-a2bd9f8912ade5149855dc6e2371aaae49093660.zip | |
std lib: modify allocator idiom
Before we accepted a nullable allocator for some stuff like
opening files. Now we require an allocator.
Use the mem.FixedBufferAllocator pattern if a bound on the amount
to allocate is known.
This also establishes the pattern that usually an allocator is the
first argument to a function (possibly after "self").
fix docs for std.cstr.addNullByte
self hosted compiler:
* only build docs when explicitly asked to
* clean up main
* stub out zig fmt
Diffstat (limited to 'std/os')
| -rw-r--r-- | std/os/child_process.zig | 28 | ||||
| -rw-r--r-- | std/os/index.zig | 44 | ||||
| -rw-r--r-- | std/os/path.zig | 2 | ||||
| -rw-r--r-- | std/os/windows/util.zig | 29 |
4 files changed, 38 insertions, 65 deletions
diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 0b3040cdc9..7b0be8ef82 100644 --- a/std/os/child_process.zig +++ b/std/os/child_process.zig @@ -360,11 +360,14 @@ pub const ChildProcess = struct { errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); - const dev_null_fd = if (any_ignore) - try os.posixOpen("/dev/null", posix.O_RDWR, 0, null) - else - undefined - ; + const dev_null_fd = if (any_ignore) blk: { + const dev_null_path = "/dev/null"; + var fixed_buffer_mem: [dev_null_path.len + 1]u8 = undefined; + var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + break :blk try os.posixOpen(&fixed_allocator.allocator, "/dev/null", posix.O_RDWR, 0); + } else blk: { + break :blk undefined; + }; defer { if (any_ignore) os.close(dev_null_fd); } var env_map_owned: BufMap = undefined; @@ -466,12 +469,15 @@ pub const ChildProcess = struct { self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); - const nul_handle = if (any_ignore) - try os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, - windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null) - else - undefined - ; + const nul_handle = if (any_ignore) blk: { + const nul_file_path = "NUL"; + var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined; + var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, + windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL); + } else blk: { + break :blk undefined; + }; defer { if (any_ignore) os.close(nul_handle); } if (any_ignore) { try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); diff --git a/std/os/index.zig b/std/os/index.zig index a2da2ec673..b8d5f073e0 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -15,7 +15,6 @@ pub const posix = switch(builtin.os) { else => @compileError("Unsupported OS"), }; -pub const max_noalloc_path_len = 1024; pub const ChildProcess = @import("child_process.zig").ChildProcess; pub const path = @import("path.zig"); @@ -265,32 +264,14 @@ pub const PosixOpenError = error { Unexpected, }; -/// ::file_path may need to be copied in memory to add a null terminating byte. In this case -/// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed -/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned. -/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. +/// ::file_path needs to be copied in memory to add a null terminating byte. /// Calls POSIX open, keeps trying if it gets interrupted, and translates /// the return value into zig errors. -pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) PosixOpenError!i32 { - var stack_buf: [max_noalloc_path_len]u8 = undefined; - var path0: []u8 = undefined; - var need_free = false; - - if (file_path.len < stack_buf.len) { - path0 = stack_buf[0..file_path.len + 1]; - } else if (allocator) |a| { - path0 = try a.alloc(u8, file_path.len + 1); - need_free = true; - } else { - return error.NameTooLong; - } - defer if (need_free) { - (??allocator).free(path0); - }; - mem.copy(u8, path0, file_path); - path0[file_path.len] = 0; +pub fn posixOpen(allocator: &Allocator, file_path: []const u8, flags: u32, perm: usize) PosixOpenError!i32 { + const path_with_null = try cstr.addNullByte(allocator, file_path); + defer allocator.free(path_with_null); - return posixOpenC(path0.ptr, flags, perm); + return posixOpenC(path_with_null.ptr, flags, perm); } pub fn posixOpenC(file_path: &const u8, flags: u32, perm: usize) !i32 { @@ -784,11 +765,11 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [ try getRandomBytes(rand_buf[0..]); b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); - var out_file = try io.File.openWriteMode(tmp_path, mode, allocator); + var out_file = try io.File.openWriteMode(allocator, tmp_path, mode); defer out_file.close(); errdefer _ = deleteFile(allocator, tmp_path); - var in_file = try io.File.openRead(source_path, allocator); + var in_file = try io.File.openRead(allocator, source_path); defer in_file.close(); var buf: [page_size]u8 = undefined; @@ -1074,7 +1055,7 @@ pub const Dir = struct { }; pub fn open(allocator: &Allocator, dir_path: []const u8) !Dir { - const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); + const fd = try posixOpen(allocator, dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0); return Dir { .allocator = allocator, .fd = fd, @@ -1642,13 +1623,16 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) (error{Unexpected}) { pub fn openSelfExe() !io.File { switch (builtin.os) { Os.linux => { - return io.File.openRead("/proc/self/exe", null); + const proc_file_path = "/proc/self/exe"; + var fixed_buffer_mem: [proc_file_path.len + 1]u8 = undefined; + var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + return io.File.openRead(&fixed_allocator.allocator, proc_file_path); }, Os.macosx, Os.ios => { - var fixed_buffer_mem: [darwin.PATH_MAX]u8 = undefined; + var fixed_buffer_mem: [darwin.PATH_MAX * 2]u8 = undefined; var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); const self_exe_path = try selfExePath(&fixed_allocator.allocator); - return io.File.openRead(self_exe_path, null); + return io.File.openRead(&fixed_allocator.allocator, self_exe_path); }, else => @compileError("Unsupported OS"), } diff --git a/std/os/path.zig b/std/os/path.zig index 5a7428c220..0ea5d5a753 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -1161,7 +1161,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 { return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); }, Os.linux => { - const fd = try os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); + const fd = try os.posixOpen(allocator, pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0); defer os.close(fd); var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; diff --git a/std/os/windows/util.zig b/std/os/windows/util.zig index c19a5789e7..5af318b7b0 100644 --- a/std/os/windows/util.zig +++ b/std/os/windows/util.zig @@ -89,34 +89,17 @@ pub const OpenError = error { PipeBusy, Unexpected, OutOfMemory, - NameTooLong, }; -/// `file_path` may need to be copied in memory to add a null terminating byte. In this case -/// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed -/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned. -/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. -pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD, - creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&mem.Allocator) +/// `file_path` needs to be copied in memory to add a null terminating byte, hence the allocator. +pub fn windowsOpen(allocator: &mem.Allocator, file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD, + creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD) OpenError!windows.HANDLE { - var stack_buf: [os.max_noalloc_path_len]u8 = undefined; - var path0: []u8 = undefined; - var need_free = false; - defer if (need_free) (??allocator).free(path0); - - if (file_path.len < stack_buf.len) { - path0 = stack_buf[0..file_path.len + 1]; - } else if (allocator) |a| { - path0 = try a.alloc(u8, file_path.len + 1); - need_free = true; - } else { - return error.NameTooLong; - } - mem.copy(u8, path0, file_path); - path0[file_path.len] = 0; + const path_with_null = try cstr.addNullByte(allocator, file_path); + defer allocator.free(path_with_null); - const result = windows.CreateFileA(path0.ptr, desired_access, share_mode, null, creation_disposition, + const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition, flags_and_attrs, null); if (result == windows.INVALID_HANDLE_VALUE) { |
