gio/
subprocess_launcher.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3#[cfg(any(unix, all(docsrs, unix)))]
4use std::os::unix::io::{AsFd, AsRawFd, IntoRawFd, OwnedFd};
5
6use glib::translate::*;
7
8use crate::ffi;
9use crate::SubprocessLauncher;
10
11#[cfg(all(docsrs, not(unix)))]
12pub trait IntoRawFd: Sized {
13    fn into_raw_fd(self) -> i32 {
14        0
15    }
16}
17
18impl SubprocessLauncher {
19    /// Replace the entire environment of processes launched from this
20    /// launcher with the given 'environ' variable.
21    ///
22    /// Typically you will build this variable by using g_listenv() to copy
23    /// the process 'environ' and using the functions g_environ_setenv(),
24    /// g_environ_unsetenv(), etc.
25    ///
26    /// As an alternative, you can use g_subprocess_launcher_setenv(),
27    /// g_subprocess_launcher_unsetenv(), etc.
28    ///
29    /// Pass an empty array to set an empty environment. Pass [`None`] to inherit the
30    /// parent process’ environment. As of GLib 2.54, the parent process’ environment
31    /// will be copied when g_subprocess_launcher_set_environ() is called.
32    /// Previously, it was copied when the subprocess was executed. This means the
33    /// copied environment may now be modified (using g_subprocess_launcher_setenv(),
34    /// etc.) before launching the subprocess.
35    ///
36    /// On UNIX, all strings in this array can be arbitrary byte strings.
37    /// On Windows, they should be in UTF-8.
38    /// ## `env`
39    ///
40    ///     the replacement environment
41    #[doc(alias = "g_subprocess_launcher_set_environ")]
42    pub fn set_environ(&self, env: &[std::ffi::OsString]) {
43        unsafe {
44            ffi::g_subprocess_launcher_set_environ(self.to_glib_none().0, env.to_glib_none().0);
45        }
46    }
47
48    /// Transfer an arbitrary file descriptor from parent process to the
49    /// child.  This function takes ownership of the @source_fd; it will be closed
50    /// in the parent when @self is freed.
51    ///
52    /// By default, all file descriptors from the parent will be closed.
53    /// This function allows you to create (for example) a custom `pipe()` or
54    /// `socketpair()` before launching the process, and choose the target
55    /// descriptor in the child.
56    ///
57    /// An example use case is GNUPG, which has a command line argument
58    /// `--passphrase-fd` providing a file descriptor number where it expects
59    /// the passphrase to be written.
60    /// ## `source_fd`
61    /// File descriptor in parent process
62    /// ## `target_fd`
63    /// Target descriptor for child process
64    #[cfg(unix)]
65    #[cfg_attr(docsrs, doc(cfg(unix)))]
66    #[doc(alias = "g_subprocess_launcher_take_fd")]
67    pub fn take_fd(&self, source_fd: OwnedFd, target_fd: impl AsFd) {
68        let source_raw_fd = source_fd.into_raw_fd();
69        let target_raw_fd = target_fd.as_fd().as_raw_fd();
70        unsafe {
71            ffi::g_subprocess_launcher_take_fd(self.to_glib_none().0, source_raw_fd, target_raw_fd);
72        }
73    }
74
75    /// Sets the file descriptor to use as the stderr for spawned processes.
76    ///
77    /// If @fd is -1 then any previously given fd is unset.
78    ///
79    /// Note that the default behaviour is to pass stderr through to the
80    /// stderr of the parent process.
81    ///
82    /// The passed @fd belongs to the #GSubprocessLauncher.  It will be
83    /// automatically closed when the launcher is finalized.  The file
84    /// descriptor will also be closed on the child side when executing the
85    /// spawned process.
86    ///
87    /// You may not set a stderr fd if a stderr file path is already set or
88    /// if the launcher flags contain any flags directing stderr elsewhere.
89    ///
90    /// This feature is only available on UNIX.
91    /// ## `fd`
92    /// a file descriptor, or -1
93    #[cfg(unix)]
94    #[cfg_attr(docsrs, doc(cfg(unix)))]
95    #[doc(alias = "g_subprocess_launcher_take_stderr_fd")]
96    pub fn take_stderr_fd(&self, fd: Option<OwnedFd>) {
97        unsafe {
98            let raw_fd = fd.map_or(-1, |fd| fd.into_raw_fd());
99            ffi::g_subprocess_launcher_take_stderr_fd(self.to_glib_none().0, raw_fd);
100        }
101    }
102
103    /// Sets the file descriptor to use as the stdin for spawned processes.
104    ///
105    /// If @fd is -1 then any previously given fd is unset.
106    ///
107    /// Note that if your intention is to have the stdin of the calling
108    /// process inherited by the child then [`SubprocessFlags::STDIN_INHERIT`][crate::SubprocessFlags::STDIN_INHERIT]
109    /// is a better way to go about doing that.
110    ///
111    /// The passed @fd is noted but will not be touched in the current
112    /// process.  It is therefore necessary that it be kept open by the
113    /// caller until the subprocess is spawned.  The file descriptor will
114    /// also not be explicitly closed on the child side, so it must be marked
115    /// O_CLOEXEC if that's what you want.
116    ///
117    /// You may not set a stdin fd if a stdin file path is already set or if
118    /// the launcher flags contain any flags directing stdin elsewhere.
119    ///
120    /// This feature is only available on UNIX.
121    /// ## `fd`
122    /// a file descriptor, or -1
123    #[cfg(unix)]
124    #[cfg_attr(docsrs, doc(cfg(unix)))]
125    #[doc(alias = "g_subprocess_launcher_take_stdin_fd")]
126    pub fn take_stdin_fd(&self, fd: Option<OwnedFd>) {
127        let raw_fd = fd.map_or(-1, |fd| fd.into_raw_fd());
128        unsafe {
129            ffi::g_subprocess_launcher_take_stdin_fd(self.to_glib_none().0, raw_fd);
130        }
131    }
132
133    /// Sets the file descriptor to use as the stdout for spawned processes.
134    ///
135    /// If @fd is -1 then any previously given fd is unset.
136    ///
137    /// Note that the default behaviour is to pass stdout through to the
138    /// stdout of the parent process.
139    ///
140    /// The passed @fd is noted but will not be touched in the current
141    /// process.  It is therefore necessary that it be kept open by the
142    /// caller until the subprocess is spawned.  The file descriptor will
143    /// also not be explicitly closed on the child side, so it must be marked
144    /// O_CLOEXEC if that's what you want.
145    ///
146    /// You may not set a stdout fd if a stdout file path is already set or
147    /// if the launcher flags contain any flags directing stdout elsewhere.
148    ///
149    /// This feature is only available on UNIX.
150    /// ## `fd`
151    /// a file descriptor, or -1
152    #[cfg(unix)]
153    #[cfg_attr(docsrs, doc(cfg(unix)))]
154    #[doc(alias = "g_subprocess_launcher_take_stdout_fd")]
155    pub fn take_stdout_fd(&self, fd: Option<OwnedFd>) {
156        let raw_fd = fd.map_or(-1, |fd| fd.into_raw_fd());
157        unsafe {
158            ffi::g_subprocess_launcher_take_stdout_fd(self.to_glib_none().0, raw_fd);
159        }
160    }
161}