@@ -206,6 +206,10 @@ bitflags! {
206206
207207bitflags ! {
208208 /// The permissions a process has on memory map entries.
209+ ///
210+ /// Note that the `SHARED` and `PRIVATE` are mutually exclusive, so while you can
211+ /// use `MMPermissions::all()` to construct an instance that has all bits set,
212+ /// this particular value would never been seen in procfs.
209213 #[ derive( Default ) ]
210214 #[ cfg_attr( feature = "serde1" , derive( Serialize , Deserialize ) ) ]
211215 pub struct MMPermissions : u8 {
@@ -239,6 +243,26 @@ impl MMPermissions {
239243 _ => Self :: NONE ,
240244 }
241245 }
246+ /// Returns this permission map as a 4-character string, similar to what you
247+ /// might see in `/proc/\<pid\>/maps`.
248+ ///
249+ /// Note that the SHARED and PRIVATE bits are mutually exclusive, so this
250+ /// string is 4 characters long, not 5.
251+ pub fn as_str ( & self ) -> String {
252+ let mut s = String :: with_capacity ( 4 ) ;
253+ s. push ( if self . contains ( Self :: READ ) { 'r' } else { '-' } ) ;
254+ s. push ( if self . contains ( Self :: WRITE ) { 'w' } else { '-' } ) ;
255+ s. push ( if self . contains ( Self :: EXECUTE ) { 'x' } else { '-' } ) ;
256+ s. push ( if self . contains ( Self :: SHARED ) {
257+ 's'
258+ } else if self . contains ( Self :: PRIVATE ) {
259+ 'p'
260+ } else {
261+ '-'
262+ } ) ;
263+
264+ s
265+ }
242266}
243267
244268impl FromStr for MMPermissions {
@@ -1767,5 +1791,9 @@ mod tests {
17671791 assert_eq ! ( "rw-p" . parse( ) , Ok ( P :: READ | P :: WRITE | P :: PRIVATE ) ) ;
17681792 assert_eq ! ( "r-xs" . parse( ) , Ok ( P :: READ | P :: EXECUTE | P :: SHARED ) ) ;
17691793 assert_eq ! ( "----" . parse( ) , Ok ( P :: NONE ) ) ;
1794+
1795+ assert_eq ! ( ( P :: READ | P :: WRITE | P :: PRIVATE ) . as_str( ) , "rw-p" ) ;
1796+ assert_eq ! ( ( P :: READ | P :: EXECUTE | P :: SHARED ) . as_str( ) , "r-xs" ) ;
1797+ assert_eq ! ( P :: NONE . as_str( ) , "----" ) ;
17701798 }
17711799}
0 commit comments