]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/vxworks/ext/process.rs
resolve comments
[rust.git] / library / std / src / sys / vxworks / ext / process.rs
1 //! Unix-specific extensions to primitives in the `std::process` module.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use crate::ffi::OsStr;
6 use crate::io;
7 use crate::process;
8 use crate::sys;
9 use crate::sys::vxworks::ext::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
10 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
11
12 /// Unix-specific extensions to the [`process::Command`] builder.
13 ///
14 #[stable(feature = "rust1", since = "1.0.0")]
15 pub trait CommandExt {
16     /// Sets the child process's user ID. This translates to a
17     /// `setuid` call in the child process. Failure in the `setuid`
18     /// call will cause the spawn to fail.
19     #[stable(feature = "rust1", since = "1.0.0")]
20     fn uid(&mut self, id: u16) -> &mut process::Command;
21
22     /// Similar to `uid`, but sets the group ID of the child process. This has
23     /// the same semantics as the `uid` field.
24     #[stable(feature = "rust1", since = "1.0.0")]
25     fn gid(&mut self, id: u16) -> &mut process::Command;
26
27     /// Schedules a closure to be run just before the `exec` function is
28     /// invoked.
29     ///
30     /// The closure is allowed to return an I/O error whose OS error code will
31     /// be communicated back to the parent and returned as an error from when
32     /// the spawn was requested.
33     ///
34     /// Multiple closures can be registered and they will be called in order of
35     /// their registration. If a closure returns `Err` then no further closures
36     /// will be called and the spawn operation will immediately return with a
37     /// failure.
38     ///
39     /// # Notes and Safety
40     ///
41     /// This closure will be run in the context of the child process after a
42     /// `fork`. This primarily means that any modifications made to memory on
43     /// behalf of this closure will **not** be visible to the parent process.
44     /// This is often a very constrained environment where normal operations
45     /// like `malloc` or acquiring a mutex are not guaranteed to work (due to
46     /// other threads perhaps still running when the `fork` was run).
47     ///
48     /// This also means that all resources such as file descriptors and
49     /// memory-mapped regions got duplicated. It is your responsibility to make
50     /// sure that the closure does not violate library invariants by making
51     /// invalid use of these duplicates.
52     ///
53     /// When this closure is run, aspects such as the stdio file descriptors and
54     /// working directory have successfully been changed, so output to these
55     /// locations may not appear where intended.
56     #[stable(feature = "process_pre_exec", since = "1.34.0")]
57     unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
58     where
59         F: FnMut() -> io::Result<()> + Send + Sync + 'static;
60
61     /// Schedules a closure to be run just before the `exec` function is
62     /// invoked.
63     ///
64     /// This method is stable and usable, but it should be unsafe. To fix
65     /// that, it got deprecated in favor of the unsafe [`pre_exec`].
66     ///
67     /// [`pre_exec`]: CommandExt::pre_exec
68     #[stable(feature = "process_exec", since = "1.15.0")]
69     #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
70     fn before_exec<F>(&mut self, f: F) -> &mut process::Command
71     where
72         F: FnMut() -> io::Result<()> + Send + Sync + 'static,
73     {
74         unsafe { self.pre_exec(f) }
75     }
76
77     /// Performs all the required setup by this `Command`, followed by calling
78     /// the `execvp` syscall.
79     ///
80     /// On success this function will not return, and otherwise it will return
81     /// an error indicating why the exec (or another part of the setup of the
82     /// `Command`) failed.
83     ///
84     /// `exec` not returning has the same implications as calling
85     /// [`process::exit`] – no destructors on the current stack or any other
86     /// thread’s stack will be run. Therefore, it is recommended to only call
87     /// `exec` at a point where it is fine to not run any destructors. Note,
88     /// that the `execvp` syscall independently guarantees that all memory is
89     /// freed and all file descriptors with the `CLOEXEC` option (set by default
90     /// on all file descriptors opened by the standard library) are closed.
91     ///
92     /// This function, unlike `spawn`, will **not** `fork` the process to create
93     /// a new child. Like spawn, however, the default behavior for the stdio
94     /// descriptors will be to inherited from the current process.
95     ///
96     ///
97     /// # Notes
98     ///
99     /// The process may be in a "broken state" if this function returns in
100     /// error. For example the working directory, environment variables, signal
101     /// handling settings, various user/group information, or aspects of stdio
102     /// file descriptors may have changed. If a "transactional spawn" is
103     /// required to gracefully handle errors it is recommended to use the
104     /// cross-platform `spawn` instead.
105     #[stable(feature = "process_exec2", since = "1.9.0")]
106     fn exec(&mut self) -> io::Error;
107
108     /// Set executable argument
109     ///
110     /// Set the first process argument, `argv[0]`, to something other than the
111     /// default executable path.
112     #[stable(feature = "process_set_argv0", since = "1.45.0")]
113     fn arg0<S>(&mut self, arg: S) -> &mut process::Command
114     where
115         S: AsRef<OsStr>;
116 }
117
118 #[stable(feature = "rust1", since = "1.0.0")]
119 impl CommandExt for process::Command {
120     fn uid(&mut self, id: u16) -> &mut process::Command {
121         self.as_inner_mut().uid(id);
122         self
123     }
124
125     fn gid(&mut self, id: u16) -> &mut process::Command {
126         self.as_inner_mut().gid(id);
127         self
128     }
129
130     unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
131     where
132         F: FnMut() -> io::Result<()> + Send + Sync + 'static,
133     {
134         self.as_inner_mut().pre_exec(Box::new(f));
135         self
136     }
137
138     fn exec(&mut self) -> io::Error {
139         self.as_inner_mut().exec(sys::process::Stdio::Inherit)
140     }
141
142     fn arg0<S>(&mut self, arg: S) -> &mut process::Command
143     where
144         S: AsRef<OsStr>,
145     {
146         self.as_inner_mut().set_arg_0(arg.as_ref());
147         self
148     }
149 }
150
151 /// Unix-specific extensions to [`process::ExitStatus`].
152 ///
153 #[stable(feature = "rust1", since = "1.0.0")]
154 pub trait ExitStatusExt {
155     /// Creates a new `ExitStatus` from the raw underlying `i32` return value of
156     /// a process.
157     #[stable(feature = "exit_status_from", since = "1.12.0")]
158     fn from_raw(raw: i32) -> Self;
159
160     /// If the process was terminated by a signal, returns that signal.
161     #[stable(feature = "rust1", since = "1.0.0")]
162     fn signal(&self) -> Option<i32>;
163 }
164
165 #[stable(feature = "rust1", since = "1.0.0")]
166 impl ExitStatusExt for process::ExitStatus {
167     fn from_raw(raw: i32) -> Self {
168         process::ExitStatus::from_inner(From::from(raw))
169     }
170
171     fn signal(&self) -> Option<i32> {
172         self.as_inner().signal()
173     }
174 }
175
176 #[stable(feature = "process_extensions", since = "1.2.0")]
177 impl FromRawFd for process::Stdio {
178     unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio {
179         let fd = sys::fd::FileDesc::new(fd);
180         let io = sys::process::Stdio::Fd(fd);
181         process::Stdio::from_inner(io)
182     }
183 }
184
185 #[stable(feature = "process_extensions", since = "1.2.0")]
186 impl AsRawFd for process::ChildStdin {
187     fn as_raw_fd(&self) -> RawFd {
188         self.as_inner().fd().raw()
189     }
190 }
191
192 #[stable(feature = "process_extensions", since = "1.2.0")]
193 impl AsRawFd for process::ChildStdout {
194     fn as_raw_fd(&self) -> RawFd {
195         self.as_inner().fd().raw()
196     }
197 }
198
199 #[stable(feature = "process_extensions", since = "1.2.0")]
200 impl AsRawFd for process::ChildStderr {
201     fn as_raw_fd(&self) -> RawFd {
202         self.as_inner().fd().raw()
203     }
204 }
205
206 #[stable(feature = "into_raw_os", since = "1.4.0")]
207 impl IntoRawFd for process::ChildStdin {
208     fn into_raw_fd(self) -> RawFd {
209         self.into_inner().into_fd().into_raw()
210     }
211 }
212
213 #[stable(feature = "into_raw_os", since = "1.4.0")]
214 impl IntoRawFd for process::ChildStdout {
215     fn into_raw_fd(self) -> RawFd {
216         self.into_inner().into_fd().into_raw()
217     }
218 }
219
220 #[stable(feature = "into_raw_os", since = "1.4.0")]
221 impl IntoRawFd for process::ChildStderr {
222     fn into_raw_fd(self) -> RawFd {
223         self.into_inner().into_fd().into_raw()
224     }
225 }
226
227 /// Returns the OS-assigned process identifier associated with this process's parent.
228 #[stable(feature = "unix_ppid", since = "1.27.0")]
229 pub fn parent_id() -> u32 {
230     crate::sys::os::getppid()
231 }