| author | |
| committer | |
| log | 72c4b80d31c3ccecbd8cf96e5afdf756e055dc6a |
| tree | 08db5921f6b3c08fb9f6590fac8c29f9941c4c25 |
| parent | 62e3d67605075f27134736917495e7a7a17869f6 |
| signature |
Co-authored-by: Veikka Tuominen <git@vexu.eu>7 files changed, 26 insertions(+), 4 deletions(-)
lib/std/os.zig+4-4| ... | @@ -787,7 +787,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { | ... | @@ -787,7 +787,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { |
| 787 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are | 787 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are |
| 788 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. | 788 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. |
| 789 | /// | 789 | /// |
| 790 | /// If `iov.len` is larger than will fit in a `u31`, a partial write will occur. | 790 | /// If `iov.len` is larger than `IOV_MAX`, a partial write will occur. |
| 791 | pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { | 791 | pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { |
| 792 | if (std.Target.current.os.tag == .windows) { | 792 | if (std.Target.current.os.tag == .windows) { |
| 793 | // TODO improve this to use WriteFileScatter | 793 | // TODO improve this to use WriteFileScatter |
| ... | @@ -816,7 +816,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { | ... | @@ -816,7 +816,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize { |
| 816 | } | 816 | } |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31); | 819 | const iov_count = if (iov.len > IOV_MAX) IOV_MAX else @intCast(u31, iov.len); |
| 820 | while (true) { | 820 | while (true) { |
| 821 | const rc = system.writev(fd, iov.ptr, iov_count); | 821 | const rc = system.writev(fd, iov.ptr, iov_count); |
| 822 | switch (errno(rc)) { | 822 | switch (errno(rc)) { |
| ... | @@ -954,7 +954,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { | ... | @@ -954,7 +954,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { |
| 954 | /// * Darwin | 954 | /// * Darwin |
| 955 | /// * Windows | 955 | /// * Windows |
| 956 | /// | 956 | /// |
| 957 | /// If `iov.len` is larger than will fit in a `u31`, a partial write will occur. | 957 | /// If `iov.len` is larger than `IOV_MAX`, a partial write will occur. |
| 958 | pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize { | 958 | pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize { |
| 959 | const have_pwrite_but_not_pwritev = switch (std.Target.current.os.tag) { | 959 | const have_pwrite_but_not_pwritev = switch (std.Target.current.os.tag) { |
| 960 | .windows, .macos, .ios, .watchos, .tvos, .haiku => true, | 960 | .windows, .macos, .ios, .watchos, .tvos, .haiku => true, |
| ... | @@ -997,7 +997,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz | ... | @@ -997,7 +997,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz |
| 997 | else | 997 | else |
| 998 | system.pwritev; | 998 | system.pwritev; |
| 999 | 999 | ||
| 1000 | const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31); | 1000 | const iov_count = if (iov.len > IOV_MAX) IOV_MAX else @intCast(u31, iov.len); |
| 1001 | const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned | 1001 | const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned |
| 1002 | while (true) { | 1002 | while (true) { |
| 1003 | const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset); | 1003 | const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset); |
lib/std/os/bits/darwin.zig+1| ... | @@ -235,6 +235,7 @@ pub const host_t = mach_port_t; | ... | @@ -235,6 +235,7 @@ pub const host_t = mach_port_t; |
| 235 | pub const CALENDAR_CLOCK = 1; | 235 | pub const CALENDAR_CLOCK = 1; |
| 236 | 236 | ||
| 237 | pub const PATH_MAX = 1024; | 237 | pub const PATH_MAX = 1024; |
| 238 | pub const IOV_MAX = 16; | ||
| 238 | 239 | ||
| 239 | pub const STDIN_FILENO = 0; | 240 | pub const STDIN_FILENO = 0; |
| 240 | pub const STDOUT_FILENO = 1; | 241 | pub const STDOUT_FILENO = 1; |
lib/std/os/bits/dragonfly.zig+1| ... | @@ -168,6 +168,7 @@ pub const SA_NOCLDWAIT = 0x0020; | ... | @@ -168,6 +168,7 @@ pub const SA_NOCLDWAIT = 0x0020; |
| 168 | pub const SA_SIGINFO = 0x0040; | 168 | pub const SA_SIGINFO = 0x0040; |
| 169 | 169 | ||
| 170 | pub const PATH_MAX = 1024; | 170 | pub const PATH_MAX = 1024; |
| 171 | pub const IOV_MAX = KERN_IOV_MAX; | ||
| 171 | 172 | ||
| 172 | pub const ino_t = c_ulong; | 173 | pub const ino_t = c_ulong; |
| 173 | 174 |
lib/std/os/bits/freebsd.zig+2| ... | @@ -238,8 +238,10 @@ pub const CTL_DEBUG = 5; | ... | @@ -238,8 +238,10 @@ pub const CTL_DEBUG = 5; |
| 238 | 238 | ||
| 239 | pub const KERN_PROC = 14; // struct: process entries | 239 | pub const KERN_PROC = 14; // struct: process entries |
| 240 | pub const KERN_PROC_PATHNAME = 12; // path to executable | 240 | pub const KERN_PROC_PATHNAME = 12; // path to executable |
| 241 | pub const KERN_IOV_MAX = 35; | ||
| 241 | 242 | ||
| 242 | pub const PATH_MAX = 1024; | 243 | pub const PATH_MAX = 1024; |
| 244 | pub const IOV_MAX = KERN_IOV_MAX; | ||
| 243 | 245 | ||
| 244 | pub const STDIN_FILENO = 0; | 246 | pub const STDIN_FILENO = 0; |
| 245 | pub const STDOUT_FILENO = 1; | 247 | pub const STDOUT_FILENO = 1; |
lib/std/os/bits/netbsd.zig+2| ... | @@ -405,8 +405,10 @@ pub const CTL_DEBUG = 5; | ... | @@ -405,8 +405,10 @@ pub const CTL_DEBUG = 5; |
| 405 | 405 | ||
| 406 | pub const KERN_PROC_ARGS = 48; // struct: process argv/env | 406 | pub const KERN_PROC_ARGS = 48; // struct: process argv/env |
| 407 | pub const KERN_PROC_PATHNAME = 5; // path to executable | 407 | pub const KERN_PROC_PATHNAME = 5; // path to executable |
| 408 | pub const KERN_IOV_MAX = 38; | ||
| 408 | 409 | ||
| 409 | pub const PATH_MAX = 1024; | 410 | pub const PATH_MAX = 1024; |
| 411 | pub const IOV_MAX = KERN_IOV_MAX; | ||
| 410 | 412 | ||
| 411 | pub const STDIN_FILENO = 0; | 413 | pub const STDIN_FILENO = 0; |
| 412 | pub const STDOUT_FILENO = 1; | 414 | pub const STDOUT_FILENO = 1; |
lib/std/os/bits/wasi.zig+2| ... | @@ -76,6 +76,8 @@ pub const kernel_stat = struct { | ... | @@ -76,6 +76,8 @@ pub const kernel_stat = struct { |
| 76 | } | 76 | } |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | pub const IOV_MAX = 1024; | ||
| 80 | |||
| 79 | pub const AT_REMOVEDIR: u32 = 0x4; | 81 | pub const AT_REMOVEDIR: u32 = 0x4; |
| 80 | pub const AT_FDCWD: fd_t = -2; | 82 | pub const AT_FDCWD: fd_t = -2; |
| 81 | 83 |
lib/std/os/test.zig+14| ... | @@ -786,3 +786,17 @@ test "dup & dup2" { | ... | @@ -786,3 +786,17 @@ test "dup & dup2" { |
| 786 | var buf: [7]u8 = undefined; | 786 | var buf: [7]u8 = undefined; |
| 787 | try testing.expectEqualStrings("dupdup2", buf[0..try file.readAll(&buf)]); | 787 | try testing.expectEqualStrings("dupdup2", buf[0..try file.readAll(&buf)]); |
| 788 | } | 788 | } |
| 789 | |||
| 790 | test "writev longer than IOV_MAX" { | ||
| 791 | if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; | ||
| 792 | |||
| 793 | var tmp = tmpDir(.{}); | ||
| 794 | defer tmp.cleanup(); | ||
| 795 | |||
| 796 | var file = try tmp.dir.createFile("pwritev", .{}); | ||
| 797 | defer file.close(); | ||
| 798 | |||
| 799 | const iovecs = [_]os.iovec_const{.{ .iov_base = "a", .iov_len = 1 }} ** (os.IOV_MAX + 1); | ||
| 800 | const amt = try file.writev(&iovecs); | ||
| 801 | try testing.expectEqual(@as(usize, os.IOV_MAX), amt); | ||
| 802 | } |