1#[cfg(feature = "user")]
4pub(crate) fn cstr_to_rust(c: *const libc::c_char) -> Option<String> {
5 cstr_to_rust_with_size(c, None)
6}
7
8#[cfg(any(feature = "disk", feature = "system", feature = "user"))]
9#[allow(dead_code)]
10pub(crate) fn cstr_to_rust_with_size(
11 c: *const libc::c_char,
12 size: Option<usize>,
13) -> Option<String> {
14 if c.is_null() {
15 return None;
16 }
17 let (mut s, max) = match size {
18 Some(len) => (Vec::with_capacity(len), len as isize),
19 None => (Vec::new(), isize::MAX),
20 };
21 let mut i = 0;
22 unsafe {
23 loop {
24 let value = *c.offset(i) as u8;
25 if value == 0 {
26 break;
27 }
28 s.push(value);
29 i += 1;
30 if i >= max {
31 break;
32 }
33 }
34 String::from_utf8(s).ok()
35 }
36}
37
38#[cfg(all(
39 feature = "system",
40 not(any(
41 target_os = "ios",
42 all(target_os = "macos", feature = "apple-sandbox",)
43 ))
44))]
45pub(crate) fn wait_process(pid: crate::Pid) -> Option<std::process::ExitStatus> {
46 use std::os::unix::process::ExitStatusExt;
47
48 let mut status = 0;
49 unsafe {
51 if retry_eintr!(libc::waitpid(pid.0, &mut status, 0)) < 0 {
52 let duration = std::time::Duration::from_millis(10);
54 while libc::kill(pid.0, 0) == 0 {
55 std::thread::sleep(duration);
56 }
57 }
58 Some(std::process::ExitStatus::from_raw(status))
59 }
60}