1pub use crate::auto::functions::*;
4#[cfg(not(windows))]
5use std::boxed::Box as Box_;
6#[cfg(not(windows))]
7use std::mem;
8#[cfg(not(windows))]
9#[cfg(feature = "v2_58")]
10use std::os::unix::io::{AsFd, AsRawFd};
11#[cfg(not(windows))]
12use std::os::unix::io::{FromRawFd, OwnedFd};
13use std::ptr;
14
15use crate::{ChecksumType, GStr, ffi, translate::*};
19#[cfg(not(windows))]
20use crate::{Error, Pid, SpawnFlags};
21
22#[cfg(feature = "v2_58")]
23#[cfg(not(windows))]
24#[cfg_attr(docsrs, doc(cfg(all(feature = "v2_58", not(windows)))))]
25#[allow(clippy::too_many_arguments)]
26#[doc(alias = "g_spawn_async_with_fds")]
27pub fn spawn_async_with_fds<P: AsRef<std::path::Path>>(
28 working_directory: P,
29 argv: &[&str],
30 envp: &[&str],
31 flags: SpawnFlags,
32 child_setup: Option<Box_<dyn FnOnce() + 'static>>,
33 stdin_fd: Option<impl AsFd>,
34 stdout_fd: Option<impl AsFd>,
35 stderr_fd: Option<impl AsFd>,
36) -> Result<Pid, Error> {
37 let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
38 unsafe extern "C" fn child_setup_func(user_data: ffi::gpointer) {
39 unsafe {
40 let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
41 Box_::from_raw(user_data as *mut _);
42 let callback = (*callback).expect("cannot get closure...");
43 callback()
44 }
45 }
46 let child_setup = if child_setup_data.is_some() {
47 Some(child_setup_func as _)
48 } else {
49 None
50 };
51 let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
52 let stdin_raw_fd = stdin_fd.map_or(-1, |fd| fd.as_fd().as_raw_fd());
53 let stdout_raw_fd = stdout_fd.map_or(-1, |fd| fd.as_fd().as_raw_fd());
54 let stderr_raw_fd = stderr_fd.map_or(-1, |fd| fd.as_fd().as_raw_fd());
55 unsafe {
56 let mut child_pid = mem::MaybeUninit::uninit();
57 let mut error = ptr::null_mut();
58 let _ = ffi::g_spawn_async_with_fds(
59 working_directory.as_ref().to_glib_none().0,
60 argv.to_glib_none().0,
61 envp.to_glib_none().0,
62 flags.into_glib(),
63 child_setup,
64 Box_::into_raw(super_callback0) as *mut _,
65 child_pid.as_mut_ptr(),
66 stdin_raw_fd,
67 stdout_raw_fd,
68 stderr_raw_fd,
69 &mut error,
70 );
71 let child_pid = from_glib(child_pid.assume_init());
72 if error.is_null() {
73 Ok(child_pid)
74 } else {
75 Err(from_glib_full(error))
76 }
77 }
78}
79
80#[cfg(not(windows))]
138#[cfg_attr(docsrs, doc(cfg(not(windows))))]
139#[doc(alias = "g_spawn_async_with_pipes")]
140pub fn spawn_async_with_pipes<
141 P: AsRef<std::path::Path>,
142 T: FromRawFd,
143 U: FromRawFd,
144 V: FromRawFd,
145>(
146 working_directory: P,
147 argv: &[&std::path::Path],
148 envp: &[&std::path::Path],
149 flags: SpawnFlags,
150 child_setup: Option<Box_<dyn FnOnce() + 'static>>,
151) -> Result<(Pid, T, U, V), Error> {
152 let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
153 unsafe extern "C" fn child_setup_func(user_data: ffi::gpointer) {
154 unsafe {
155 let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
156 Box_::from_raw(user_data as *mut _);
157 let callback = (*callback).expect("cannot get closure...");
158 callback()
159 }
160 }
161 let child_setup = if child_setup_data.is_some() {
162 Some(child_setup_func as _)
163 } else {
164 None
165 };
166 let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
167 unsafe {
168 let mut child_pid = mem::MaybeUninit::uninit();
169 let mut standard_input = mem::MaybeUninit::uninit();
170 let mut standard_output = mem::MaybeUninit::uninit();
171 let mut standard_error = mem::MaybeUninit::uninit();
172 let mut error = ptr::null_mut();
173 let _ = ffi::g_spawn_async_with_pipes(
174 working_directory.as_ref().to_glib_none().0,
175 argv.to_glib_none().0,
176 envp.to_glib_none().0,
177 flags.into_glib(),
178 child_setup,
179 Box_::into_raw(super_callback0) as *mut _,
180 child_pid.as_mut_ptr(),
181 standard_input.as_mut_ptr(),
182 standard_output.as_mut_ptr(),
183 standard_error.as_mut_ptr(),
184 &mut error,
185 );
186 if error.is_null() {
187 let child_pid = from_glib(child_pid.assume_init());
188 let standard_input = standard_input.assume_init();
189 let standard_output = standard_output.assume_init();
190 let standard_error = standard_error.assume_init();
191 #[cfg(not(windows))]
192 {
193 Ok((
194 child_pid,
195 FromRawFd::from_raw_fd(standard_input),
196 FromRawFd::from_raw_fd(standard_output),
197 FromRawFd::from_raw_fd(standard_error),
198 ))
199 }
200 } else {
211 Err(from_glib_full(error))
212 }
213 }
214}
215
216#[doc(alias = "g_get_charset")]
222#[doc(alias = "get_charset")]
223pub fn charset() -> (bool, Option<&'static GStr>) {
224 unsafe {
225 let mut out_charset = ptr::null();
226 let is_utf8 = from_glib(ffi::g_get_charset(&mut out_charset));
227 let charset = from_glib_none(out_charset);
228 (is_utf8, charset)
229 }
230}
231
232#[doc(alias = "g_compute_checksum_for_string")]
233pub fn compute_checksum_for_string(
234 checksum_type: ChecksumType,
235 str: impl IntoGStr,
236) -> Option<crate::GString> {
237 str.run_with_gstr(|str| unsafe {
238 from_glib_full(ffi::g_compute_checksum_for_string(
239 checksum_type.into_glib(),
240 str.as_ptr(),
241 str.len() as _,
242 ))
243 })
244}
245
246#[cfg(unix)]
247#[doc(alias = "g_file_open_tmp")]
248pub fn file_open_tmp(
249 tmpl: Option<impl AsRef<std::path::Path>>,
250) -> Result<(OwnedFd, std::path::PathBuf), crate::Error> {
251 unsafe {
252 let mut name_used = ptr::null_mut();
253 let mut error = ptr::null_mut();
254 let ret = ffi::g_file_open_tmp(
255 tmpl.as_ref().map(|p| p.as_ref()).to_glib_none().0,
256 &mut name_used,
257 &mut error,
258 );
259 if error.is_null() {
260 Ok((OwnedFd::from_raw_fd(ret), from_glib_full(name_used)))
261 } else {
262 Err(from_glib_full(error))
263 }
264 }
265}
266
267#[cfg(feature = "futures")]
273pub fn spawn_future<R: Send + 'static, F: std::future::Future<Output = R> + Send + 'static>(
274 f: F,
275) -> crate::JoinHandle<R> {
276 let ctx = crate::MainContext::ref_thread_default();
277 ctx.spawn(f)
278}
279
280#[cfg(feature = "futures")]
289pub fn spawn_future_local<R: 'static, F: std::future::Future<Output = R> + 'static>(
290 f: F,
291) -> crate::JoinHandle<R> {
292 let ctx = crate::MainContext::ref_thread_default();
293 ctx.spawn_local(f)
294}