1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 #[cfg(not(windows))]
4 use std::boxed::Box as Box_;
5 #[cfg(not(windows))]
6 use std::mem;
7 #[cfg(not(windows))]
8 #[cfg(any(feature = "v2_58", feature = "dox"))]
9 use std::os::unix::io::AsRawFd;
10 #[cfg(not(windows))]
11 use std::os::unix::io::{FromRawFd, RawFd};
12 // #[cfg(windows)]
13 // #[cfg(any(feature = "v2_58", feature = "dox"))]
14 // use std::os::windows::io::AsRawHandle;
15 use crate::translate::*;
16 #[cfg(not(windows))]
17 use crate::Error;
18 use crate::GString;
19 #[cfg(not(windows))]
20 use crate::Pid;
21 #[cfg(not(windows))]
22 use crate::SpawnFlags;
23 use std::ptr;
24
25 #[cfg(any(feature = "v2_58", feature = "dox"))]
26 #[cfg(not(windows))]
27 #[cfg_attr(feature = "dox", doc(cfg(all(feature = "v2_58", not(windows)))))]
28 #[allow(clippy::too_many_arguments)]
29 #[doc(alias = "g_spawn_async_with_fds")]
spawn_async_with_fds<P: AsRef<std::path::Path>, T: AsRawFd, U: AsRawFd, V: AsRawFd>( working_directory: P, argv: &[&str], envp: &[&str], flags: SpawnFlags, child_setup: Option<Box_<dyn FnOnce() + 'static>>, stdin_fd: T, stdout_fd: U, stderr_fd: V, ) -> Result<Pid, Error>30 pub fn spawn_async_with_fds<P: AsRef<std::path::Path>, T: AsRawFd, U: AsRawFd, V: AsRawFd>(
31 working_directory: P,
32 argv: &[&str],
33 envp: &[&str],
34 flags: SpawnFlags,
35 child_setup: Option<Box_<dyn FnOnce() + 'static>>,
36 stdin_fd: T,
37 stdout_fd: U,
38 stderr_fd: V,
39 ) -> Result<Pid, Error> {
40 let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
41 unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(user_data: ffi::gpointer) {
42 let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
43 Box_::from_raw(user_data as *mut _);
44 let callback = (*callback).expect("cannot get closure...");
45 callback()
46 }
47 let child_setup = if child_setup_data.is_some() {
48 Some(child_setup_func::<P> as _)
49 } else {
50 None
51 };
52 let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
53 unsafe {
54 let mut child_pid = mem::MaybeUninit::uninit();
55 let mut error = ptr::null_mut();
56 let _ = ffi::g_spawn_async_with_fds(
57 working_directory.as_ref().to_glib_none().0,
58 argv.to_glib_none().0,
59 envp.to_glib_none().0,
60 flags.into_glib(),
61 child_setup,
62 Box_::into_raw(super_callback0) as *mut _,
63 child_pid.as_mut_ptr(),
64 stdin_fd.as_raw_fd(),
65 stdout_fd.as_raw_fd(),
66 stderr_fd.as_raw_fd(),
67 &mut error,
68 );
69 let child_pid = from_glib(child_pid.assume_init());
70 if error.is_null() {
71 Ok(child_pid)
72 } else {
73 Err(from_glib_full(error))
74 }
75 }
76 }
77
78 // #[cfg(any(feature = "v2_58", feature = "dox"))]
79 // #[cfg(windows)]
80 // pub fn spawn_async_with_fds<
81 // P: AsRef<std::path::Path>,
82 // T: AsRawHandle,
83 // U: AsRawHandle,
84 // V: AsRawHandle,
85 // >(
86 // working_directory: P,
87 // argv: &[&str],
88 // envp: &[&str],
89 // flags: SpawnFlags,
90 // child_setup: Option<Box_<dyn FnOnce() + 'static>>,
91 // stdin_fd: T,
92 // stdout_fd: U,
93 // stderr_fd: V,
94 // ) -> Result<Pid, Error> {
95 // let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
96 // unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(
97 // user_data: ffi::gpointer,
98 // ) {
99 // let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
100 // Box_::from_raw(user_data as *mut _);
101 // let callback = (*callback).expect("cannot get closure...");
102 // callback()
103 // }
104 // let child_setup = if child_setup_data.is_some() {
105 // Some(child_setup_func::<P> as _)
106 // } else {
107 // None
108 // };
109 // let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
110 // unsafe {
111 // let mut child_pid = mem::MaybeUninit::uninit();
112 // let mut error = ptr::null_mut();
113 // let _ = ffi::g_spawn_async_with_fds(
114 // working_directory.as_ref().to_glib_none().0,
115 // argv.to_glib_none().0,
116 // envp.to_glib_none().0,
117 // flags.into_glib(),
118 // child_setup,
119 // Box_::into_raw(super_callback0) as *mut _,
120 // child_pid.as_mut_ptr(),
121 // stdin_fd.as_raw_handle() as usize as _,
122 // stdout_fd.as_raw_handle() as usize as _,
123 // stderr_fd.as_raw_handle() as usize as _,
124 // &mut error,
125 // );
126 // let child_pid = from_glib(child_pid.assume_init());
127 // if error.is_null() {
128 // Ok(child_pid)
129 // } else {
130 // Err(from_glib_full(error))
131 // }
132 // }
133 // }
134
135 #[cfg(not(windows))]
136 #[cfg_attr(feature = "dox", doc(cfg(not(windows))))]
137 #[doc(alias = "g_spawn_async_with_pipes")]
spawn_async_with_pipes< P: AsRef<std::path::Path>, T: FromRawFd, U: FromRawFd, V: FromRawFd, >( working_directory: P, argv: &[&std::path::Path], envp: &[&std::path::Path], flags: SpawnFlags, child_setup: Option<Box_<dyn FnOnce() + 'static>>, ) -> Result<(Pid, T, U, V), Error>138 pub fn spawn_async_with_pipes<
139 P: AsRef<std::path::Path>,
140 T: FromRawFd,
141 U: FromRawFd,
142 V: FromRawFd,
143 >(
144 working_directory: P,
145 argv: &[&std::path::Path],
146 envp: &[&std::path::Path],
147 flags: SpawnFlags,
148 child_setup: Option<Box_<dyn FnOnce() + 'static>>,
149 ) -> Result<(Pid, T, U, V), Error> {
150 let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
151 unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(user_data: ffi::gpointer) {
152 let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
153 Box_::from_raw(user_data as *mut _);
154 let callback = (*callback).expect("cannot get closure...");
155 callback()
156 }
157 let child_setup = if child_setup_data.is_some() {
158 Some(child_setup_func::<P> as _)
159 } else {
160 None
161 };
162 let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
163 unsafe {
164 let mut child_pid = mem::MaybeUninit::uninit();
165 let mut standard_input = mem::MaybeUninit::uninit();
166 let mut standard_output = mem::MaybeUninit::uninit();
167 let mut standard_error = mem::MaybeUninit::uninit();
168 let mut error = ptr::null_mut();
169 let _ = ffi::g_spawn_async_with_pipes(
170 working_directory.as_ref().to_glib_none().0,
171 argv.to_glib_none().0,
172 envp.to_glib_none().0,
173 flags.into_glib(),
174 child_setup,
175 Box_::into_raw(super_callback0) as *mut _,
176 child_pid.as_mut_ptr(),
177 standard_input.as_mut_ptr(),
178 standard_output.as_mut_ptr(),
179 standard_error.as_mut_ptr(),
180 &mut error,
181 );
182 let child_pid = from_glib(child_pid.assume_init());
183 let standard_input = standard_input.assume_init();
184 let standard_output = standard_output.assume_init();
185 let standard_error = standard_error.assume_init();
186 if error.is_null() {
187 #[cfg(not(windows))]
188 {
189 Ok((
190 child_pid,
191 FromRawFd::from_raw_fd(standard_input),
192 FromRawFd::from_raw_fd(standard_output),
193 FromRawFd::from_raw_fd(standard_error),
194 ))
195 }
196 // #[cfg(windows)]
197 // {
198 // use std::os::windows::io::{FromRawHandle, RawHandle};
199 // Ok((
200 // child_pid,
201 // File::from_raw_handle(standard_input as usize as RawHandle),
202 // File::from_raw_handle(standard_output as usize as RawHandle),
203 // File::from_raw_handle(standard_error as usize as RawHandle),
204 // ))
205 // }
206 } else {
207 Err(from_glib_full(error))
208 }
209 }
210 }
211
212 /// Obtain the character set for the current locale.
213 ///
214 /// This returns whether the locale's encoding is UTF-8, and the current
215 /// charset if available.
216 #[doc(alias = "g_get_charset")]
217 #[doc(alias = "get_charset")]
charset() -> (bool, Option<GString>)218 pub fn charset() -> (bool, Option<GString>) {
219 unsafe {
220 let mut out_charset = ptr::null();
221 let is_utf8 = from_glib(ffi::g_get_charset(&mut out_charset));
222 let charset = from_glib_none(out_charset);
223 (is_utf8, charset)
224 }
225 }
226
227 #[cfg(unix)]
228 #[doc(alias = "g_unix_open_pipe")]
unix_open_pipe(flags: i32) -> Result<(RawFd, RawFd), Error>229 pub fn unix_open_pipe(flags: i32) -> Result<(RawFd, RawFd), Error> {
230 unsafe {
231 let mut fds = [0, 2];
232 let mut error = ptr::null_mut();
233 let _ = ffi::g_unix_open_pipe(fds.as_mut_ptr(), flags, &mut error);
234 if error.is_null() {
235 Ok((
236 FromRawFd::from_raw_fd(fds[0]),
237 FromRawFd::from_raw_fd(fds[1]),
238 ))
239 } else {
240 Err(from_glib_full(error))
241 }
242 }
243 }
244