authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-07 14:42:10+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-11 12:33:48+02:00
log31f1cc9a0d80e87efb1f414352ff9d6abf2067ca
tree71f721104facaeaf79d4c53b365ea855099a1b18
parentf4a05286d34d2360da5a76cf0c77697775b571eb

std: Harmonize use of off_t between libc and Zig impls

Let's follow the libc/kernel convention and use an i64 for offsets, we bitcast as needed and avoid the useless conditional casts.

4 files changed, 55 insertions(+), 42 deletions(-)

lib/std/c.zig+5-5
...@@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;...@@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;
89pub extern "c" fn raise(sig: c_int) c_int;89pub extern "c" fn raise(sig: c_int) c_int;
90pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;90pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
91pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;91pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
92pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;92pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;
93pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;93pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize;
94pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;94pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;
95pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;95pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize;
96pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;96pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
97pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;97pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize;
98pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: u64) *c_void;98pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: off_t) *c_void;
99pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;99pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
100pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;100pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
101pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;101pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;
lib/std/c/linux.zig+6-6
...@@ -67,14 +67,14 @@ pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;...@@ -67,14 +67,14 @@ pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;
67pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;67pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;
68pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;68pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
69pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;69pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
70pub extern "c" fn lseek64(fd: fd_t, offset: u64, whence: c_int) u64;70pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
71pub extern "c" fn mmap64(addr: ?*align(std.mem.page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: u64) *c_void;71pub extern "c" fn mmap64(addr: ?*align(std.mem.page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: i64) *c_void;
72pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int;72pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int;
73pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;73pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
74pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;74pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize;
75pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;75pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: i64) isize;
76pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;76pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: i64) isize;
77pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;77pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: i64) isize;
78pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize;78pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize;
79pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int;79pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int;
8080
lib/std/os.zig+25-13
...@@ -502,8 +502,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {...@@ -502,8 +502,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
502 else502 else
503 system.pread;503 system.pread;
504504
505 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
505 while (true) {506 while (true) {
506 const rc = pread_sym(fd, buf.ptr, adjusted_len, offset);507 const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset);
507 switch (errno(rc)) {508 switch (errno(rc)) {
508 0 => return @intCast(usize, rc),509 0 => return @intCast(usize, rc),
509 EINTR => continue,510 EINTR => continue,
...@@ -577,12 +578,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {...@@ -577,12 +578,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
577 else578 else
578 system.ftruncate;579 system.ftruncate;
579580
580 // XXX Pick a side and avoid this cast madness.581 const ilen = @bitCast(i64, length); // the OS treats this as unsigned
581 const casted_length = if (builtin.link_libc)582 switch (errno(ftruncate_sym(fd, ilen))) {
582 @bitCast(off_t, length)
583 else
584 length;
585 switch (errno(ftruncate_sym(fd, casted_length))) {
586 0 => return,583 0 => return,
587 EINTR => continue,584 EINTR => continue,
588 EFBIG => return error.FileTooBig,585 EFBIG => return error.FileTooBig,
...@@ -912,8 +909,9 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {...@@ -912,8 +909,9 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
912 else909 else
913 system.pwrite;910 system.pwrite;
914911
912 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
915 while (true) {913 while (true) {
916 const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, offset);914 const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset);
917 switch (errno(rc)) {915 switch (errno(rc)) {
918 0 => return @intCast(usize, rc),916 0 => return @intCast(usize, rc),
919 EINTR => continue,917 EINTR => continue,
...@@ -3750,7 +3748,8 @@ pub fn mmap(...@@ -3750,7 +3748,8 @@ pub fn mmap(
3750 else3748 else
3751 system.mmap;3749 system.mmap;
37523750
3753 const rc = mmap_sym(ptr, length, prot, flags, fd, offset);3751 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
3752 const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset);
3754 const err = if (builtin.link_libc) blk: {3753 const err = if (builtin.link_libc) blk: {
3755 if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];3754 if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
3756 break :blk system._errno().*;3755 break :blk system._errno().*;
...@@ -4104,8 +4103,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -4104,8 +4103,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
4104 else => |err| return unexpectedErrno(err),4103 else => |err| return unexpectedErrno(err),
4105 }4104 }
4106 }4105 }
4107 const ipos = @bitCast(i64, offset); // the OS treats this as unsigned4106
4108 switch (errno(system.lseek(fd, ipos, SEEK_SET))) {4107 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4108 system.lseek64
4109 else
4110 system.lseek;
4111
4112 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4113 switch (errno(lseek_sym(fd, ioffset, SEEK_SET))) {
4109 0 => return,4114 0 => return,
4110 EBADF => unreachable, // always a race condition4115 EBADF => unreachable, // always a race condition
4111 EINVAL => return error.Unseekable,4116 EINVAL => return error.Unseekable,
...@@ -4146,7 +4151,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -4146,7 +4151,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
4146 else => |err| return unexpectedErrno(err),4151 else => |err| return unexpectedErrno(err),
4147 }4152 }
4148 }4153 }
4149 switch (errno(system.lseek(fd, offset, SEEK_CUR))) {4154 const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc)
4155 system.lseek64
4156 else
4157 system.lseek;
4158
4159 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4160 switch (errno(lseek_sym(fd, ioffset, SEEK_CUR))) {
4150 0 => return,4161 0 => return,
4151 EBADF => unreachable, // always a race condition4162 EBADF => unreachable, // always a race condition
4152 EINVAL => return error.Unseekable,4163 EINVAL => return error.Unseekable,
...@@ -4192,7 +4203,8 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -4192,7 +4203,8 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
4192 else4203 else
4193 system.lseek;4204 system.lseek;
41944205
4195 switch (errno(lseek_sym(fd, offset, SEEK_END))) {4206 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
4207 switch (errno(lseek_sym(fd, ioffset, SEEK_END))) {
4196 0 => return,4208 0 => return,
4197 EBADF => unreachable, // always a race condition4209 EBADF => unreachable, // always a race condition
4198 EINVAL => return error.Unseekable,4210 EINVAL => return error.Unseekable,
lib/std/os/linux.zig+19-18
...@@ -59,15 +59,16 @@ const require_aligned_register_pair =...@@ -59,15 +59,16 @@ const require_aligned_register_pair =
59 std.Target.current.cpu.arch.isThumb();59 std.Target.current.cpu.arch.isThumb();
6060
61// Split a 64bit value into a {LSB,MSB} pair.61// Split a 64bit value into a {LSB,MSB} pair.
62fn splitValue64(val: u64) [2]u32 {62fn splitValue64(val: i64) [2]u32 {
63 const u = @bitCast(u64, val);
63 switch (builtin.endian) {64 switch (builtin.endian) {
64 .Little => return [2]u32{65 .Little => return [2]u32{
65 @truncate(u32, val),66 @truncate(u32, u),
66 @truncate(u32, val >> 32),67 @truncate(u32, u >> 32),
67 },68 },
68 .Big => return [2]u32{69 .Big => return [2]u32{
69 @truncate(u32, val >> 32),70 @truncate(u32, u >> 32),
70 @truncate(u32, val),71 @truncate(u32, u),
71 },72 },
72 }73 }
73}74}
...@@ -243,7 +244,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {...@@ -243,7 +244,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {
243 return syscall2(.umount2, @ptrToInt(special), flags);244 return syscall2(.umount2, @ptrToInt(special), flags);
244}245}
245246
246pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: u64) usize {247pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: i64) usize {
247 if (@hasField(SYS, "mmap2")) {248 if (@hasField(SYS, "mmap2")) {
248 // Make sure the offset is also specified in multiples of page size249 // Make sure the offset is also specified in multiples of page size
249 if ((offset & (MMAP2_UNIT - 1)) != 0)250 if ((offset & (MMAP2_UNIT - 1)) != 0)
...@@ -256,7 +257,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -256,7 +257,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
256 prot,257 prot,
257 flags,258 flags,
258 @bitCast(usize, @as(isize, fd)),259 @bitCast(usize, @as(isize, fd)),
259 @truncate(usize, offset / MMAP2_UNIT),260 @truncate(usize, @bitCast(u64, offset) / MMAP2_UNIT),
260 );261 );
261 } else {262 } else {
262 return syscall6(263 return syscall6(
...@@ -266,7 +267,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -266,7 +267,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
266 prot,267 prot,
267 flags,268 flags,
268 @bitCast(usize, @as(isize, fd)),269 @bitCast(usize, @as(isize, fd)),
269 offset,270 @bitCast(u64, offset),
270 );271 );
271 }272 }
272}273}
...@@ -308,7 +309,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {...@@ -308,7 +309,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
308 return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);309 return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
309}310}
310311
311pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {312pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
312 const offset_halves = splitValue64(offset);313 const offset_halves = splitValue64(offset);
313 return syscall5(314 return syscall5(
314 .preadv,315 .preadv,
...@@ -320,7 +321,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {...@@ -320,7 +321,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
320 );321 );
321}322}
322323
323pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {324pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
324 const offset_halves = splitValue64(offset);325 const offset_halves = splitValue64(offset);
325 return syscall6(326 return syscall6(
326 .preadv2,327 .preadv2,
...@@ -341,7 +342,7 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {...@@ -341,7 +342,7 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
341 return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);342 return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
342}343}
343344
344pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {345pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
345 const offset_halves = splitValue64(offset);346 const offset_halves = splitValue64(offset);
346 return syscall5(347 return syscall5(
347 .pwritev,348 .pwritev,
...@@ -353,7 +354,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us...@@ -353,7 +354,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
353 );354 );
354}355}
355356
356pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {357pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
357 const offset_halves = splitValue64(offset);358 const offset_halves = splitValue64(offset);
358 return syscall6(359 return syscall6(
359 .pwritev2,360 .pwritev2,
...@@ -386,7 +387,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us...@@ -386,7 +387,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
386 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));387 return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
387}388}
388389
389pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {390pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {
390 if (@hasField(SYS, "pread64") and usize_bits < 64) {391 if (@hasField(SYS, "pread64") and usize_bits < 64) {
391 const offset_halves = splitValue64(offset);392 const offset_halves = splitValue64(offset);
392 if (require_aligned_register_pair) {393 if (require_aligned_register_pair) {
...@@ -417,7 +418,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {...@@ -417,7 +418,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
417 @bitCast(usize, @as(isize, fd)),418 @bitCast(usize, @as(isize, fd)),
418 @ptrToInt(buf),419 @ptrToInt(buf),
419 count,420 count,
420 offset,421 @bitCast(u64, offset),
421 );422 );
422 }423 }
423}424}
...@@ -452,7 +453,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {...@@ -452,7 +453,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
452 return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);453 return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
453}454}
454455
455pub fn ftruncate(fd: i32, length: u64) usize {456pub fn ftruncate(fd: i32, length: i64) usize {
456 if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {457 if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {
457 const length_halves = splitValue64(length);458 const length_halves = splitValue64(length);
458 if (require_aligned_register_pair) {459 if (require_aligned_register_pair) {
...@@ -475,12 +476,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {...@@ -475,12 +476,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {
475 return syscall2(476 return syscall2(
476 .ftruncate,477 .ftruncate,
477 @bitCast(usize, @as(isize, fd)),478 @bitCast(usize, @as(isize, fd)),
478 @truncate(usize, length),479 @bitCast(usize, length),
479 );480 );
480 }481 }
481}482}
482483
483pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {484pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {
484 if (@hasField(SYS, "pwrite64") and usize_bits < 64) {485 if (@hasField(SYS, "pwrite64") and usize_bits < 64) {
485 const offset_halves = splitValue64(offset);486 const offset_halves = splitValue64(offset);
486487
...@@ -512,7 +513,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {...@@ -512,7 +513,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
512 @bitCast(usize, @as(isize, fd)),513 @bitCast(usize, @as(isize, fd)),
513 @ptrToInt(buf),514 @ptrToInt(buf),
514 count,515 count,
515 offset,516 @bitCast(u64, offset),
516 );517 );
517 }518 }
518}519}