@@ -30,7 +30,7 @@ fn test_existing_pid() {
3030 . succeeds ( )
3131 . stdout_move_str ( ) ;
3232
33- assert_format ( pid, & result) ;
33+ assert_format ( pid, & result, false ) ;
3434}
3535
3636#[ test]
@@ -50,8 +50,8 @@ fn test_multiple_existing_pids() {
5050 let pos_second_pid = result. iter ( ) . rposition ( |line| re. is_match ( line) ) . unwrap ( ) ;
5151 let ( left, right) = result. split_at ( pos_second_pid) ;
5252
53- assert_format ( pid, & left. join ( "\n " ) ) ;
54- assert_format ( pid, & right. join ( "\n " ) ) ;
53+ assert_format ( pid, & left. join ( "\n " ) , false ) ;
54+ assert_format ( pid, & right. join ( "\n " ) , false ) ;
5555}
5656
5757#[ test]
@@ -65,7 +65,7 @@ fn test_non_existing_and_existing_pid() {
6565 . fails ( ) ;
6666 let result = result. code_is ( 42 ) . no_stderr ( ) . stdout_str ( ) ;
6767
68- assert_format ( pid, result) ;
68+ assert_format ( pid, result, false ) ;
6969}
7070
7171#[ test]
@@ -103,7 +103,7 @@ fn test_extended() {
103103 . succeeds ( )
104104 . stdout_move_str ( ) ;
105105
106- assert_extended_format ( pid, & result) ;
106+ assert_extended_format ( pid, & result, false ) ;
107107 }
108108}
109109
@@ -119,7 +119,7 @@ fn test_more_extended() {
119119 . succeeds ( )
120120 . stdout_move_str ( ) ;
121121
122- assert_more_extended_format ( pid, & result) ;
122+ assert_more_extended_format ( pid, & result, false ) ;
123123}
124124
125125#[ test]
@@ -134,7 +134,7 @@ fn test_most_extended() {
134134 . succeeds ( )
135135 . stdout_move_str ( ) ;
136136
137- assert_most_extended_format ( pid, & result) ;
137+ assert_most_extended_format ( pid, & result, false ) ;
138138}
139139
140140#[ test]
@@ -166,7 +166,7 @@ fn test_device() {
166166 . succeeds ( )
167167 . stdout_move_str ( ) ;
168168
169- assert_device_format ( pid, & result) ;
169+ assert_device_format ( pid, & result, false ) ;
170170 }
171171}
172172
@@ -187,6 +187,63 @@ fn test_device_permission_denied() {
187187 }
188188}
189189
190+ #[ test]
191+ #[ cfg( target_os = "linux" ) ]
192+ fn test_showpath ( ) {
193+ let pid = process:: id ( ) ;
194+
195+ for arg in [ "-p" , "--show-path" ] {
196+ // default format
197+ let result = new_ucmd ! ( )
198+ . arg ( arg)
199+ . arg ( pid. to_string ( ) )
200+ . succeeds ( )
201+ . stdout_move_str ( ) ;
202+
203+ assert_format ( pid, & result, true ) ;
204+
205+ // extended format
206+ let result = new_ucmd ! ( )
207+ . arg ( arg)
208+ . arg ( "--extended" )
209+ . arg ( pid. to_string ( ) )
210+ . succeeds ( )
211+ . stdout_move_str ( ) ;
212+
213+ assert_extended_format ( pid, & result, true ) ;
214+
215+ // more-extended format
216+ let result = new_ucmd ! ( )
217+ . arg ( arg)
218+ . arg ( "-X" )
219+ . arg ( pid. to_string ( ) )
220+ . succeeds ( )
221+ . stdout_move_str ( ) ;
222+
223+ assert_more_extended_format ( pid, & result, true ) ;
224+
225+ // most-extended format
226+ let result = new_ucmd ! ( )
227+ . arg ( arg)
228+ . arg ( "--XX" )
229+ . arg ( pid. to_string ( ) )
230+ . succeeds ( )
231+ . stdout_move_str ( ) ;
232+
233+ assert_most_extended_format ( pid, & result, true ) ;
234+
235+ // device format
236+ let result = new_ucmd ! ( )
237+ . arg ( arg)
238+ . arg ( "--device" )
239+ . arg ( pid. to_string ( ) )
240+ . succeeds ( )
241+ . stdout_move_str ( ) ;
242+
243+ assert_device_format ( pid, & result, true ) ;
244+ }
245+ }
246+
190247#[ test]
191248fn test_invalid_arg ( ) {
192249 new_ucmd ! ( ) . arg ( "--definitely-invalid" ) . fails ( ) . code_is ( 1 ) ;
@@ -211,14 +268,20 @@ fn assert_cmdline_only(pid: &str, s: &str) {
211268// ...
212269// total 1040320K
213270#[ cfg( target_os = "linux" ) ]
214- fn assert_format ( pid : u32 , s : & str ) {
271+ fn assert_format ( pid : u32 , s : & str , show_path : bool ) {
215272 let ( first_line, rest) = s. split_once ( '\n' ) . unwrap ( ) ;
216273 let re = Regex :: new ( & format ! ( "^{pid}: .+[^ ]$" ) ) . unwrap ( ) ;
217274 assert ! ( re. is_match( first_line) ) ;
218275
219276 let rest = rest. trim_end ( ) ;
220277 let ( memory_map, last_line) = rest. rsplit_once ( '\n' ) . unwrap ( ) ;
221- let re = Regex :: new ( r"(?m)^[0-9a-f]{16} +[1-9][0-9]*K (-|r)(-|w)(-|x)(-|s)- ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$" ) . unwrap ( ) ;
278+ let base_pattern = r"(?m)^[0-9a-f]{16} +[1-9][0-9]*K (-|r)(-|w)(-|x)(-|s)-" ;
279+ let mapping_pattern = if show_path {
280+ r" ( \[ (anon|stack) \]|/[/a-zA-Z0-9._-]+)$"
281+ } else {
282+ r" ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$"
283+ } ;
284+ let re = Regex :: new ( & format ! ( "{base_pattern}{mapping_pattern}" ) ) . unwrap ( ) ;
222285 assert ! ( re. is_match( memory_map) ) ;
223286
224287 let re = Regex :: new ( "^ total +[1-9][0-9]*K$" ) . unwrap ( ) ;
@@ -236,7 +299,7 @@ fn assert_format(pid: u32, s: &str) {
236299// ---------------- ------- ------- ------- (one intentional trailing space)
237300// total kB 144 7 14
238301#[ cfg( target_os = "linux" ) ]
239- fn assert_extended_format ( pid : u32 , s : & str ) {
302+ fn assert_extended_format ( pid : u32 , s : & str , show_path : bool ) {
240303 let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
241304 let line_count = lines. len ( ) ;
242305
@@ -246,10 +309,13 @@ fn assert_extended_format(pid: u32, s: &str) {
246309 let expected_header = "Address Kbytes RSS Dirty Mode Mapping" ;
247310 assert_eq ! ( expected_header, lines[ 1 ] , "failing line: '{}'" , lines[ 1 ] ) ;
248311
249- let re = Regex :: new (
250- r"^[0-9a-f]{16} +[1-9][0-9]* +\d+ +\d+ (-|r)(-|w)(-|x)(-|s)- ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$" ,
251- )
252- . unwrap ( ) ;
312+ let base_pattern = r"^[0-9a-f]{16} +[1-9][0-9]* +\d+ +\d+ (-|r)(-|w)(-|x)(-|s)-" ;
313+ let mapping_pattern = if show_path {
314+ r" ( \[ (anon|stack) \]|/[/a-zA-Z0-9._-]+)$"
315+ } else {
316+ r" ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$"
317+ } ;
318+ let re = Regex :: new ( & format ! ( "{base_pattern}{mapping_pattern}" ) ) . unwrap ( ) ;
253319
254320 for line in lines. iter ( ) . take ( line_count - 2 ) . skip ( 2 ) {
255321 assert ! ( re. is_match( line) , "failing line: '{line}'" ) ;
@@ -282,7 +348,7 @@ fn assert_extended_format(pid: u32, s: &str) {
282348// ==== ==== ==== ========= ========== ========= ======== ============== ============= ============== =============== ==== ======= ====== =========== (one intentional trailing space)
283349// 4164 3448 2826 552 3448 552 0 0 0 0 0 0 0 0 0 KB (one intentional trailing space)
284350#[ cfg( target_os = "linux" ) ]
285- fn assert_more_extended_format ( pid : u32 , s : & str ) {
351+ fn assert_more_extended_format ( pid : u32 , s : & str , show_path : bool ) {
286352 let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
287353 let line_count = lines. len ( ) ;
288354
@@ -292,7 +358,13 @@ fn assert_more_extended_format(pid: u32, s: &str) {
292358 let re = Regex :: new ( r"^ Address Perm Offset Device Inode +Size +Rss +Pss +Pss_Dirty +Referenced +Anonymous( +KSM)? +LazyFree +ShmemPmdMapped +FilePmdMapped +Shared_Hugetlb +Private_Hugetlb +Swap +SwapPss +Locked +THPeligible( +ProtectionKey)? +Mapping$" ) . unwrap ( ) ;
293359 assert ! ( re. is_match( lines[ 1 ] ) , "failing line: '{}'" , lines[ 1 ] ) ;
294360
295- let re = Regex :: new ( r"^[0-9a-f]{16} (-|r)(-|w)(-|x)(p|s) [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5} +\d+ +[1-9][0-9]* +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? (|\[[a-zA-Z_ ]+\]|[a-zA-Z0-9._-]+)$" ) . unwrap ( ) ;
361+ let base_pattern = r"^[0-9a-f]{16} (-|r)(-|w)(-|x)(p|s) [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5} +\d+ +[1-9][0-9]* +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)?" ;
362+ let mapping_pattern = if show_path {
363+ r" (|\[[a-zA-Z_ ]+\]|/[/a-zA-Z0-9._-]+)$"
364+ } else {
365+ r" (|\[[a-zA-Z_ ]+\]|[a-zA-Z0-9._-]+)$"
366+ } ;
367+ let re = Regex :: new ( & format ! ( "{base_pattern}{mapping_pattern}" ) ) . unwrap ( ) ;
296368
297369 for line in lines. iter ( ) . take ( line_count - 2 ) . skip ( 2 ) {
298370 assert ! ( re. is_match( line) , "failing line: '{line}'" ) ;
@@ -324,7 +396,7 @@ fn assert_more_extended_format(pid: u32, s: &str) {
324396// ==== ============== =========== ==== ==== ========= ============ ============ ============= ============= ========== ========= ======== ============= ============== ============= ============== =============== ==== ======= ====== =========== (one intentional trailing space)
325397// 4164 92 92 3448 2880 552 1132 0 1764 552 3448 552 0 0 0 0 0 0 0 0 0 0 KB (one intentional trailing space)
326398#[ cfg( target_os = "linux" ) ]
327- fn assert_most_extended_format ( pid : u32 , s : & str ) {
399+ fn assert_most_extended_format ( pid : u32 , s : & str , show_path : bool ) {
328400 let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
329401 let line_count = lines. len ( ) ;
330402
@@ -334,7 +406,13 @@ fn assert_most_extended_format(pid: u32, s: &str) {
334406 let re = Regex :: new ( r"^ Address Perm Offset Device Inode +Size +KernelPageSize +MMUPageSize +Rss +Pss +Pss_Dirty +Shared_Clean +Shared_Dirty +Private_Clean +Private_Dirty +Referenced +Anonymous( +KSM)? +LazyFree +AnonHugePages +ShmemPmdMapped +FilePmdMapped +Shared_Hugetlb +Private_Hugetlb +Swap +SwapPss +Locked +THPeligible( +ProtectionKey)? +VmFlags +Mapping$" ) . unwrap ( ) ;
335407 assert ! ( re. is_match( lines[ 1 ] ) , "failing line: '{}'" , lines[ 1 ] ) ;
336408
337- let re = Regex :: new ( r"^[0-9a-f]{16} (-|r)(-|w)(-|x)(p|s) [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5} +\d+ +[1-9][0-9]* +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +([a-z][a-z] )*(|\[[a-zA-Z_ ]+\]|[a-zA-Z0-9._-]+)$" ) . unwrap ( ) ;
409+ let base_pattern = r"^[0-9a-f]{16} (-|r)(-|w)(-|x)(p|s) [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5} +\d+ +[1-9][0-9]* +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+ +\d+( +\d+)? +([a-z][a-z] )*" ;
410+ let mapping_pattern = if show_path {
411+ r"(|\[[a-zA-Z_ ]+\]|/[/a-zA-Z0-9._-]+)$"
412+ } else {
413+ r"(|\[[a-zA-Z_ ]+\]|[a-zA-Z0-9._-]+)$"
414+ } ;
415+ let re = Regex :: new ( & format ! ( "{base_pattern}{mapping_pattern}" ) ) . unwrap ( ) ;
338416
339417 for line in lines. iter ( ) . take ( line_count - 2 ) . skip ( 2 ) {
340418 assert ! ( re. is_match( line) , "failing line: '{line}'" ) ;
@@ -365,7 +443,7 @@ fn assert_most_extended_format(pid: u32, s: &str) {
365443// ...
366444// mapped: 3060K writeable/private: 348K shared: 0K
367445#[ cfg( target_os = "linux" ) ]
368- fn assert_device_format ( pid : u32 , s : & str ) {
446+ fn assert_device_format ( pid : u32 , s : & str , show_path : bool ) {
369447 let lines: Vec < _ > = s. lines ( ) . collect ( ) ;
370448 let line_count = lines. len ( ) ;
371449
@@ -375,10 +453,14 @@ fn assert_device_format(pid: u32, s: &str) {
375453 let expected_header = "Address Kbytes Mode Offset Device Mapping" ;
376454 assert_eq ! ( expected_header, lines[ 1 ] ) ;
377455
378- let re = Regex :: new (
379- r"^[0-9a-f]{16} +[1-9][0-9]* (-|r)(-|w)(-|x)(-|s)- [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5} ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$" ,
380- )
381- . unwrap ( ) ;
456+ let base_pattern =
457+ r"^[0-9a-f]{16} +[1-9][0-9]* (-|r)(-|w)(-|x)(-|s)- [0-9a-f]{16} [0-9a-f]{3}:[0-9a-f]{5}" ;
458+ let mapping_pattern = if show_path {
459+ r" ( \[ (anon|stack) \]|/[/a-zA-Z0-9._-]+)$"
460+ } else {
461+ r" ( \[ (anon|stack) \]|[a-zA-Z0-9._-]+)$"
462+ } ;
463+ let re = Regex :: new ( & format ! ( "{base_pattern}{mapping_pattern}" ) ) . unwrap ( ) ;
382464
383465 for line in lines. iter ( ) . take ( line_count - 1 ) . skip ( 2 ) {
384466 assert ! ( re. is_match( line) , "failing line: {line}" ) ;
0 commit comments