@@ -29,8 +29,7 @@ fileprivate let _pageSize: Int = {
29
29
// WebAssembly defines a fixed page size
30
30
fileprivate let _pageSize : Int = 65_536
31
31
#elseif canImport(Android)
32
- import Bionic
33
- import unistd
32
+ import Android
34
33
fileprivate let _pageSize : Int = Int ( getpagesize ( ) )
35
34
#elseif canImport(Glibc)
36
35
import Glibc
@@ -142,7 +141,7 @@ extension Platform {
142
141
typealias Operation < Input, Output> = ( Input , UnsafeMutablePointer < Output > , UnsafeMutablePointer < CChar > , Int , UnsafeMutablePointer < UnsafeMutablePointer < Output > ? > ) -> Int32
143
142
#endif
144
143
145
- private static func withUserGroupBuffer< Input, Output, R> ( _ input: Input , _ output: Output , sizeProperty: Int32 , operation: Operation < Input , Output > , block: ( Output ) throws -> R ) rethrows -> R ? {
144
+ private static func withUserGroupBuffer< Input, Output, R> ( _ input: Input , _ output: Output , sizeProperty: Int32 , operation: Operation < Input , Output > , block: ( Output ) throws -> R ? ) rethrows -> R ? {
146
145
var bufferLen = sysconf ( sizeProperty)
147
146
if bufferLen == - 1 {
148
147
bufferLen = 4096 // Generous default size estimate
@@ -172,31 +171,51 @@ extension Platform {
172
171
173
172
static func name( forUID uid: uid_t ) -> String ? {
174
173
withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
175
- String ( cString: $0. pw_name)
174
+ // Android's pw_name `char *`` is nullable, so always coerce to a nullable pointer
175
+ // in order to be compatible with Android.
176
+ let pw_name : UnsafeMutablePointer < CChar > ? = $0. pw_name
177
+ return pw_name. flatMap { String ( cString: $0) }
176
178
}
177
179
}
178
180
179
181
static func fullName( forUID uid: uid_t ) -> String ? {
180
182
withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
181
- String ( cString: $0. pw_gecos)
183
+ #if os(Android) && (arch(i386) || arch(arm))
184
+ // pw_gecos isn't available on 32-bit Android.
185
+ let pw_gecos : UnsafeMutablePointer < CChar > ? = nil
186
+ #else
187
+ // Android's pw_gecos `char *`` is nullable, so always coerce to a nullable pointer
188
+ // in order to be compatible with Android.
189
+ let pw_gecos : UnsafeMutablePointer < CChar > ? = $0. pw_gecos
190
+ #endif
191
+ return pw_gecos. flatMap { String ( cString: $0) }
182
192
}
183
193
}
184
194
185
195
static func name( forGID gid: gid_t ) -> String ? {
186
196
withUserGroupBuffer ( gid, group ( ) , sizeProperty: Int32 ( _SC_GETGR_R_SIZE_MAX) , operation: getgrgid_r) {
187
- String ( cString: $0. gr_name)
197
+ // Android's gr_name `char *`` is nullable, so always coerce to a nullable pointer
198
+ // in order to be compatible with Android.
199
+ let gr_name : UnsafeMutablePointer < CChar > ? = $0. gr_name
200
+ return gr_name. flatMap { String ( cString: $0) }
188
201
}
189
202
}
190
203
191
204
static func homeDirectory( forUserName userName: String ) -> String ? {
192
205
withUserGroupBuffer ( userName, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwnam_r) {
193
- String ( cString: $0. pw_dir)
206
+ // Android's pw_dir `char *`` is nullable, so always coerce to a nullable pointer
207
+ // in order to be compatible with Android.
208
+ let pw_dir : UnsafeMutablePointer < CChar > ? = $0. pw_dir
209
+ return pw_dir. flatMap { String ( cString: $0) }
194
210
}
195
211
}
196
212
197
213
static func homeDirectory( forUID uid: uid_t ) -> String ? {
198
214
withUserGroupBuffer ( uid, passwd ( ) , sizeProperty: Int32 ( _SC_GETPW_R_SIZE_MAX) , operation: getpwuid_r) {
199
- String ( cString: $0. pw_dir)
215
+ // Android's pw_dir `char *`` is nullable, so always coerce to a nullable pointer
216
+ // in order to be compatible with Android.
217
+ let pw_dir : UnsafeMutablePointer < CChar > ? = $0. pw_dir
218
+ return pw_dir. flatMap { String ( cString: $0) }
200
219
}
201
220
}
202
221
}
0 commit comments