c_scape/process/
system.rs1use crate::convert_res;
2use core::ptr::{addr_of_mut, copy_nonoverlapping};
3use core::slice;
4use errno::{set_errno, Errno};
5use libc::{c_char, c_double, c_int, c_long};
6use memoffset::span_of;
7
8#[no_mangle]
9unsafe extern "C" fn uname(buf: *mut libc::utsname) -> c_int {
10 libc!(libc::uname(buf));
11
12 let uname = rustix::system::uname();
13
14 let sysname = uname.sysname().to_bytes_with_nul();
15 assert!(sysname.len() <= span_of!(libc::utsname, sysname).len());
16 copy_nonoverlapping(
17 sysname.as_ptr(),
18 addr_of_mut!((*buf).sysname).cast::<u8>(),
19 sysname.len(),
20 );
21
22 let nodename = uname.nodename().to_bytes_with_nul();
23 assert!(nodename.len() <= span_of!(libc::utsname, nodename).len());
24 copy_nonoverlapping(
25 nodename.as_ptr(),
26 addr_of_mut!((*buf).nodename).cast::<u8>(),
27 nodename.len(),
28 );
29
30 let release = uname.release().to_bytes_with_nul();
31 assert!(release.len() <= span_of!(libc::utsname, release).len());
32 copy_nonoverlapping(
33 release.as_ptr(),
34 addr_of_mut!((*buf).release).cast::<u8>(),
35 release.len(),
36 );
37
38 let version = uname.version().to_bytes_with_nul();
39 assert!(version.len() <= span_of!(libc::utsname, version).len());
40 copy_nonoverlapping(
41 version.as_ptr(),
42 addr_of_mut!((*buf).version).cast::<u8>(),
43 version.len(),
44 );
45
46 let machine = uname.machine().to_bytes_with_nul();
47 assert!(machine.len() <= span_of!(libc::utsname, machine).len());
48 copy_nonoverlapping(
49 machine.as_ptr(),
50 addr_of_mut!((*buf).machine).cast::<u8>(),
51 machine.len(),
52 );
53
54 let domainname = uname.domainname().to_bytes_with_nul();
55 assert!(domainname.len() <= span_of!(libc::utsname, domainname).len());
56 copy_nonoverlapping(
57 domainname.as_ptr(),
58 addr_of_mut!((*buf).domainname).cast::<u8>(),
59 domainname.len(),
60 );
61
62 0
63}
64
65#[no_mangle]
66unsafe extern "C" fn getloadavg(a: *mut c_double, n: c_int) -> c_int {
67 libc!(libc::getloadavg(a, n));
68
69 if n == 0 {
70 return 0;
71 }
72 if n < 0 {
73 return -1;
74 }
75
76 let info = rustix::system::sysinfo();
77 let mut a = a;
78
79 for i in 0..core::cmp::min(n as usize, info.loads.len()) {
80 a.write((info.loads[i] as f64) / ((1 << libc::SI_LOAD_SHIFT) as f64));
81 a = a.add(1);
82 }
83
84 n
85}
86
87#[cfg(not(target_os = "wasi"))]
88#[no_mangle]
89unsafe extern "C" fn gethostname(name: *mut c_char, len: usize) -> c_int {
90 libc!(libc::gethostname(name, len));
91
92 let uname = rustix::system::uname();
93 let nodename = uname.nodename();
94 if nodename.to_bytes().len() + 1 > len {
95 set_errno(Errno(libc::ENAMETOOLONG));
96 return -1;
97 }
98 copy_nonoverlapping(
99 nodename.to_bytes().as_ptr().cast::<u8>(),
100 name.cast::<u8>(),
101 nodename.to_bytes().len(),
102 );
103 *name.add(nodename.to_bytes().len()) = 0;
104 0
105}
106
107#[cfg(not(target_os = "wasi"))]
108#[no_mangle]
109unsafe extern "C" fn sethostname(name: *mut c_char, len: usize) -> c_int {
110 libc!(libc::sethostname(name, len));
111
112 let slice = slice::from_raw_parts(name.cast(), len);
113 match convert_res(rustix::system::sethostname(slice)) {
114 Some(()) => 0,
115 None => -1,
116 }
117}
118
119#[deprecated]
120#[no_mangle]
121unsafe extern "C" fn gethostid() -> c_long {
122 libc!(libc::gethostid());
123
124 0
126}
127
128#[cfg(not(target_env = "musl"))]
129#[deprecated]
130#[no_mangle]
131unsafe extern "C" fn sethostid(id: c_long) -> c_int {
132 libc!(libc::sethostid(id));
133
134 if id == 0 {
135 0
136 } else {
137 set_errno(Errno(libc::EACCES));
138 -1
139 }
140}