@@ -11,12 +11,17 @@ use std::os::unix::fs as unix_fs;
11
11
use std:: os:: unix:: fs:: PermissionsExt ;
12
12
use std:: fs;
13
13
use std:: io:: ErrorKind ;
14
+ use std:: sync:: Mutex ;
14
15
use config:: PinConfig ;
15
16
use nix:: unistd:: { chown, Gid , Uid } ;
16
17
use sysfs_gpio;
17
- use users:: { get_user_by_name , get_group_by_name } ;
18
+ use users:: { UsersCache , Groups , Users } ;
18
19
use error:: * ;
19
20
21
+ lazy_static ! {
22
+ static ref USERS_CACHE : Mutex <UsersCache > = Mutex :: new( UsersCache :: new( ) ) ;
23
+ }
24
+
20
25
/// Unexport the pin specified in the provided config
21
26
///
22
27
/// Unexporting a config (in this context) involves a few different
@@ -69,32 +74,54 @@ pub fn unexport(pin_config: &PinConfig,
69
74
/// without an error as the desired end state is achieved.
70
75
pub fn export ( pin_config : & PinConfig , symlink_root : Option < & str > ) -> Result < ( ) > {
71
76
let pin = pin_config. get_pin ( ) ;
72
- try! ( pin. export ( ) ) ;
77
+ pin. export ( ) ? ;
73
78
74
- // change user, group, mode for files in gpio directory
75
- for entry in fs:: read_dir ( format ! ( "/sys/class/gpio/gpio{}" , & pin_config. num) ) ? {
76
- let e = entry?;
77
- let metadata = e. metadata ( ) ?;
79
+ let uid = if let Some ( username) = pin_config. user . as_ref ( ) {
80
+ Some (
81
+ USERS_CACHE
82
+ . lock ( )
83
+ . unwrap ( )
84
+ . get_user_by_name ( username)
85
+ . map ( |u| Uid :: from_raw ( u. uid ( ) ) )
86
+ . ok_or_else ( || format ! ( "Unable to find user {:?}" , username) ) ?,
87
+ )
88
+ } else {
89
+ None
90
+ } ;
78
91
79
- let user = pin_config. user . as_ref ( ) . and_then ( |username| get_user_by_name ( username) ) ;
80
- let group = pin_config. group . as_ref ( ) . and_then ( |groupname| get_group_by_name ( groupname) ) ;
92
+ let gid = if let Some ( groupname) = pin_config. group . as_ref ( ) {
93
+ Some (
94
+ USERS_CACHE
95
+ . lock ( )
96
+ . unwrap ( )
97
+ . get_group_by_name ( groupname)
98
+ . map ( |g| Gid :: from_raw ( g. gid ( ) ) )
99
+ . ok_or_else ( || format ! ( "Unable to find group {:?}" , groupname) ) ?,
100
+ )
101
+ } else {
102
+ None
103
+ } ;
81
104
82
- if metadata. is_file ( ) {
83
- if user. is_some ( ) && group. is_some ( ) {
84
- chown ( e. path ( ) . as_path ( ) ,
85
- user. as_ref ( ) . map ( |u| Uid :: from_raw ( u. uid ( ) ) ) ,
86
- group. as_ref ( ) . map ( |g| Gid :: from_raw ( g. gid ( ) ) ) ) ?;
87
- }
105
+ // change user, group, mode for files in gpio directory
106
+ if uid. is_some ( ) || gid. is_some ( ) || pin_config. mode . is_some ( ) {
107
+ for entry in fs:: read_dir ( format ! ( "/sys/class/gpio/gpio{}" , & pin_config. num) ) ? {
108
+ let e = entry?;
109
+ let metadata = e. metadata ( ) ?;
88
110
89
- if let Some ( mode) = pin_config. mode {
90
- let mut permissions = metadata. permissions ( ) ;
91
- permissions. set_mode ( mode) ;
92
- fs:: set_permissions ( e. path ( ) . as_path ( ) , permissions) ?;
111
+ if metadata. is_file ( ) {
112
+ if uid. is_some ( ) || gid. is_some ( ) {
113
+ chown ( e. path ( ) . as_path ( ) , uid, gid) ?;
114
+ }
115
+
116
+ if let Some ( mode) = pin_config. mode {
117
+ let mut permissions = metadata. permissions ( ) ;
118
+ permissions. set_mode ( mode) ;
119
+ fs:: set_permissions ( e. path ( ) . as_path ( ) , permissions) ?;
120
+ }
93
121
}
94
122
}
95
123
}
96
124
97
-
98
125
// if there is a symlink root provided, create symlink
99
126
if let Some ( symroot) = symlink_root {
100
127
// create root directory if not exists
0 commit comments