diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-10-12 17:57:35 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-10-12 17:57:35 -0700 |
| commit | c19dcafa17117475f8334d5186bd87fb56c9d315 (patch) | |
| tree | f7af587f9a1355c5229699d78876f7d1a84942a4 /lib/std/os.zig | |
| parent | c0b2813e0468586faee5bf3ee7583afad53d771a (diff) | |
| parent | 2ab0c7391a871a3063f825e08e02ea2a8e9269e9 (diff) | |
| download | zig-c19dcafa17117475f8334d5186bd87fb56c9d315.tar.gz zig-c19dcafa17117475f8334d5186bd87fb56c9d315.zip | |
Merge remote-tracking branch 'origin/master' into llvm11
Diffstat (limited to 'lib/std/os.zig')
| -rw-r--r-- | lib/std/os.zig | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index c89f122c63..bc7dae031c 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -62,7 +62,7 @@ pub const system = if (@hasDecl(root, "os") and root.os != @This()) else if (builtin.link_libc) std.c else switch (builtin.os.tag) { - .macosx, .ios, .watchos, .tvos => darwin, + .macos, .ios, .watchos, .tvos => darwin, .freebsd => freebsd, .linux => linux, .netbsd => netbsd, @@ -354,7 +354,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { // Prevents EINVAL. const max_count = switch (std.Target.current.os.tag) { .linux => 0x7ffff000, - .macosx, .ios, .watchos, .tvos => math.maxInt(i32), + .macos, .ios, .watchos, .tvos => math.maxInt(i32), else => math.maxInt(isize), }; const adjusted_len = math.min(max_count, buf.len); @@ -582,7 +582,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { /// On these systems, the read races with concurrent writes to the same file descriptor. pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { const have_pread_but_not_preadv = switch (std.Target.current.os.tag) { - .windows, .macosx, .ios, .watchos, .tvos => true, + .windows, .macos, .ios, .watchos, .tvos => true, else => false, }; if (have_pread_but_not_preadv) { @@ -709,7 +709,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { const max_count = switch (std.Target.current.os.tag) { .linux => 0x7ffff000, - .macosx, .ios, .watchos, .tvos => math.maxInt(i32), + .macos, .ios, .watchos, .tvos => math.maxInt(i32), else => math.maxInt(isize), }; const adjusted_len = math.min(max_count, bytes.len); @@ -863,7 +863,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { // Prevent EINVAL. const max_count = switch (std.Target.current.os.tag) { .linux => 0x7ffff000, - .macosx, .ios, .watchos, .tvos => math.maxInt(i32), + .macos, .ios, .watchos, .tvos => math.maxInt(i32), else => math.maxInt(isize), }; const adjusted_len = math.min(max_count, bytes.len); @@ -915,7 +915,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { /// If `iov.len` is larger than will fit in a `u31`, a partial write will occur. pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize { const have_pwrite_but_not_pwritev = switch (std.Target.current.os.tag) { - .windows, .macosx, .ios, .watchos, .tvos => true, + .windows, .macos, .ios, .watchos, .tvos => true, else => false, }; @@ -4091,7 +4091,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { const end_index = std.unicode.utf16leToUtf8(out_buffer, wide_slice) catch unreachable; return out_buffer[0..end_index]; }, - .macosx, .ios, .watchos, .tvos => { + .macos, .ios, .watchos, .tvos => { // On macOS, we can use F_GETPATH fcntl command to query the OS for // the path to the file descriptor. @memset(out_buffer, 0, MAX_PATH_BYTES); @@ -4688,7 +4688,7 @@ pub fn sendfile( }); const max_count = switch (std.Target.current.os.tag) { .linux => 0x7ffff000, - .macosx, .ios, .watchos, .tvos => math.maxInt(i32), + .macos, .ios, .watchos, .tvos => math.maxInt(i32), else => math.maxInt(size_t), }; @@ -4846,7 +4846,7 @@ pub fn sendfile( } } }, - .macosx, .ios, .tvos, .watchos => sf: { + .macos, .ios, .tvos, .watchos => sf: { var hdtr_data: std.c.sf_hdtr = undefined; var hdtr: ?*std.c.sf_hdtr = null; if (headers.len != 0 or trailers.len != 0) { @@ -4945,6 +4945,9 @@ pub fn sendfile( pub const CopyFileRangeError = error{ FileTooBig, InputOutput, + /// `fd_in` is not open for reading; or `fd_out` is not open for writing; + /// or the `O_APPEND` flag is set for `fd_out`. + FilesOpenedWithWrongFlags, IsDir, OutOfMemory, NoSpaceLeft, @@ -4953,6 +4956,11 @@ pub const CopyFileRangeError = error{ FileBusy, } || PReadError || PWriteError || UnexpectedError; +var has_copy_file_range_syscall = init: { + const kernel_has_syscall = std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) orelse true; + break :init std.atomic.Int(bool).init(kernel_has_syscall); +}; + /// Transfer data between file descriptors at specified offsets. /// Returns the number of bytes written, which can less than requested. /// @@ -4981,22 +4989,18 @@ pub const CopyFileRangeError = error{ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize { const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok; - // TODO support for other systems than linux - const try_syscall = comptime std.Target.current.os.isAtLeast(.linux, .{ .major = 4, .minor = 5 }) != false; - - if (use_c or try_syscall) { + if (std.Target.current.os.tag == .linux and + (use_c or has_copy_file_range_syscall.get())) + { const sys = if (use_c) std.c else linux; var off_in_copy = @bitCast(i64, off_in); var off_out_copy = @bitCast(i64, off_out); const rc = sys.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags); - - // TODO avoid wasting a syscall every time if kernel is too old and returns ENOSYS https://github.com/ziglang/zig/issues/1018 - switch (sys.getErrno(rc)) { 0 => return @intCast(usize, rc), - EBADF => unreachable, + EBADF => return error.FilesOpenedWithWrongFlags, EFBIG => return error.FileTooBig, EIO => return error.InputOutput, EISDIR => return error.IsDir, @@ -5005,9 +5009,14 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len EOVERFLOW => return error.Unseekable, EPERM => return error.PermissionDenied, ETXTBSY => return error.FileBusy, - EINVAL => {}, // these may not be regular files, try fallback - EXDEV => {}, // support for cross-filesystem copy added in Linux 5.3, use fallback - ENOSYS => {}, // syscall added in Linux 4.5, use fallback + // these may not be regular files, try fallback + EINVAL => {}, + // support for cross-filesystem copy added in Linux 5.3, use fallback + EXDEV => {}, + // syscall added in Linux 4.5, use fallback + ENOSYS => { + has_copy_file_range_syscall.set(false); + }, else => |err| return unexpectedErrno(err), } } |
