Skip to main content

rustix/backend/libc/system/
syscalls.rs

1//! libc syscalls supporting `rustix::process`.
2
3use super::types::RawUname;
4use crate::backend::c;
5#[cfg(not(target_os = "wasi"))]
6use crate::backend::conv::ret_infallible;
7#[cfg(target_os = "linux")]
8use crate::system::RebootCommand;
9use core::mem::MaybeUninit;
10#[cfg(linux_kernel)]
11use {
12    crate::backend::conv::c_str, crate::fd::BorrowedFd, crate::ffi::CStr, crate::system::Sysinfo,
13};
14#[cfg(not(any(
15    target_os = "emscripten",
16    target_os = "espidf",
17    target_os = "horizon",
18    target_os = "redox",
19    target_os = "vita",
20    target_os = "wasi"
21)))]
22use {crate::backend::conv::ret, crate::io};
23
24#[cfg(not(target_os = "wasi"))]
25#[inline]
26pub(crate) fn uname() -> RawUname {
27    let mut uname = MaybeUninit::<RawUname>::uninit();
28    unsafe {
29        let r = c::uname(uname.as_mut_ptr());
30
31        // On POSIX, `uname` is documented to return non-negative on success
32        // instead of the usual 0, though some specific systems do document
33        // that they always use zero allowing us to skip this check.
34        #[cfg(not(any(apple, freebsdlike, linux_like, target_os = "netbsd")))]
35        let r = core::cmp::min(r, 0);
36
37        ret_infallible(r);
38        uname.assume_init()
39    }
40}
41
42#[cfg(linux_kernel)]
43pub(crate) fn sysinfo() -> Sysinfo {
44    let mut info = MaybeUninit::<Sysinfo>::uninit();
45    unsafe {
46        ret_infallible(c::sysinfo(info.as_mut_ptr()));
47        info.assume_init()
48    }
49}
50
51#[cfg(not(any(
52    target_os = "emscripten",
53    target_os = "espidf",
54    target_os = "horizon",
55    target_os = "redox",
56    target_os = "vita",
57    target_os = "wasi"
58)))]
59pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> {
60    unsafe {
61        ret(c::sethostname(
62            name.as_ptr().cast(),
63            name.len().try_into().map_err(|_| io::Errno::INVAL)?,
64        ))
65    }
66}
67
68#[cfg(not(any(
69    target_os = "android",
70    target_os = "cygwin",
71    target_os = "emscripten",
72    target_os = "espidf",
73    target_os = "illumos",
74    target_os = "haiku",
75    target_os = "horizon",
76    target_os = "redox",
77    target_os = "solaris",
78    target_os = "vita",
79    target_os = "wasi",
80)))]
81pub(crate) fn setdomainname(name: &[u8]) -> io::Result<()> {
82    unsafe {
83        ret(c::setdomainname(
84            name.as_ptr().cast(),
85            name.len().try_into().map_err(|_| io::Errno::INVAL)?,
86        ))
87    }
88}
89
90// <https://github.com/rust-lang/libc/pull/4212>
91#[cfg(target_os = "android")]
92pub(crate) fn setdomainname(name: &[u8]) -> io::Result<()> {
93    syscall! {
94        fn setdomainname(
95            name: *const c::c_char,
96            len: c::size_t
97        ) via SYS_setdomainname -> c::c_int
98    }
99
100    unsafe {
101        ret(setdomainname(
102            name.as_ptr().cast(),
103            name.len().try_into().map_err(|_| io::Errno::INVAL)?,
104        ))
105    }
106}
107
108#[cfg(target_os = "linux")]
109pub(crate) fn reboot(cmd: RebootCommand) -> io::Result<()> {
110    unsafe { ret(c::reboot(cmd as i32)) }
111}
112
113#[cfg(linux_kernel)]
114#[inline]
115pub(crate) fn init_module(image: &[u8], param_values: &CStr) -> io::Result<()> {
116    syscall! {
117        fn init_module(
118            module_image: *const c::c_void,
119            len: c::c_ulong,
120            param_values: *const c::c_char
121        ) via SYS_init_module -> c::c_int
122    }
123
124    unsafe {
125        ret(init_module(
126            image.as_ptr().cast(),
127            image.len() as _,
128            c_str(param_values),
129        ))
130    }
131}
132
133#[cfg(linux_kernel)]
134#[inline]
135pub(crate) fn finit_module(
136    fd: BorrowedFd<'_>,
137    param_values: &CStr,
138    flags: c::c_int,
139) -> io::Result<()> {
140    use crate::fd::AsRawFd as _;
141
142    syscall! {
143        fn finit_module(
144            fd: c::c_int,
145            param_values: *const c::c_char,
146            flags: c::c_int
147        ) via SYS_finit_module -> c::c_int
148    }
149
150    unsafe { ret(finit_module(fd.as_raw_fd(), c_str(param_values), flags)) }
151}
152
153#[cfg(linux_kernel)]
154#[inline]
155pub(crate) fn delete_module(name: &CStr, flags: c::c_int) -> io::Result<()> {
156    syscall! {
157        fn delete_module(
158            name: *const c::c_char,
159            flags: c::c_int
160        ) via SYS_delete_module -> c::c_int
161    }
162    unsafe { ret(delete_module(c_str(name), flags)) }
163}