@@ -62,13 +62,14 @@ fn test_command_fork_no_unwind() {
6262}
6363
6464#[ test]
65- #[ cfg( target_os = "linux" ) ]
65+ #[ cfg( target_os = "linux" ) ] // pidfds are a linux-specific concept
6666fn test_command_pidfd ( ) {
6767 use crate :: assert_matches:: assert_matches;
6868 use crate :: os:: fd:: { AsRawFd , RawFd } ;
6969 use crate :: os:: linux:: process:: { ChildExt , CommandExt } ;
7070 use crate :: process:: Command ;
7171
72+ // pidfds require the pidfd_open syscall
7273 let our_pid = crate :: process:: id ( ) ;
7374 let pidfd = unsafe { libc:: syscall ( libc:: SYS_pidfd_open , our_pid, 0 ) } ;
7475 let pidfd_open_available = if pidfd >= 0 {
@@ -81,7 +82,9 @@ fn test_command_pidfd() {
8182 // always exercise creation attempts
8283 let mut child = Command :: new ( "false" ) . create_pidfd ( true ) . spawn ( ) . unwrap ( ) ;
8384
84- // but only check if we know that the kernel supports pidfds
85+ // but only check if we know that the kernel supports pidfds.
86+ // We don't assert the precise value, since the standard library
87+ // might have opened other file descriptors before our code runs.
8588 if pidfd_open_available {
8689 assert ! ( child. pidfd( ) . is_ok( ) ) ;
8790 }
@@ -97,4 +100,17 @@ fn test_command_pidfd() {
97100 child. kill ( ) . expect ( "failed to kill child" ) ;
98101 let status = child. wait ( ) . expect ( "error waiting on pidfd" ) ;
99102 assert_eq ! ( status. signal( ) , Some ( libc:: SIGKILL ) ) ;
103+
104+ let _ = Command :: new ( "echo" )
105+ . create_pidfd ( false )
106+ . spawn ( )
107+ . unwrap ( )
108+ . pidfd ( )
109+ . expect_err ( "pidfd should not have been created when create_pid(false) is set" ) ;
110+
111+ let _ = Command :: new ( "echo" )
112+ . spawn ( )
113+ . unwrap ( )
114+ . pidfd ( )
115+ . expect_err ( "pidfd should not have been created" ) ;
100116}
0 commit comments