Skip to content

Commit 6bf8ea4

Browse files
authored
Use the syscall macro instead of c::syscall. (#702)
This makes the codebase more consistent, as syscalls made by the libc backend are now always done in the same way. And, it's easier to audit the signatures, as they're now always explicitly declared. This also eliminates the `syscall_*` conversion routines and varous manual conversions to `c::c_long`.
1 parent 540f1f3 commit 6bf8ea4

File tree

11 files changed

+452
-257
lines changed

11 files changed

+452
-257
lines changed

src/backend/libc/c.rs

Lines changed: 195 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -192,19 +192,19 @@ mod readwrite_pv64 {
192192
// 64-bit offsets on 32-bit platforms are passed in endianness-specific
193193
// lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
194194
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
195-
fn lo(x: u64) -> usize {
195+
fn lo(x: i64) -> usize {
196196
(x >> 32) as usize
197197
}
198198
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
199-
fn hi(x: u64) -> usize {
200-
(x & 0xffff_ffff) as usize
199+
fn hi(x: i64) -> usize {
200+
x as usize
201201
}
202202
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
203-
fn lo(x: u64) -> usize {
204-
(x & 0xffff_ffff) as usize
203+
fn lo(x: i64) -> usize {
204+
x as usize
205205
}
206206
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
207-
fn hi(x: u64) -> usize {
207+
fn hi(x: i64) -> usize {
208208
(x >> 32) as usize
209209
}
210210

@@ -226,18 +226,28 @@ mod readwrite_pv64 {
226226
} else {
227227
#[cfg(target_pointer_width = "32")]
228228
{
229-
libc::syscall(
230-
libc::SYS_preadv,
231-
fd,
232-
iov,
233-
iovcnt,
234-
hi(offset as u64),
235-
lo(offset as u64),
236-
) as libc::ssize_t
229+
syscall! {
230+
fn preadv(
231+
fd: libc::c_int,
232+
iov: *const libc::iovec,
233+
iovcnt: libc::c_int,
234+
offset_hi: usize,
235+
offset_lo: usize
236+
) via SYS_preadv -> libc::ssize_t
237+
}
238+
preadv(fd, iov, iovcnt, hi(offset), lo(offset))
237239
}
238240
#[cfg(target_pointer_width = "64")]
239241
{
240-
libc::syscall(libc::SYS_preadv, fd, iov, iovcnt, offset) as libc::ssize_t
242+
syscall! {
243+
fn preadv(
244+
fd: libc::c_int,
245+
iov: *const libc::iovec,
246+
iovcnt: libc::c_int,
247+
offset: libc::off_t
248+
) via SYS_preadv -> libc::ssize_t
249+
}
250+
preadv(fd, iov, iovcnt, offset)
241251
}
242252
}
243253
}
@@ -256,18 +266,28 @@ mod readwrite_pv64 {
256266
} else {
257267
#[cfg(target_pointer_width = "32")]
258268
{
259-
libc::syscall(
260-
libc::SYS_pwritev,
261-
fd,
262-
iov,
263-
iovcnt,
264-
hi(offset as u64),
265-
lo(offset as u64),
266-
) as libc::ssize_t
269+
syscall! {
270+
fn pwritev(
271+
fd: libc::c_int,
272+
iov: *const libc::iovec,
273+
iovcnt: libc::c_int,
274+
offset_hi: usize,
275+
offset_lo: usize
276+
) via SYS_pwritev -> libc::ssize_t
277+
}
278+
pwritev(fd, iov, iovcnt, hi(offset), lo(offset))
267279
}
268280
#[cfg(target_pointer_width = "64")]
269281
{
270-
libc::syscall(libc::SYS_pwritev, fd, iov, iovcnt, offset) as libc::ssize_t
282+
syscall! {
283+
fn pwritev(
284+
fd: libc::c_int,
285+
iov: *const libc::iovec,
286+
iovcnt: libc::c_int,
287+
offset: libc::off_t
288+
) via SYS_pwritev -> libc::ssize_t
289+
}
290+
pwritev(fd, iov, iovcnt, offset)
271291
}
272292
}
273293
}
@@ -303,19 +323,19 @@ mod readwrite_pv64v2 {
303323
// 64-bit offsets on 32-bit platforms are passed in endianness-specific
304324
// lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
305325
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
306-
fn lo(x: u64) -> usize {
326+
fn lo(x: i64) -> usize {
307327
(x >> 32) as usize
308328
}
309329
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
310-
fn hi(x: u64) -> usize {
311-
(x & 0xffff_ffff) as usize
330+
fn hi(x: i64) -> usize {
331+
x as usize
312332
}
313333
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
314-
fn lo(x: u64) -> usize {
315-
(x & 0xffff_ffff) as usize
334+
fn lo(x: i64) -> usize {
335+
x as usize
316336
}
317337
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
318-
fn hi(x: u64) -> usize {
338+
fn hi(x: i64) -> usize {
319339
(x >> 32) as usize
320340
}
321341

@@ -338,19 +358,30 @@ mod readwrite_pv64v2 {
338358
} else {
339359
#[cfg(target_pointer_width = "32")]
340360
{
341-
libc::syscall(
342-
libc::SYS_preadv2,
343-
fd,
344-
iov,
345-
iovcnt,
346-
hi(offset as u64),
347-
lo(offset as u64),
348-
flags,
349-
) as libc::ssize_t
361+
syscall! {
362+
fn preadv2(
363+
fd: libc::c_int,
364+
iov: *const libc::iovec,
365+
iovcnt: libc::c_int,
366+
offset_hi: usize,
367+
offset_lo: usize,
368+
flags: libc::c_int
369+
) via SYS_preadv2 -> libc::ssize_t
370+
}
371+
preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
350372
}
351373
#[cfg(target_pointer_width = "64")]
352374
{
353-
libc::syscall(libc::SYS_preadv2, fd, iov, iovcnt, offset, flags) as libc::ssize_t
375+
syscall! {
376+
fn preadv2(
377+
fd: libc::c_int,
378+
iov: *const libc::iovec,
379+
iovcnt: libc::c_int,
380+
offset: libc::off_t,
381+
flags: libc::c_int
382+
) via SYS_preadv2 -> libc::ssize_t
383+
}
384+
preadv2(fd, iov, iovcnt, offset, flags)
354385
}
355386
}
356387
}
@@ -370,22 +401,136 @@ mod readwrite_pv64v2 {
370401
} else {
371402
#[cfg(target_pointer_width = "32")]
372403
{
373-
libc::syscall(
374-
libc::SYS_pwritev,
375-
fd,
376-
iov,
377-
iovcnt,
378-
hi(offset as u64),
379-
lo(offset as u64),
380-
flags,
381-
) as libc::ssize_t
404+
syscall! {
405+
fn pwritev2(
406+
fd: libc::c_int,
407+
iov: *const libc::iovec,
408+
iovec: libc::c_int,
409+
offset_hi: usize,
410+
offset_lo: usize,
411+
flags: libc::c_int
412+
) via SYS_pwritev2 -> libc::ssize_t
413+
}
414+
pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
382415
}
383416
#[cfg(target_pointer_width = "64")]
384417
{
385-
libc::syscall(libc::SYS_pwritev2, fd, iov, iovcnt, offset, flags) as libc::ssize_t
418+
syscall! {
419+
fn pwritev2(
420+
fd: libc::c_int,
421+
iov:*const libc::iovec,
422+
iovcnt: libc::c_int,
423+
offset: libc::off_t,
424+
flags: libc::c_int
425+
) via SYS_pwritev2 -> libc::ssize_t
426+
}
427+
pwritev2(fd, iov, iovcnt, offset, flags)
386428
}
387429
}
388430
}
389431
}
390432
#[cfg(all(target_os = "linux", target_env = "gnu"))]
391433
pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};
434+
435+
// On non-glibc, assume we don't have `pwritev2`/`preadv2` in libc and use
436+
// `c::syscall` instead.
437+
#[cfg(any(
438+
target_os = "android",
439+
all(target_os = "linux", not(target_env = "gnu")),
440+
))]
441+
mod readwrite_pv64v2 {
442+
// 64-bit offsets on 32-bit platforms are passed in endianness-specific
443+
// lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
444+
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
445+
fn lo(x: i64) -> usize {
446+
(x >> 32) as usize
447+
}
448+
#[cfg(all(target_endian = "little", target_pointer_width = "32"))]
449+
fn hi(x: i64) -> usize {
450+
x as usize
451+
}
452+
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
453+
fn lo(x: i64) -> usize {
454+
x as usize
455+
}
456+
#[cfg(all(target_endian = "big", target_pointer_width = "32"))]
457+
fn hi(x: i64) -> usize {
458+
(x >> 32) as usize
459+
}
460+
461+
pub(in super::super) unsafe fn preadv64v2(
462+
fd: libc::c_int,
463+
iov: *const libc::iovec,
464+
iovcnt: libc::c_int,
465+
offset: libc::off64_t,
466+
flags: libc::c_int,
467+
) -> libc::ssize_t {
468+
#[cfg(target_pointer_width = "32")]
469+
{
470+
syscall! {
471+
fn preadv2(
472+
fd: libc::c_int,
473+
iov: *const libc::iovec,
474+
iovcnt: libc::c_int,
475+
offset_hi: usize,
476+
offset_lo: usize,
477+
flags: libc::c_int
478+
) via SYS_preadv2 -> libc::ssize_t
479+
}
480+
preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
481+
}
482+
#[cfg(target_pointer_width = "64")]
483+
{
484+
syscall! {
485+
fn preadv2(
486+
fd: libc::c_int,
487+
iov: *const libc::iovec,
488+
iovcnt: libc::c_int,
489+
offset: libc::off_t,
490+
flags: libc::c_int
491+
) via SYS_preadv2 -> libc::ssize_t
492+
}
493+
preadv2(fd, iov, iovcnt, offset, flags)
494+
}
495+
}
496+
pub(in super::super) unsafe fn pwritev64v2(
497+
fd: libc::c_int,
498+
iov: *const libc::iovec,
499+
iovcnt: libc::c_int,
500+
offset: libc::off64_t,
501+
flags: libc::c_int,
502+
) -> libc::ssize_t {
503+
#[cfg(target_pointer_width = "32")]
504+
{
505+
syscall! {
506+
fn pwritev2(
507+
fd: libc::c_int,
508+
iov: *const libc::iovec,
509+
iovcnt: libc::c_int,
510+
offset_hi: usize,
511+
offset_lo: usize,
512+
flags: libc::c_int
513+
) via SYS_pwritev2 -> libc::ssize_t
514+
}
515+
pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
516+
}
517+
#[cfg(target_pointer_width = "64")]
518+
{
519+
syscall! {
520+
fn pwritev2(
521+
fd: libc::c_int,
522+
iov:*const libc::iovec,
523+
iovcnt: libc::c_int,
524+
offset: libc::off_t,
525+
flags: libc::c_int
526+
) via SYS_pwritev2 -> libc::ssize_t
527+
}
528+
pwritev2(fd, iov, iovcnt, offset, flags)
529+
}
530+
}
531+
}
532+
#[cfg(any(
533+
target_os = "android",
534+
all(target_os = "linux", not(target_env = "gnu")),
535+
))]
536+
pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};

src/backend/libc/conv.rs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,6 @@ pub(super) fn ret(raw: c::c_int) -> io::Result<()> {
4141
}
4242
}
4343

44-
#[inline]
45-
pub(super) fn syscall_ret(raw: c::c_long) -> io::Result<()> {
46-
if raw == 0 {
47-
Ok(())
48-
} else {
49-
Err(io::Errno::last_os_error())
50-
}
51-
}
52-
5344
#[inline]
5445
pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> {
5546
if raw >= 0 {
@@ -92,31 +83,6 @@ pub(super) fn ret_usize(raw: c::ssize_t) -> io::Result<usize> {
9283
}
9384
}
9485

95-
#[inline]
96-
pub(super) fn syscall_ret_usize(raw: c::c_long) -> io::Result<usize> {
97-
if raw == -1 {
98-
Err(io::Errno::last_os_error())
99-
} else {
100-
debug_assert!(raw >= 0);
101-
Ok(raw as c::ssize_t as usize)
102-
}
103-
}
104-
105-
#[cfg(linux_kernel)]
106-
#[inline]
107-
pub(super) fn syscall_ret_u32(raw: c::c_long) -> io::Result<u32> {
108-
if raw == -1 {
109-
Err(io::Errno::last_os_error())
110-
} else {
111-
let r32 = raw as u32;
112-
113-
// Converting `raw` to `u32` should be lossless.
114-
debug_assert_eq!(r32 as c::c_long, raw);
115-
116-
Ok(r32)
117-
}
118-
}
119-
12086
#[cfg(not(windows))]
12187
#[cfg(feature = "fs")]
12288
#[inline]
@@ -171,22 +137,6 @@ pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> {
171137
}
172138
}
173139

174-
/// Convert a `c_long` returned from `syscall` to an `OwnedFd`, if valid.
175-
///
176-
/// # Safety
177-
///
178-
/// The caller must ensure that this is the return value of a `syscall` call
179-
/// which returns an owned file descriptor.
180-
#[cfg(not(windows))]
181-
#[inline]
182-
pub(super) unsafe fn syscall_ret_owned_fd(raw: c::c_long) -> io::Result<OwnedFd> {
183-
if raw == -1 {
184-
Err(io::Errno::last_os_error())
185-
} else {
186-
Ok(OwnedFd::from_raw_fd(raw as RawFd))
187-
}
188-
}
189-
190140
/// Convert the buffer-length argument value of a `send` or `recv` call.
191141
#[cfg(not(windows))]
192142
#[inline]

0 commit comments

Comments
 (0)