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}