1#![deny(unsafe_code)]
2
3pub mod android;
4#[cfg(target_os = "macos")]
5pub mod apple;
6pub mod bicycle;
7pub mod config;
8pub mod device;
9pub mod doctor;
10pub mod dot_cargo;
11pub mod env;
12pub mod init;
13pub mod opts;
14pub mod os;
15mod project;
16pub mod reserved_names;
17pub mod target;
18mod templating;
19pub mod update;
20pub mod util;
21use std::ffi::OsStr;
22
23pub use duct::Handle as ChildHandle;
24
25pub static NAME: &str = "mobile";
26
27trait DuctExpressionExt {
28 fn vars(self, vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>) -> Self;
29 fn run_and_detach(&self) -> Result<(), std::io::Error>;
30 fn dup_stdio(&self) -> Self;
33}
34
35impl DuctExpressionExt for duct::Expression {
36 fn vars(
37 mut self,
38 vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>,
39 ) -> Self {
40 for (k, v) in vars {
41 self = self.env(&k, &v);
42 }
43 self
44 }
45
46 fn run_and_detach(&self) -> Result<(), std::io::Error> {
47 self.before_spawn(|cmd| {
48 #[cfg(unix)]
51 #[allow(unsafe_code)]
52 unsafe {
53 use std::os::unix::process::CommandExt as _;
54
55 let display = format!("{cmd:?}");
56 cmd.pre_exec(move || match libc::fork() {
57 -1 => {
58 let err = std::io::Error::last_os_error();
59 log::error!("`fork` failed for command {:?}: {}", display, err);
60 Err(err)
61 }
62 0 => {
63 if libc::setsid() == -1 {
64 let err = std::io::Error::last_os_error();
65 log::error!("`setsid` failed for command {:?}: {}", display, err);
66 Err(err)
67 } else {
68 Ok(())
69 }
70 }
71 _ => libc::_exit(0),
72 });
73 }
74 #[cfg(windows)]
75 {
76 use std::os::windows::process::CommandExt;
77 const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
78 const CREATE_NO_WINDOW: u32 = 0x08000000;
79 cmd.creation_flags(CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW);
80 }
81
82 Ok(())
83 })
84 .stdin_null()
85 .stdout_null()
86 .stderr_null()
87 .start()?;
88 Ok(())
89 }
90
91 fn dup_stdio(&self) -> Self {
92 self.stdin_file(os_pipe::dup_stdin().unwrap())
93 .stdout_file(os_pipe::dup_stdout().unwrap())
94 .stderr_file(os_pipe::dup_stderr().unwrap())
95 }
96}