-
Notifications
You must be signed in to change notification settings - Fork 704
feat: add homeDirectory accessor to FileSystem #3392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -362,6 +362,67 @@ public enum Libc: Sendable { | |
} | ||
} | ||
|
||
static func homeDirectoryForCurrentUser() -> Result<FilePath, Errno> { | ||
if let home = getenv("HOME"), home.pointee != 0 { | ||
return .success(FilePath(String(cString: home))) | ||
} | ||
|
||
#if os(Windows) | ||
if let profile = getenv("USERPROFILE"), profile.pointee != 0 { | ||
return .success(FilePath(String(cString: profile))) | ||
} | ||
return .failure(.noSuchFileOrDirectory) | ||
#else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
return self._homeDirectoryFromPasswordDatabase() | ||
#endif | ||
} | ||
|
||
#if canImport(Darwin) || canImport(Glibc) || canImport(Musl) || canImport(Android) | ||
private static func _homeDirectoryFromPasswordDatabase() -> Result<FilePath, Errno> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you refactor this slightly so that it's |
||
var pwd = passwd() | ||
var result: UnsafeMutablePointer<passwd>? = nil | ||
var buffer = [CChar](repeating: 0, count: 256) | ||
|
||
let uid: uid_t = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The syscalls and libc calls in Then layered on top of that are the functions on the To that end, could you add a |
||
#if canImport(Darwin) | ||
return Darwin.getuid() | ||
#elseif canImport(Glibc) | ||
return Glibc.getuid() | ||
#elseif canImport(Musl) | ||
return Musl.getuid() | ||
#else | ||
return 0 | ||
#endif | ||
}() | ||
|
||
while true { | ||
let error: CInt = buffer.withUnsafeMutableBufferPointer { pointer in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than dealing with let result = buffer.withUnsafeMutableBufferPointer { pointer in
withUnsafeMutablePointer(to &result) { resultPointer in
nothingOrErrno(retryOnInterrupt: true) {
libc_getpwuid_r(uid, &pwd, pointer.baseAddress!, pointer.count, resultPointer)
}
}
} That allows you to switch on the result below and use the |
||
guard let baseAddress = pointer.baseAddress else { | ||
return CInt(ERANGE) | ||
} | ||
Comment on lines
+400
to
+402
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check shouldn't be necessary, |
||
|
||
return withUnsafeMutablePointer(to: &result) { resultPointer in | ||
libc_getpwuid_r(uid, &pwd, baseAddress, pointer.count, resultPointer) | ||
} | ||
} | ||
|
||
if error == 0 { | ||
guard result != nil, let directoryPointer = pwd.pw_dir else { | ||
return .failure(.noSuchFileOrDirectory) | ||
} | ||
return .success(FilePath(String(cString: directoryPointer))) | ||
} | ||
|
||
if error == ERANGE { | ||
buffer.append(contentsOf: repeatElement(0, count: buffer.count)) | ||
continue | ||
} | ||
|
||
return .failure(Errno(rawValue: error)) | ||
} | ||
} | ||
#endif | ||
|
||
#if !os(Android) | ||
static func constr(_ name: CInt) -> Result<String, Errno> { | ||
var buffer = [CInterop.PlatformChar](repeating: 0, count: 128) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are structured to follow the underlying syscall so this should be called
getpwuid_r