@@ -135,6 +135,70 @@ extension Platform {
135
135
}
136
136
return result
137
137
}
138
+
139
+ #if canImport(Darwin)
140
+ typealias Operation < Input, Output> = ( Input , UnsafeMutablePointer < Output > ? , UnsafeMutablePointer < CChar > ? , Int , UnsafeMutablePointer < UnsafeMutablePointer < Output > ? > ? ) -> Int32
141
+ #else
142
+ typealias Operation < Input, Output> = ( Input , UnsafeMutablePointer < Output > , UnsafeMutablePointer < CChar > , Int , UnsafeMutablePointer < UnsafeMutablePointer < Output > ? > ) -> Int32
143
+ #endif
144
+
145
+ private static func withUserGroupBuffer< Input, Output, R> ( _ input: Input , _ output: Output , sizeProperty: Int32 , operation: Operation < Input , Output > , block: ( Output ) throws -> R ) rethrows -> R ? {
146
+ var bufferLen = sysconf ( sizeProperty)
147
+ if bufferLen == - 1 {
148
+ bufferLen = 4096 // Generous default size estimate
149
+ }
150
+ return try withUnsafeTemporaryAllocation ( of: CChar . self, capacity: bufferLen) {
151
+ var result = output
152
+ var ptr : UnsafeMutablePointer < Output > ?
153
+ let error = operation ( input, & result, $0. baseAddress!, bufferLen, & ptr)
154
+ guard error == 0 && ptr != nil else {
155
+ return nil
156
+ }
157
+ return try block ( result)
158
+ }
159
+ }
160
+
161
+ static func uid( forName name: String ) -> uid_t ? {
162
+ withUserGroupBuffer ( name, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwnam_r) {
163
+ $0. pw_uid
164
+ }
165
+ }
166
+
167
+ static func gid( forName name: String ) -> uid_t ? {
168
+ withUserGroupBuffer ( name, group ( ) , sizeProperty: Int32 ( _SC_GETGR_R_SIZE_MAX) , operation: getgrnam_r) {
169
+ $0. gr_gid
170
+ }
171
+ }
172
+
173
+ static func name( forUID uid: uid_t ) -> String ? {
174
+ withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
175
+ String ( cString: $0. pw_name)
176
+ }
177
+ }
178
+
179
+ static func fullName( forUID uid: uid_t ) -> String ? {
180
+ withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
181
+ String ( cString: $0. pw_gecos)
182
+ }
183
+ }
184
+
185
+ static func name( forGID gid: gid_t ) -> String ? {
186
+ withUserGroupBuffer ( gid, group ( ) , sizeProperty: Int32 ( _SC_GETGR_R_SIZE_MAX) , operation: getgrgid_r) {
187
+ String ( cString: $0. gr_name)
188
+ }
189
+ }
190
+
191
+ static func homeDirectory( forUserName userName: String ) -> String ? {
192
+ withUserGroupBuffer ( userName, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwnam_r) {
193
+ String ( cString: $0. pw_dir)
194
+ }
195
+ }
196
+
197
+ static func homeDirectory( forUID uid: uid_t ) -> String ? {
198
+ withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
199
+ String ( cString: $0. pw_dir)
200
+ }
201
+ }
138
202
}
139
203
#endif
140
204
0 commit comments