coreshift_core/
process.rs1use crate::CoreError;
11use crate::error::syscall_ret;
12
13pub enum ForkResult {
15 Parent(i32),
17 Child,
19}
20
21pub unsafe fn fork() -> Result<ForkResult, CoreError> {
28 let pid = unsafe { libc::fork() };
29 if pid < 0 {
30 return Err(CoreError::sys(
31 std::io::Error::last_os_error().raw_os_error().unwrap_or(-1),
32 "fork",
33 ));
34 }
35 if pid == 0 {
36 Ok(ForkResult::Child)
37 } else {
38 Ok(ForkResult::Parent(pid))
39 }
40}
41
42pub fn setsid() -> Result<(), CoreError> {
44 let ret = unsafe { libc::setsid() };
45 if ret < 0 {
46 return Err(CoreError::sys(
47 std::io::Error::last_os_error().raw_os_error().unwrap_or(-1),
48 "setsid",
49 ));
50 }
51 Ok(())
52}
53
54pub fn setpgid(pid: i32, pgid: i32) -> Result<(), CoreError> {
56 syscall_ret(unsafe { libc::setpgid(pid, pgid) }, "setpgid")
57}
58
59pub unsafe fn redirect_stdio_to_devnull() -> Result<(), CoreError> {
64 let fd = unsafe {
65 libc::open(c"/dev/null".as_ptr(), libc::O_RDWR)
66 };
67 if fd < 0 {
68 return Err(CoreError::sys(
69 std::io::Error::last_os_error().raw_os_error().unwrap_or(-1),
70 "open:/dev/null",
71 ));
72 }
73 unsafe {
74 libc::dup2(fd, 0);
75 libc::dup2(fd, 1);
76 libc::dup2(fd, 2);
77 if fd > 2 { libc::close(fd); }
78 }
79 Ok(())
80}
81
82pub fn set_pdeathsig(sig: i32) -> Result<(), CoreError> {
84 syscall_ret(
85 unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, sig as libc::c_ulong, 0, 0, 0) },
86 "prctl:PR_SET_PDEATHSIG",
87 )
88}
89
90pub unsafe fn redirect_fd_to(src_fd: i32, dst_fd: i32) {
97 unsafe {
98 libc::dup2(src_fd, dst_fd);
99 libc::close(src_fd);
100 }
101}
102
103pub fn getuid() -> u32 { unsafe { libc::getuid() } }
104pub fn getgid() -> u32 { unsafe { libc::getgid() } }
105
106pub fn setuid(uid: u32) -> Result<(), CoreError> {
110 syscall_ret(
111 unsafe { libc::setresuid(uid, uid, uid) },
112 "setresuid",
113 )
114}
115
116pub fn setgid(gid: u32) -> Result<(), CoreError> {
120 syscall_ret(
121 unsafe { libc::setresgid(gid, gid, gid) },
122 "setresgid",
123 )
124}
125
126pub fn close_fds_from(start: i32) {
131 if let Ok(entries) = std::fs::read_dir("/proc/self/fd") {
132 let fds: Vec<i32> = entries
133 .filter_map(|e| e.ok())
134 .filter_map(|e| e.file_name().to_str()?.parse::<i32>().ok())
135 .filter(|&fd| fd >= start)
136 .collect();
137 for fd in fds {
139 unsafe { libc::close(fd) };
140 }
141 } else {
142 for fd in start..1024 {
143 unsafe { libc::close(fd) };
144 }
145 }
146}