aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-10-12 17:57:35 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-10-12 17:57:35 -0700
commitc19dcafa17117475f8334d5186bd87fb56c9d315 (patch)
treef7af587f9a1355c5229699d78876f7d1a84942a4 /lib/std/os.zig
parentc0b2813e0468586faee5bf3ee7583afad53d771a (diff)
parent2ab0c7391a871a3063f825e08e02ea2a8e9269e9 (diff)
downloadzig-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.zig49
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),
}
}