diff --git a/lib/std/c.zig b/lib/std/c.zig index 58ebaaa804..acfc6b34f7 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int; pub extern "c" fn raise(sig: c_int) c_int; pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize; pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize; -pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize; -pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize; +pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize; +pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize; pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize; -pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize; +pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize; pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize; -pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize; -pub 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; +pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize; +pub 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; pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int; pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int; pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int; diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index d2d5e610c3..a8c8bbc34d 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -67,14 +67,14 @@ pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int; pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int; pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int; pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int; -pub extern "c" fn lseek64(fd: fd_t, offset: u64, whence: c_int) u64; -pub 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; +pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64; +pub 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; pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int; pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int; -pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize; -pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize; -pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize; -pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize; +pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize; +pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: i64) isize; +pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: i64) isize; +pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: i64) isize; pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize; pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int; diff --git a/lib/std/os.zig b/lib/std/os.zig index b78141d20b..358290a347 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -502,8 +502,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize { else system.pread; + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned while (true) { - const rc = pread_sym(fd, buf.ptr, adjusted_len, offset); + const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset); switch (errno(rc)) { 0 => return @intCast(usize, rc), EINTR => continue, @@ -577,12 +578,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { else system.ftruncate; - // XXX Pick a side and avoid this cast madness. - const casted_length = if (builtin.link_libc) - @bitCast(off_t, length) - else - length; - switch (errno(ftruncate_sym(fd, casted_length))) { + const ilen = @bitCast(i64, length); // the OS treats this as unsigned + switch (errno(ftruncate_sym(fd, ilen))) { 0 => return, EINTR => continue, EFBIG => return error.FileTooBig, @@ -912,8 +909,9 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize { else system.pwrite; + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned while (true) { - const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, offset); + const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset); switch (errno(rc)) { 0 => return @intCast(usize, rc), EINTR => continue, @@ -3750,7 +3748,8 @@ pub fn mmap( else system.mmap; - const rc = mmap_sym(ptr, length, prot, flags, fd, offset); + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned + const rc = mmap_sym(ptr, length, prot, flags, fd, ioffset); const err = if (builtin.link_libc) blk: { if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length]; break :blk system._errno().*; @@ -4104,8 +4103,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { else => |err| return unexpectedErrno(err), } } - const ipos = @bitCast(i64, offset); // the OS treats this as unsigned - switch (errno(system.lseek(fd, ipos, SEEK_SET))) { + + const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc) + system.lseek64 + else + system.lseek; + + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned + switch (errno(lseek_sym(fd, ioffset, SEEK_SET))) { 0 => return, EBADF => unreachable, // always a race condition EINVAL => return error.Unseekable, @@ -4146,7 +4151,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { else => |err| return unexpectedErrno(err), } } - switch (errno(system.lseek(fd, offset, SEEK_CUR))) { + const lseek_sym = if (builtin.os.tag == .linux and builtin.link_libc) + system.lseek64 + else + system.lseek; + + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned + switch (errno(lseek_sym(fd, ioffset, SEEK_CUR))) { 0 => return, EBADF => unreachable, // always a race condition EINVAL => return error.Unseekable, @@ -4192,7 +4203,8 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { else system.lseek; - switch (errno(lseek_sym(fd, offset, SEEK_END))) { + const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned + switch (errno(lseek_sym(fd, ioffset, SEEK_END))) { 0 => return, EBADF => unreachable, // always a race condition EINVAL => return error.Unseekable, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 6c88d9eae1..912dd3a6f7 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -59,15 +59,16 @@ const require_aligned_register_pair = std.Target.current.cpu.arch.isThumb(); // Split a 64bit value into a {LSB,MSB} pair. -fn splitValue64(val: u64) [2]u32 { +fn splitValue64(val: i64) [2]u32 { + const u = @bitCast(u64, val); switch (builtin.endian) { .Little => return [2]u32{ - @truncate(u32, val), - @truncate(u32, val >> 32), + @truncate(u32, u), + @truncate(u32, u >> 32), }, .Big => return [2]u32{ - @truncate(u32, val >> 32), - @truncate(u32, val), + @truncate(u32, u >> 32), + @truncate(u32, u), }, } } @@ -243,7 +244,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize { return syscall2(.umount2, @ptrToInt(special), flags); } -pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: u64) usize { +pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: i64) usize { if (@hasField(SYS, "mmap2")) { // Make sure the offset is also specified in multiples of page size if ((offset & (MMAP2_UNIT - 1)) != 0) @@ -256,7 +257,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of prot, flags, @bitCast(usize, @as(isize, fd)), - @truncate(usize, offset / MMAP2_UNIT), + @truncate(usize, @bitCast(u64, offset) / MMAP2_UNIT), ); } else { return syscall6( @@ -266,7 +267,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of prot, flags, @bitCast(usize, @as(isize, fd)), - offset, + @bitCast(u64, offset), ); } } @@ -308,7 +309,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize { return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count); } -pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize { +pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize { const offset_halves = splitValue64(offset); return syscall5( .preadv, @@ -320,7 +321,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize { ); } -pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize { +pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize { const offset_halves = splitValue64(offset); return syscall6( .preadv2, @@ -341,7 +342,7 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize { return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count); } -pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize { +pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize { const offset_halves = splitValue64(offset); return syscall5( .pwritev, @@ -353,7 +354,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us ); } -pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize { +pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize { const offset_halves = splitValue64(offset); return syscall6( .pwritev2, @@ -386,7 +387,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath)); } -pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { +pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize { if (@hasField(SYS, "pread64") and usize_bits < 64) { const offset_halves = splitValue64(offset); if (require_aligned_register_pair) { @@ -417,7 +418,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, - offset, + @bitCast(u64, offset), ); } } @@ -452,7 +453,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count); } -pub fn ftruncate(fd: i32, length: u64) usize { +pub fn ftruncate(fd: i32, length: i64) usize { if (@hasField(SYS, "ftruncate64") and usize_bits < 64) { const length_halves = splitValue64(length); if (require_aligned_register_pair) { @@ -475,12 +476,12 @@ pub fn ftruncate(fd: i32, length: u64) usize { return syscall2( .ftruncate, @bitCast(usize, @as(isize, fd)), - @truncate(usize, length), + @bitCast(usize, length), ); } } -pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize { +pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize { if (@hasField(SYS, "pwrite64") and usize_bits < 64) { const offset_halves = splitValue64(offset); @@ -512,7 +513,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize { @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, - offset, + @bitCast(u64, offset), ); } }