Skip to content

Commit 31f1cc9

Browse files
committed
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.
1 parent f4a0528 commit 31f1cc9

File tree

4 files changed

+55
-42
lines changed

4 files changed

+55
-42
lines changed

lib/std/c.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ pub extern "c" fn ftruncate(fd: c_int, length: off_t) c_int;
8989
pub extern "c" fn raise(sig: c_int) c_int;
9090
pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
9191
pub extern "c" fn readv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint) isize;
92-
pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
93-
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;
92+
pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: off_t) isize;
93+
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: off_t) isize;
9494
pub extern "c" fn writev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint) isize;
95-
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;
95+
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: off_t) isize;
9696
pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
97-
pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;
98-
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;
97+
pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: off_t) isize;
98+
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;
9999
pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
100100
pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
101101
pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;

lib/std/c/linux.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ pub extern "c" fn fstat64(fd: fd_t, buf: *libc_stat) c_int;
6767
pub extern "c" fn fstatat64(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int;
6868
pub extern "c" fn ftruncate64(fd: c_int, length: off_t) c_int;
6969
pub extern "c" fn getrlimit64(resource: rlimit_resource, rlim: *rlimit) c_int;
70-
pub extern "c" fn lseek64(fd: fd_t, offset: u64, whence: c_int) u64;
71-
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;
70+
pub extern "c" fn lseek64(fd: fd_t, offset: i64, whence: c_int) i64;
71+
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;
7272
pub extern "c" fn open64(path: [*:0]const u8, oflag: c_uint, ...) c_int;
7373
pub extern "c" fn openat64(fd: c_int, path: [*:0]const u8, oflag: c_uint, ...) c_int;
74-
pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
75-
pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: u64) isize;
76-
pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;
77-
pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: u64) isize;
74+
pub extern "c" fn pread64(fd: fd_t, buf: [*]u8, nbyte: usize, offset: i64) isize;
75+
pub extern "c" fn preadv64(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: i64) isize;
76+
pub extern "c" fn pwrite64(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: i64) isize;
77+
pub extern "c" fn pwritev64(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: i64) isize;
7878
pub extern "c" fn sendfile64(out_fd: fd_t, in_fd: fd_t, offset: ?*i64, count: usize) isize;
7979
pub extern "c" fn setrlimit64(resource: rlimit_resource, rlim: *const rlimit) c_int;
8080

lib/std/os.zig

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,9 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
502502
else
503503
system.pread;
504504

505+
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
505506
while (true) {
506-
const rc = pread_sym(fd, buf.ptr, adjusted_len, offset);
507+
const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset);
507508
switch (errno(rc)) {
508509
0 => return @intCast(usize, rc),
509510
EINTR => continue,
@@ -577,12 +578,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
577578
else
578579
system.ftruncate;
579580

580-
// XXX Pick a side and avoid this cast madness.
581-
const casted_length = if (builtin.link_libc)
582-
@bitCast(off_t, length)
583-
else
584-
length;
585-
switch (errno(ftruncate_sym(fd, casted_length))) {
581+
const ilen = @bitCast(i64, length); // the OS treats this as unsigned
582+
switch (errno(ftruncate_sym(fd, ilen))) {
586583
0 => return,
587584
EINTR => continue,
588585
EFBIG => return error.FileTooBig,
@@ -912,8 +909,9 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
912909
else
913910
system.pwrite;
914911

912+
const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
915913
while (true) {
916-
const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, offset);
914+
const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset);
917915
switch (errno(rc)) {
918916
0 => return @intCast(usize, rc),
919917
EINTR => continue,
@@ -3750,7 +3748,8 @@ pub fn mmap(
37503748
else
37513749
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);
37543753
const err = if (builtin.link_libc) blk: {
37553754
if (rc != std.c.MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
37563755
break :blk system._errno().*;
@@ -4104,8 +4103,14 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
41044103
else => |err| return unexpectedErrno(err),
41054104
}
41064105
}
4107-
const ipos = @bitCast(i64, offset); // the OS treats this as unsigned
4108-
switch (errno(system.lseek(fd, ipos, SEEK_SET))) {
4106+
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))) {
41094114
0 => return,
41104115
EBADF => unreachable, // always a race condition
41114116
EINVAL => return error.Unseekable,
@@ -4146,7 +4151,13 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
41464151
else => |err| return unexpectedErrno(err),
41474152
}
41484153
}
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))) {
41504161
0 => return,
41514162
EBADF => unreachable, // always a race condition
41524163
EINVAL => return error.Unseekable,
@@ -4192,7 +4203,8 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
41924203
else
41934204
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))) {
41964208
0 => return,
41974209
EBADF => unreachable, // always a race condition
41984210
EINVAL => return error.Unseekable,

lib/std/os/linux.zig

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,16 @@ const require_aligned_register_pair =
5959
std.Target.current.cpu.arch.isThumb();
6060

6161
// Split a 64bit value into a {LSB,MSB} pair.
62-
fn splitValue64(val: u64) [2]u32 {
62+
fn splitValue64(val: i64) [2]u32 {
63+
const u = @bitCast(u64, val);
6364
switch (builtin.endian) {
6465
.Little => return [2]u32{
65-
@truncate(u32, val),
66-
@truncate(u32, val >> 32),
66+
@truncate(u32, u),
67+
@truncate(u32, u >> 32),
6768
},
6869
.Big => return [2]u32{
69-
@truncate(u32, val >> 32),
70-
@truncate(u32, val),
70+
@truncate(u32, u >> 32),
71+
@truncate(u32, u),
7172
},
7273
}
7374
}
@@ -243,7 +244,7 @@ pub fn umount2(special: [*:0]const u8, flags: u32) usize {
243244
return syscall2(.umount2, @ptrToInt(special), flags);
244245
}
245246

246-
pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: u64) usize {
247+
pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: i64) usize {
247248
if (@hasField(SYS, "mmap2")) {
248249
// Make sure the offset is also specified in multiples of page size
249250
if ((offset & (MMAP2_UNIT - 1)) != 0)
@@ -256,7 +257,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
256257
prot,
257258
flags,
258259
@bitCast(usize, @as(isize, fd)),
259-
@truncate(usize, offset / MMAP2_UNIT),
260+
@truncate(usize, @bitCast(u64, offset) / MMAP2_UNIT),
260261
);
261262
} else {
262263
return syscall6(
@@ -266,7 +267,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
266267
prot,
267268
flags,
268269
@bitCast(usize, @as(isize, fd)),
269-
offset,
270+
@bitCast(u64, offset),
270271
);
271272
}
272273
}
@@ -308,7 +309,7 @@ pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
308309
return syscall3(.read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
309310
}
310311

311-
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
312+
pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: i64) usize {
312313
const offset_halves = splitValue64(offset);
313314
return syscall5(
314315
.preadv,
@@ -320,7 +321,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
320321
);
321322
}
322323

323-
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
324+
pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: i64, flags: kernel_rwf) usize {
324325
const offset_halves = splitValue64(offset);
325326
return syscall6(
326327
.preadv2,
@@ -341,7 +342,7 @@ pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
341342
return syscall3(.writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
342343
}
343344

344-
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
345+
pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64) usize {
345346
const offset_halves = splitValue64(offset);
346347
return syscall5(
347348
.pwritev,
@@ -353,7 +354,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
353354
);
354355
}
355356

356-
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
357+
pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: i64, flags: kernel_rwf) usize {
357358
const offset_halves = splitValue64(offset);
358359
return syscall6(
359360
.pwritev2,
@@ -386,7 +387,7 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us
386387
return syscall3(.symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
387388
}
388389

389-
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
390+
pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: i64) usize {
390391
if (@hasField(SYS, "pread64") and usize_bits < 64) {
391392
const offset_halves = splitValue64(offset);
392393
if (require_aligned_register_pair) {
@@ -417,7 +418,7 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
417418
@bitCast(usize, @as(isize, fd)),
418419
@ptrToInt(buf),
419420
count,
420-
offset,
421+
@bitCast(u64, offset),
421422
);
422423
}
423424
}
@@ -452,7 +453,7 @@ pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
452453
return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
453454
}
454455

455-
pub fn ftruncate(fd: i32, length: u64) usize {
456+
pub fn ftruncate(fd: i32, length: i64) usize {
456457
if (@hasField(SYS, "ftruncate64") and usize_bits < 64) {
457458
const length_halves = splitValue64(length);
458459
if (require_aligned_register_pair) {
@@ -475,12 +476,12 @@ pub fn ftruncate(fd: i32, length: u64) usize {
475476
return syscall2(
476477
.ftruncate,
477478
@bitCast(usize, @as(isize, fd)),
478-
@truncate(usize, length),
479+
@bitCast(usize, length),
479480
);
480481
}
481482
}
482483

483-
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
484+
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: i64) usize {
484485
if (@hasField(SYS, "pwrite64") and usize_bits < 64) {
485486
const offset_halves = splitValue64(offset);
486487

@@ -512,7 +513,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: u64) usize {
512513
@bitCast(usize, @as(isize, fd)),
513514
@ptrToInt(buf),
514515
count,
515-
offset,
516+
@bitCast(u64, offset),
516517
);
517518
}
518519
}

0 commit comments

Comments
 (0)