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