1 #[cfg(not(windows))]
2 use glib_sys;
3 #[cfg(any(feature = "v2_58", feature = "dox"))]
4 #[cfg(not(windows))]
5 use std;
6 #[cfg(not(windows))]
7 use std::boxed::Box as Box_;
8 #[cfg(not(windows))]
9 use std::mem;
10 #[cfg(not(windows))]
11 #[cfg(any(feature = "v2_58", feature = "dox"))]
12 use std::os::unix::io::AsRawFd;
13 #[cfg(not(windows))]
14 use std::os::unix::io::FromRawFd;
15 // #[cfg(windows)]
16 // #[cfg(any(feature = "v2_58", feature = "dox"))]
17 // use std::os::windows::io::AsRawHandle;
18 #[cfg(not(windows))]
19 use std::ptr;
20 #[cfg(not(windows))]
21 use translate::*;
22 #[cfg(not(windows))]
23 use Error;
24 #[cfg(not(windows))]
25 use Pid;
26 #[cfg(not(windows))]
27 use SpawnFlags;
28 
29 #[cfg(any(feature = "v2_58", feature = "dox"))]
30 #[cfg(not(windows))]
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>31 pub fn spawn_async_with_fds<P: AsRef<std::path::Path>, T: AsRawFd, U: AsRawFd, V: AsRawFd>(
32     working_directory: P,
33     argv: &[&str],
34     envp: &[&str],
35     flags: SpawnFlags,
36     child_setup: Option<Box_<dyn FnOnce() + 'static>>,
37     stdin_fd: T,
38     stdout_fd: U,
39     stderr_fd: V,
40 ) -> Result<Pid, Error> {
41     let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
42     unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(
43         user_data: glib_sys::gpointer,
44     ) {
45         let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
46             Box_::from_raw(user_data as *mut _);
47         let callback = (*callback).expect("cannot get closure...");
48         callback()
49     }
50     let child_setup = if child_setup_data.is_some() {
51         Some(child_setup_func::<P> as _)
52     } else {
53         None
54     };
55     let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
56     unsafe {
57         let mut child_pid = mem::MaybeUninit::uninit();
58         let mut error = ptr::null_mut();
59         let _ = glib_sys::g_spawn_async_with_fds(
60             working_directory.as_ref().to_glib_none().0,
61             argv.to_glib_none().0,
62             envp.to_glib_none().0,
63             flags.to_glib(),
64             child_setup,
65             Box_::into_raw(super_callback0) as *mut _,
66             child_pid.as_mut_ptr(),
67             stdin_fd.as_raw_fd(),
68             stdout_fd.as_raw_fd(),
69             stderr_fd.as_raw_fd(),
70             &mut error,
71         );
72         let child_pid = from_glib(child_pid.assume_init());
73         if error.is_null() {
74             Ok(child_pid)
75         } else {
76             Err(from_glib_full(error))
77         }
78     }
79 }
80 
81 // #[cfg(any(feature = "v2_58", feature = "dox"))]
82 // #[cfg(windows)]
83 // pub fn spawn_async_with_fds<
84 //     P: AsRef<std::path::Path>,
85 //     T: AsRawHandle,
86 //     U: AsRawHandle,
87 //     V: AsRawHandle,
88 // >(
89 //     working_directory: P,
90 //     argv: &[&str],
91 //     envp: &[&str],
92 //     flags: SpawnFlags,
93 //     child_setup: Option<Box_<dyn FnOnce() + 'static>>,
94 //     stdin_fd: T,
95 //     stdout_fd: U,
96 //     stderr_fd: V,
97 // ) -> Result<Pid, Error> {
98 //     let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
99 //     unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(
100 //         user_data: glib_sys::gpointer,
101 //     ) {
102 //         let callback: Box_<Option<Box_<dyn FnOnce() + 'static>>> =
103 //             Box_::from_raw(user_data as *mut _);
104 //         let callback = (*callback).expect("cannot get closure...");
105 //         callback()
106 //     }
107 //     let child_setup = if child_setup_data.is_some() {
108 //         Some(child_setup_func::<P> as _)
109 //     } else {
110 //         None
111 //     };
112 //     let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
113 //     unsafe {
114 //         let mut child_pid = mem::MaybeUninit::uninit();
115 //         let mut error = ptr::null_mut();
116 //         let _ = glib_sys::g_spawn_async_with_fds(
117 //             working_directory.as_ref().to_glib_none().0,
118 //             argv.to_glib_none().0,
119 //             envp.to_glib_none().0,
120 //             flags.to_glib(),
121 //             child_setup,
122 //             Box_::into_raw(super_callback0) as *mut _,
123 //             child_pid.as_mut_ptr(),
124 //             stdin_fd.as_raw_handle() as usize as _,
125 //             stdout_fd.as_raw_handle() as usize as _,
126 //             stderr_fd.as_raw_handle() as usize as _,
127 //             &mut error,
128 //         );
129 //         let child_pid = from_glib(child_pid.assume_init());
130 //         if error.is_null() {
131 //             Ok(child_pid)
132 //         } else {
133 //             Err(from_glib_full(error))
134 //         }
135 //     }
136 // }
137 
138 #[cfg(not(windows))]
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>139 pub fn spawn_async_with_pipes<
140     P: AsRef<std::path::Path>,
141     T: FromRawFd,
142     U: FromRawFd,
143     V: FromRawFd,
144 >(
145     working_directory: P,
146     argv: &[&std::path::Path],
147     envp: &[&std::path::Path],
148     flags: SpawnFlags,
149     child_setup: Option<Box_<dyn FnOnce() + 'static>>,
150 ) -> Result<(Pid, T, U, V), Error> {
151     let child_setup_data: Box_<Option<Box_<dyn FnOnce() + 'static>>> = Box_::new(child_setup);
152     unsafe extern "C" fn child_setup_func<P: AsRef<std::path::Path>>(
153         user_data: glib_sys::gpointer,
154     ) {
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     let child_setup = if child_setup_data.is_some() {
161         Some(child_setup_func::<P> as _)
162     } else {
163         None
164     };
165     let super_callback0: Box_<Option<Box_<dyn FnOnce() + 'static>>> = child_setup_data;
166     unsafe {
167         let mut child_pid = mem::MaybeUninit::uninit();
168         let mut standard_input = mem::MaybeUninit::uninit();
169         let mut standard_output = mem::MaybeUninit::uninit();
170         let mut standard_error = mem::MaybeUninit::uninit();
171         let mut error = ptr::null_mut();
172         let _ = glib_sys::g_spawn_async_with_pipes(
173             working_directory.as_ref().to_glib_none().0,
174             argv.to_glib_none().0,
175             envp.to_glib_none().0,
176             flags.to_glib(),
177             child_setup,
178             Box_::into_raw(super_callback0) as *mut _,
179             child_pid.as_mut_ptr(),
180             standard_input.as_mut_ptr(),
181             standard_output.as_mut_ptr(),
182             standard_error.as_mut_ptr(),
183             &mut error,
184         );
185         let child_pid = from_glib(child_pid.assume_init());
186         let standard_input = standard_input.assume_init();
187         let standard_output = standard_output.assume_init();
188         let standard_error = standard_error.assume_init();
189         if error.is_null() {
190             #[cfg(not(windows))]
191             {
192                 Ok((
193                     child_pid,
194                     FromRawFd::from_raw_fd(standard_input),
195                     FromRawFd::from_raw_fd(standard_output),
196                     FromRawFd::from_raw_fd(standard_error),
197                 ))
198             }
199         // #[cfg(windows)]
200         // {
201         //     use std::os::windows::io::{FromRawHandle, RawHandle};
202         //     Ok((
203         //         child_pid,
204         //         File::from_raw_handle(standard_input as usize as RawHandle),
205         //         File::from_raw_handle(standard_output as usize as RawHandle),
206         //         File::from_raw_handle(standard_error as usize as RawHandle),
207         //     ))
208         // }
209         } else {
210             Err(from_glib_full(error))
211         }
212     }
213 }
214