1
1
//! Tests for the `pidfd` type.
2
2
3
- use libc:: { kill, SIGSTOP } ;
3
+ use libc:: { kill, SIGCONT , SIGINT , SIGSTOP } ;
4
4
#[ cfg( feature = "event" ) ]
5
5
use rustix:: event;
6
6
use rustix:: fd:: AsFd as _;
@@ -24,7 +24,7 @@ fn test_pidfd_waitid() {
24
24
Ok ( pidfd) => pidfd,
25
25
Err ( io:: Errno :: NOSYS ) => {
26
26
// The kernel does not support pidfds.
27
- unsafe { kill ( child. id ( ) as _ , SIGSTOP ) } ;
27
+ unsafe { kill ( child. id ( ) as _ , SIGINT ) } ;
28
28
return ;
29
29
}
30
30
Err ( e) => panic ! ( "failed to open pidfd: {}" , e) ,
@@ -40,8 +40,154 @@ fn test_pidfd_waitid() {
40
40
. expect ( "failed to wait" )
41
41
. unwrap ( ) ;
42
42
43
- // TODO
44
- let _ = status;
43
+ assert ! ( status. stopped( ) ) ;
44
+ assert ! ( !status. exited( ) ) ;
45
+ assert ! ( !status. killed( ) ) ;
46
+ assert ! ( !status. trapped( ) ) ;
47
+ assert ! ( !status. dumped( ) ) ;
48
+ assert ! ( !status. continued( ) ) ;
49
+
50
+ assert_eq ! (
51
+ status. stopping_signal( ) ,
52
+ Some ( process:: Signal :: STOP . as_raw( ) )
53
+ ) ;
54
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
55
+ assert_eq ! ( status. exit_status( ) , None ) ;
56
+ assert_eq ! ( status. terminating_signal( ) , None ) ;
57
+
58
+ unsafe { kill ( child. id ( ) as _ , SIGCONT ) } ;
59
+
60
+ let status = process:: waitid (
61
+ process:: WaitId :: PidFd ( pidfd. as_fd ( ) ) ,
62
+ process:: WaitIdOptions :: CONTINUED ,
63
+ )
64
+ . expect ( "failed to wait" )
65
+ . unwrap ( ) ;
66
+
67
+ assert ! ( !status. stopped( ) ) ;
68
+ assert ! ( !status. exited( ) ) ;
69
+ assert ! ( !status. killed( ) ) ;
70
+ assert ! ( !status. trapped( ) ) ;
71
+ assert ! ( !status. dumped( ) ) ;
72
+ assert ! ( status. continued( ) ) ;
73
+
74
+ assert_eq ! ( status. stopping_signal( ) , None ) ;
75
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
76
+ assert_eq ! ( status. exit_status( ) , None ) ;
77
+ assert_eq ! ( status. terminating_signal( ) , None ) ;
78
+
79
+ unsafe { kill ( child. id ( ) as _ , SIGINT ) } ;
80
+
81
+ let status = process:: waitid (
82
+ process:: WaitId :: PidFd ( pidfd. as_fd ( ) ) ,
83
+ process:: WaitIdOptions :: EXITED ,
84
+ )
85
+ . expect ( "failed to wait" )
86
+ . unwrap ( ) ;
87
+
88
+ assert ! ( !status. stopped( ) ) ;
89
+ assert ! ( !status. exited( ) ) ;
90
+ assert ! ( status. killed( ) ) ;
91
+ assert ! ( !status. trapped( ) ) ;
92
+ assert ! ( !status. dumped( ) ) ;
93
+ assert ! ( !status. continued( ) ) ;
94
+
95
+ assert_eq ! ( status. stopping_signal( ) , None ) ;
96
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
97
+ assert_eq ! ( status. exit_status( ) , None ) ;
98
+ assert_eq ! ( status. terminating_signal( ) , Some ( SIGINT ) ) ;
99
+ }
100
+
101
+ // Similar to `test_pidfd_waitid`, but use `pidfd_send_signal` to send the
102
+ // signals.
103
+ #[ test]
104
+ #[ serial]
105
+ fn test_pidfd_send_signal ( ) {
106
+ // Create a new process.
107
+ let child = Command :: new ( "yes" )
108
+ . stdout ( std:: process:: Stdio :: null ( ) )
109
+ . stderr ( std:: process:: Stdio :: null ( ) )
110
+ . spawn ( )
111
+ . expect ( "failed to execute child" ) ;
112
+
113
+ // Create a pidfd for the child process.
114
+ let pid = process:: Pid :: from_child ( & child) ;
115
+ let pidfd = match process:: pidfd_open ( pid, process:: PidfdFlags :: empty ( ) ) {
116
+ Ok ( pidfd) => pidfd,
117
+ Err ( io:: Errno :: NOSYS ) => {
118
+ // The kernel does not support pidfds.
119
+ process:: kill_process ( process:: Pid :: from_child ( & child) , process:: Signal :: INT ) . unwrap ( ) ;
120
+ return ;
121
+ }
122
+ Err ( e) => panic ! ( "failed to open pidfd: {}" , e) ,
123
+ } ;
124
+
125
+ // Wait for the child process to stop.
126
+ process:: pidfd_send_signal ( & pidfd, process:: Signal :: STOP ) . unwrap ( ) ;
127
+
128
+ let status = process:: waitid (
129
+ process:: WaitId :: PidFd ( pidfd. as_fd ( ) ) ,
130
+ process:: WaitIdOptions :: STOPPED ,
131
+ )
132
+ . expect ( "failed to wait" )
133
+ . unwrap ( ) ;
134
+
135
+ assert ! ( status. stopped( ) ) ;
136
+ assert ! ( !status. exited( ) ) ;
137
+ assert ! ( !status. killed( ) ) ;
138
+ assert ! ( !status. trapped( ) ) ;
139
+ assert ! ( !status. dumped( ) ) ;
140
+ assert ! ( !status. continued( ) ) ;
141
+
142
+ assert_eq ! (
143
+ status. stopping_signal( ) ,
144
+ Some ( process:: Signal :: STOP . as_raw( ) )
145
+ ) ;
146
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
147
+ assert_eq ! ( status. exit_status( ) , None ) ;
148
+ assert_eq ! ( status. terminating_signal( ) , None ) ;
149
+
150
+ process:: pidfd_send_signal ( & pidfd, process:: Signal :: CONT ) . unwrap ( ) ;
151
+
152
+ let status = process:: waitid (
153
+ process:: WaitId :: PidFd ( pidfd. as_fd ( ) ) ,
154
+ process:: WaitIdOptions :: CONTINUED ,
155
+ )
156
+ . expect ( "failed to wait" )
157
+ . unwrap ( ) ;
158
+
159
+ assert ! ( !status. stopped( ) ) ;
160
+ assert ! ( !status. exited( ) ) ;
161
+ assert ! ( !status. killed( ) ) ;
162
+ assert ! ( !status. trapped( ) ) ;
163
+ assert ! ( !status. dumped( ) ) ;
164
+ assert ! ( status. continued( ) ) ;
165
+
166
+ assert_eq ! ( status. stopping_signal( ) , None ) ;
167
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
168
+ assert_eq ! ( status. exit_status( ) , None ) ;
169
+ assert_eq ! ( status. terminating_signal( ) , None ) ;
170
+
171
+ process:: pidfd_send_signal ( & pidfd, process:: Signal :: INT ) . unwrap ( ) ;
172
+
173
+ let status = process:: waitid (
174
+ process:: WaitId :: PidFd ( pidfd. as_fd ( ) ) ,
175
+ process:: WaitIdOptions :: EXITED ,
176
+ )
177
+ . expect ( "failed to wait" )
178
+ . unwrap ( ) ;
179
+
180
+ assert ! ( !status. stopped( ) ) ;
181
+ assert ! ( !status. exited( ) ) ;
182
+ assert ! ( status. killed( ) ) ;
183
+ assert ! ( !status. trapped( ) ) ;
184
+ assert ! ( !status. dumped( ) ) ;
185
+ assert ! ( !status. continued( ) ) ;
186
+
187
+ assert_eq ! ( status. stopping_signal( ) , None ) ;
188
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
189
+ assert_eq ! ( status. exit_status( ) , None ) ;
190
+ assert_eq ! ( status. terminating_signal( ) , Some ( SIGINT ) ) ;
45
191
}
46
192
47
193
#[ cfg( feature = "event" ) ]
@@ -62,6 +208,7 @@ fn test_pidfd_poll() {
62
208
Ok ( pidfd) => pidfd,
63
209
Err ( io:: Errno :: NOSYS ) | Err ( io:: Errno :: INVAL ) => {
64
210
// The kernel does not support non-blocking pidfds.
211
+ process:: kill_process ( process:: Pid :: from_child ( & child) , process:: Signal :: INT ) . unwrap ( ) ;
65
212
return ;
66
213
}
67
214
Err ( e) => panic ! ( "failed to open pidfd: {}" , e) ,
@@ -89,6 +236,15 @@ fn test_pidfd_poll() {
89
236
. expect ( "failed to wait" )
90
237
. unwrap ( ) ;
91
238
92
- // TODO
93
- let _ = status;
239
+ assert ! ( !status. stopped( ) ) ;
240
+ assert ! ( status. exited( ) ) ;
241
+ assert ! ( !status. killed( ) ) ;
242
+ assert ! ( !status. trapped( ) ) ;
243
+ assert ! ( !status. dumped( ) ) ;
244
+ assert ! ( !status. continued( ) ) ;
245
+
246
+ assert_eq ! ( status. stopping_signal( ) , None ) ;
247
+ assert_eq ! ( status. trapping_signal( ) , None ) ;
248
+ assert_eq ! ( status. exit_status( ) , Some ( 0 ) ) ;
249
+ assert_eq ! ( status. terminating_signal( ) , None ) ;
94
250
}
0 commit comments