1use super::super::resource::{LimitPair, Resource};
20use super::super::{
21 Chdir, ChildProcessStarter, Clock, Close, CpuTimes, Dir, Dup, Exec, Exit, Fcntl, FdFlag, Fork,
22 Fstat, GetCwd, GetPid, GetPw, GetRlimit, GetSigaction, GetUid, Gid, IsExecutableFile, Isatty,
23 Mode, OfdAccess, Open, OpenFlag, Pipe, Result, Seek, SendSignal, SetPgid, SetRlimit, ShellPath,
24 Sigaction, Sigmask, SigmaskOp, Signals, Sysconf, TcGetPgrp, TcSetPgrp, Times, Uid, Umask, Wait,
25 signal,
26};
27use super::Concurrent;
28use crate::io::Fd;
29use crate::job::{Pid, ProcessState};
30use crate::path::PathBuf;
31use crate::semantics::ExitStatus;
32use enumset::EnumSet;
33use std::convert::Infallible;
34use std::ffi::{CStr, CString};
35use std::io::SeekFrom;
36use std::ops::RangeInclusive;
37use std::time::Instant;
38use unix_str::UnixString;
39
40impl<S> Fstat for Concurrent<S>
41where
42 S: Fstat + Sigmask,
43{
44 type Stat = S::Stat;
45
46 #[inline]
47 fn fstat(&self, fd: Fd) -> Result<Self::Stat> {
48 self.inner.fstat(fd)
49 }
50 #[inline]
51 fn fstatat(&self, dir_fd: Fd, path: &CStr, follow_symlinks: bool) -> Result<Self::Stat> {
52 self.inner.fstatat(dir_fd, path, follow_symlinks)
53 }
54 #[inline]
55 fn is_directory(&self, path: &CStr) -> bool {
56 self.inner.is_directory(path)
57 }
58 #[inline]
59 fn fd_is_pipe(&self, fd: Fd) -> bool {
60 self.inner.fd_is_pipe(fd)
61 }
62}
63
64impl<S> IsExecutableFile for Concurrent<S>
65where
66 S: IsExecutableFile + Sigmask,
67{
68 #[inline]
69 fn is_executable_file(&self, path: &CStr) -> bool {
70 self.inner.is_executable_file(path)
71 }
72}
73
74impl<S> Pipe for Concurrent<S>
75where
76 S: Pipe + Sigmask,
77{
78 #[inline]
79 fn pipe(&self) -> Result<(Fd, Fd)> {
80 self.inner.pipe()
81 }
82}
83
84impl<S> Dup for Concurrent<S>
85where
86 S: Dup + Sigmask,
87{
88 #[inline]
89 fn dup(&self, from: Fd, to_min: Fd, flags: EnumSet<FdFlag>) -> Result<Fd> {
90 self.inner.dup(from, to_min, flags)
91 }
92
93 #[inline]
94 fn dup2(&self, from: Fd, to: Fd) -> Result<Fd> {
95 self.inner.dup2(from, to)
96 }
97}
98
99impl<S> Open for Concurrent<S>
101where
102 S: Open + Sigmask,
103{
104 #[inline]
105 fn open(
106 &self,
107 path: &CStr,
108 access: OfdAccess,
109 flags: EnumSet<OpenFlag>,
110 mode: Mode,
111 ) -> impl Future<Output = Result<Fd>> + use<S> {
112 self.inner.open(path, access, flags, mode)
113 }
114
115 #[inline]
116 fn open_tmpfile(&self, parent_dir: &unix_path::Path) -> Result<Fd> {
117 self.inner.open_tmpfile(parent_dir)
118 }
119
120 #[inline]
121 fn fdopendir(&self, fd: Fd) -> Result<impl Dir + use<S>> {
122 self.inner.fdopendir(fd)
123 }
124
125 #[inline]
126 fn opendir(&self, path: &CStr) -> Result<impl Dir + use<S>> {
127 self.inner.opendir(path)
128 }
129}
130
131impl<S> Close for Concurrent<S>
132where
133 S: Close + Sigmask,
134{
135 #[inline]
136 fn close(&self, fd: Fd) -> Result<()> {
137 self.inner.close(fd)
138 }
139}
140
141impl<S> Fcntl for Concurrent<S>
142where
143 S: Fcntl + Sigmask,
144{
145 #[inline]
146 fn ofd_access(&self, fd: Fd) -> Result<OfdAccess> {
147 self.inner.ofd_access(fd)
148 }
149
150 #[inline]
151 fn get_and_set_nonblocking(&self, fd: Fd, nonblocking: bool) -> Result<bool> {
152 self.inner.get_and_set_nonblocking(fd, nonblocking)
153 }
154
155 #[inline]
156 fn fcntl_getfd(&self, fd: Fd) -> Result<EnumSet<FdFlag>> {
157 self.inner.fcntl_getfd(fd)
158 }
159
160 #[inline]
161 fn fcntl_setfd(&self, fd: Fd, flags: EnumSet<FdFlag>) -> Result<()> {
162 self.inner.fcntl_setfd(fd, flags)
163 }
164}
165
166impl<S> Seek for Concurrent<S>
167where
168 S: Seek + Sigmask,
169{
170 #[inline]
171 fn lseek(&self, fd: Fd, position: SeekFrom) -> Result<u64> {
172 self.inner.lseek(fd, position)
173 }
174}
175
176impl<S> Umask for Concurrent<S>
177where
178 S: Sigmask + Umask,
179{
180 #[inline]
181 fn umask(&self, new_mask: Mode) -> Mode {
182 self.inner.umask(new_mask)
183 }
184}
185
186impl<S> GetCwd for Concurrent<S>
187where
188 S: GetCwd + Sigmask,
189{
190 #[inline]
191 fn getcwd(&self) -> Result<PathBuf> {
192 self.inner.getcwd()
193 }
194}
195
196impl<S> Chdir for Concurrent<S>
197where
198 S: Chdir + Sigmask,
199{
200 #[inline]
201 fn chdir(&self, path: &CStr) -> Result<()> {
202 self.inner.chdir(path)
203 }
204}
205
206impl<S> Clock for Concurrent<S>
207where
208 S: Clock + Sigmask,
209{
210 #[inline]
211 fn now(&self) -> Instant {
212 self.inner.now()
213 }
214}
215
216impl<S> Times for Concurrent<S>
217where
218 S: Sigmask + Times,
219{
220 #[inline]
221 fn times(&self) -> Result<CpuTimes> {
222 self.inner.times()
223 }
224}
225
226impl<S> GetPid for Concurrent<S>
227where
228 S: GetPid + Sigmask,
229{
230 #[inline]
231 fn getpid(&self) -> Pid {
232 self.inner.getpid()
233 }
234 #[inline]
235 fn getppid(&self) -> Pid {
236 self.inner.getppid()
237 }
238 #[inline]
239 fn getpgrp(&self) -> Pid {
240 self.inner.getpgrp()
241 }
242 #[inline]
243 fn getsid(&self, pid: Pid) -> Result<Pid> {
244 self.inner.getsid(pid)
245 }
246}
247
248impl<S> SetPgid for Concurrent<S>
249where
250 S: SetPgid + Sigmask,
251{
252 #[inline]
253 fn setpgid(&self, pid: Pid, pgid: Pid) -> Result<()> {
254 self.inner.setpgid(pid, pgid)
255 }
256}
257
258impl<S> Signals for Concurrent<S>
259where
260 S: Sigmask,
261{
262 const SIGABRT: signal::Number = S::SIGABRT;
263 const SIGALRM: signal::Number = S::SIGALRM;
264 const SIGBUS: signal::Number = S::SIGBUS;
265 const SIGCHLD: signal::Number = S::SIGCHLD;
266 const SIGCLD: Option<signal::Number> = S::SIGCLD;
267 const SIGCONT: signal::Number = S::SIGCONT;
268 const SIGEMT: Option<signal::Number> = S::SIGEMT;
269 const SIGFPE: signal::Number = S::SIGFPE;
270 const SIGHUP: signal::Number = S::SIGHUP;
271 const SIGILL: signal::Number = S::SIGILL;
272 const SIGINFO: Option<signal::Number> = S::SIGINFO;
273 const SIGINT: signal::Number = S::SIGINT;
274 const SIGIO: Option<signal::Number> = S::SIGIO;
275 const SIGIOT: signal::Number = S::SIGIOT;
276 const SIGKILL: signal::Number = S::SIGKILL;
277 const SIGLOST: Option<signal::Number> = S::SIGLOST;
278 const SIGPIPE: signal::Number = S::SIGPIPE;
279 const SIGPOLL: Option<signal::Number> = S::SIGPOLL;
280 const SIGPROF: signal::Number = S::SIGPROF;
281 const SIGPWR: Option<signal::Number> = S::SIGPWR;
282 const SIGQUIT: signal::Number = S::SIGQUIT;
283 const SIGSEGV: signal::Number = S::SIGSEGV;
284 const SIGSTKFLT: Option<signal::Number> = S::SIGSTKFLT;
285 const SIGSTOP: signal::Number = S::SIGSTOP;
286 const SIGSYS: signal::Number = S::SIGSYS;
287 const SIGTERM: signal::Number = S::SIGTERM;
288 const SIGTHR: Option<signal::Number> = S::SIGTHR;
289 const SIGTRAP: signal::Number = S::SIGTRAP;
290 const SIGTSTP: signal::Number = S::SIGTSTP;
291 const SIGTTIN: signal::Number = S::SIGTTIN;
292 const SIGTTOU: signal::Number = S::SIGTTOU;
293 const SIGURG: signal::Number = S::SIGURG;
294 const SIGUSR1: signal::Number = S::SIGUSR1;
295 const SIGUSR2: signal::Number = S::SIGUSR2;
296 const SIGVTALRM: signal::Number = S::SIGVTALRM;
297 const SIGWINCH: signal::Number = S::SIGWINCH;
298 const SIGXCPU: signal::Number = S::SIGXCPU;
299 const SIGXFSZ: signal::Number = S::SIGXFSZ;
300
301 #[inline]
302 fn sigrt_range(&self) -> Option<RangeInclusive<signal::Number>> {
303 self.inner.sigrt_range()
304 }
305
306 const NAMED_SIGNALS: &'static [(&'static str, Option<signal::Number>)] = S::NAMED_SIGNALS;
307
308 #[inline]
309 fn iter_sigrt(&self) -> impl DoubleEndedIterator<Item = signal::Number> + use<S> {
310 self.inner.iter_sigrt()
311 }
312 #[inline]
313 fn to_signal_number<N: Into<signal::RawNumber>>(&self, number: N) -> Option<signal::Number> {
314 self.inner.to_signal_number(number)
315 }
316 #[inline]
317 fn sig2str<N: Into<signal::RawNumber>>(
318 &self,
319 signal: N,
320 ) -> Option<std::borrow::Cow<'static, str>> {
321 self.inner.sig2str(signal)
322 }
323 #[inline]
324 fn str2sig(&self, name: &str) -> Option<signal::Number> {
325 self.inner.str2sig(name)
326 }
327 #[inline]
328 fn validate_signal(&self, number: signal::RawNumber) -> Option<(signal::Name, signal::Number)> {
329 self.inner.validate_signal(number)
330 }
331 #[inline]
332 fn signal_name_from_number(&self, number: signal::Number) -> signal::Name {
333 self.inner.signal_name_from_number(number)
334 }
335 #[inline]
336 fn signal_number_from_name(&self, name: signal::Name) -> Option<signal::Number> {
337 self.inner.signal_number_from_name(name)
338 }
339}
340
341impl<S> Sigmask for Concurrent<S>
354where
355 S: Sigmask,
356{
357 type Sigset = S::Sigset;
358
359 #[inline]
360 fn sigmask(
361 &self,
362 op_and_signals: Option<(SigmaskOp, &Self::Sigset)>,
363 old_mask: Option<&mut Self::Sigset>,
364 ) -> impl Future<Output = Result<()>> + use<S> {
365 self.inner.sigmask(op_and_signals, old_mask)
366 }
367}
368
369impl<S> GetSigaction for Concurrent<S>
370where
371 S: GetSigaction + Sigmask,
372{
373 #[inline]
374 fn get_sigaction(&self, signal: signal::Number) -> Result<signal::Disposition> {
375 self.inner.get_sigaction(signal)
376 }
377}
378
379impl<S> Sigaction for Concurrent<S>
399where
400 S: Sigaction + Sigmask,
401{
402 #[inline]
403 fn sigaction(
404 &self,
405 signal: signal::Number,
406 disposition: signal::Disposition,
407 ) -> Result<signal::Disposition> {
408 self.inner.sigaction(signal, disposition)
409 }
410}
411
412impl<S> SendSignal for Concurrent<S>
427where
428 S: SendSignal + Sigmask,
429{
430 #[inline]
431 fn kill(
432 &self,
433 pid: Pid,
434 signal: Option<signal::Number>,
435 ) -> impl Future<Output = Result<()>> + use<S> {
436 self.inner.kill(pid, signal)
437 }
438 #[inline]
439 fn raise(&self, signal: signal::Number) -> impl Future<Output = Result<()>> + use<S> {
440 self.inner.raise(signal)
441 }
442}
443
444impl<S> Isatty for Concurrent<S>
445where
446 S: Isatty + Sigmask,
447{
448 #[inline]
449 fn isatty(&self, fd: Fd) -> bool {
450 self.inner.isatty(fd)
451 }
452}
453
454impl<S> TcGetPgrp for Concurrent<S>
455where
456 S: Sigmask + TcGetPgrp,
457{
458 #[inline]
459 fn tcgetpgrp(&self, fd: Fd) -> Result<Pid> {
460 self.inner.tcgetpgrp(fd)
461 }
462}
463
464impl<S> TcSetPgrp for Concurrent<S>
465where
466 S: Sigmask + TcSetPgrp,
467{
468 #[inline]
469 fn tcsetpgrp(&self, fd: Fd, pgid: Pid) -> impl Future<Output = Result<()>> + use<S> {
470 self.inner.tcsetpgrp(fd, pgid)
471 }
472}
473
474impl<S> Concurrent<S>
475where
476 S: Fork + Sigmask,
477{
478 #[deprecated(
485 since = "0.14.0",
486 note = "use the `Fork::run_in_child_process` method instead"
487 )]
488 #[inline]
489 pub fn new_child_process(&self) -> Result<ChildProcessStarter<S>> {
490 #[allow(deprecated, reason = "the caller and callee are both deprecated")]
491 self.inner.new_child_process()
492 }
493}
494
495impl<S> Wait for Concurrent<S>
496where
497 S: Sigmask + Wait,
498{
499 #[inline]
500 fn wait(&self, target: Pid) -> Result<Option<(Pid, ProcessState)>> {
501 self.inner.wait(target)
502 }
503}
504
505impl<S> Exec for Concurrent<S>
506where
507 S: Exec + Sigmask,
508{
509 #[inline]
510 fn execve(
511 &self,
512 path: &CStr,
513 args: &[CString],
514 envs: &[CString],
515 ) -> impl Future<Output = Result<Infallible>> + use<S> {
516 self.inner.execve(path, args, envs)
517 }
518}
519
520impl<S> Exit for Concurrent<S>
521where
522 S: Exit + Sigmask,
523{
524 #[inline]
525 fn exit(&self, exit_status: ExitStatus) -> impl Future<Output = Infallible> + use<S> {
526 self.inner.exit(exit_status)
527 }
528}
529
530impl<S> GetUid for Concurrent<S>
531where
532 S: GetUid + Sigmask,
533{
534 #[inline]
535 fn getuid(&self) -> Uid {
536 self.inner.getuid()
537 }
538 #[inline]
539 fn geteuid(&self) -> Uid {
540 self.inner.geteuid()
541 }
542 #[inline]
543 fn getgid(&self) -> Gid {
544 self.inner.getgid()
545 }
546 #[inline]
547 fn getegid(&self) -> Gid {
548 self.inner.getegid()
549 }
550}
551
552impl<S> GetPw for Concurrent<S>
553where
554 S: GetPw + Sigmask,
555{
556 #[inline]
557 fn getpwnam_dir(&self, name: &CStr) -> Result<Option<PathBuf>> {
558 self.inner.getpwnam_dir(name)
559 }
560}
561
562impl<S> Sysconf for Concurrent<S>
563where
564 S: Sysconf + Sigmask,
565{
566 #[inline]
567 fn confstr_path(&self) -> Result<UnixString> {
568 self.inner.confstr_path()
569 }
570}
571
572impl<S> ShellPath for Concurrent<S>
573where
574 S: ShellPath + Sigmask,
575{
576 #[inline]
577 fn shell_path(&self) -> CString {
578 self.inner.shell_path()
579 }
580}
581
582impl<S> GetRlimit for Concurrent<S>
583where
584 S: GetRlimit + Sigmask,
585{
586 #[inline]
587 fn getrlimit(&self, resource: Resource) -> Result<LimitPair> {
588 self.inner.getrlimit(resource)
589 }
590}
591
592impl<S> SetRlimit for Concurrent<S>
593where
594 S: SetRlimit + Sigmask,
595{
596 #[inline]
597 fn setrlimit(&self, resource: Resource, limits: LimitPair) -> Result<()> {
598 self.inner.setrlimit(resource, limits)
599 }
600}