@@ -12,8 +12,6 @@ use std::os::unix::prelude::*;
12
12
use crate :: errno:: Errno ;
13
13
#[ cfg( not( target_os = "aix" ) ) ]
14
14
use crate :: sys:: termios:: Termios ;
15
- #[ cfg( feature = "process" ) ]
16
- use crate :: unistd:: ForkResult ;
17
15
#[ cfg( all( feature = "process" , not( target_os = "aix" ) ) ) ]
18
16
use crate :: unistd:: Pid ;
19
17
use crate :: { fcntl, unistd, Result } ;
@@ -31,15 +29,19 @@ pub struct OpenptyResult {
31
29
32
30
feature ! {
33
31
#![ feature = "process" ]
34
- /// Representation of a master with a forked pty
35
- ///
36
- /// This is returned by [`forkpty`].
32
+ /// A successful result of [`forkpty()`].
37
33
#[ derive( Debug ) ]
38
- pub struct ForkptyResult {
39
- /// The master port in a virtual pty pair
40
- pub master: OwnedFd ,
41
- /// Metadata about forked process
42
- pub fork_result: ForkResult ,
34
+ pub enum ForkptyResult {
35
+ /// This is the parent process of the underlying fork.
36
+ Parent {
37
+ /// The PID of the fork's child process
38
+ child: Pid ,
39
+ /// A file descriptor referring to master side of the pseudoterminal of
40
+ /// the child process.
41
+ master: OwnedFd ,
42
+ } ,
43
+ /// This is the child process of the underlying fork.
44
+ Child ,
43
45
}
44
46
}
45
47
@@ -300,9 +302,7 @@ pub fn openpty<
300
302
301
303
feature ! {
302
304
#![ feature = "process" ]
303
- /// Create a new pseudoterminal, returning the master file descriptor and forked pid.
304
- /// in `ForkptyResult`
305
- /// (see [`forkpty`](https://man7.org/linux/man-pages/man3/forkpty.3.html)).
305
+ /// Create a new process operating in a pseudoterminal.
306
306
///
307
307
/// If `winsize` is not `None`, the window size of the slave will be set to
308
308
/// the values in `winsize`. If `termios` is not `None`, the pseudoterminal's
@@ -319,6 +319,11 @@ feature! {
319
319
/// special care must be taken to only invoke code you can control and audit.
320
320
///
321
321
/// [async-signal-safe]: https://man7.org/linux/man-pages/man7/signal-safety.7.html
322
+ ///
323
+ /// # Reference
324
+ ///
325
+ /// * [FreeBSD](https://man.freebsd.org/cgi/man.cgi?query=forkpty)
326
+ /// * [Linux](https://man7.org/linux/man-pages/man3/forkpty.3.html)
322
327
#[ cfg( not( target_os = "aix" ) ) ]
323
328
pub unsafe fn forkpty<' a, ' b, T : Into <Option <& ' a Winsize >>, U : Into <Option <& ' b Termios >>>(
324
329
winsize: T ,
@@ -343,14 +348,23 @@ pub unsafe fn forkpty<'a, 'b, T: Into<Option<&'a Winsize>>, U: Into<Option<&'b T
343
348
344
349
let res = unsafe { libc:: forkpty( master. as_mut_ptr( ) , ptr:: null_mut( ) , term, win) } ;
345
350
346
- let fork_result = Errno :: result( res) . map( |res| match res {
347
- 0 => ForkResult :: Child ,
348
- res => ForkResult :: Parent { child: Pid :: from_raw( res) } ,
349
- } ) ?;
351
+ let success_ret = Errno :: result( res) ?;
352
+ let forkpty_result = match success_ret {
353
+ // In the child process
354
+ 0 => ForkptyResult :: Child ,
355
+ // In the parent process
356
+ child_pid => {
357
+ // SAFETY:
358
+ // 1. The master buffer is guaranteed to be initialized in the parent process
359
+ // 2. OwnedFd::from_raw_fd won't panic as the fd is a valid file descriptor
360
+ let master = unsafe { OwnedFd :: from_raw_fd( master. assume_init( ) ) } ;
361
+ ForkptyResult :: Parent {
362
+ master,
363
+ child: Pid :: from_raw( child_pid) ,
364
+ }
365
+ }
366
+ } ;
350
367
351
- Ok ( ForkptyResult {
352
- master: unsafe { OwnedFd :: from_raw_fd( master. assume_init( ) ) } ,
353
- fork_result,
354
- } )
368
+ Ok ( forkpty_result)
355
369
}
356
370
}
0 commit comments