Skip to content

Commit 388dc0d

Browse files
authored
Rollup merge of #124282 - RalfJung:fill_utf16_buf, r=ChrisDenton
windows fill_utf16_buf: explain the expected return value The comment just says "return what the syscall returns", but that doesn't work for all syscalls as the Windows API is not consistent in how buffer size is negotiated. For instance, GetUserProfileDirectoryW works a bit differently, and so home_dir_crt has to translate this to the usual protocol itself. So it's worth describing that protocol. r? ``@ChrisDenton``
2 parents 4eda876 + a21c2d8 commit 388dc0d

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

library/std/src/sys/pal/windows/mod.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,21 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
201201
// currently reside in the buffer. This function is an abstraction over these
202202
// functions by making them easier to call.
203203
//
204-
// The first callback, `f1`, is yielded a (pointer, len) pair which can be
204+
// The first callback, `f1`, is passed a (pointer, len) pair which can be
205205
// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
206-
// The closure is expected to return what the syscall returns which will be
207-
// interpreted by this function to determine if the syscall needs to be invoked
208-
// again (with more buffer space).
206+
// The closure is expected to:
207+
// - On success, return the actual length of the written data *without* the null terminator.
208+
// This can be 0. In this case the last_error must be left unchanged.
209+
// - On insufficient buffer space,
210+
// - either return the required length *with* the null terminator,
211+
// - or set the last-error to ERROR_INSUFFICIENT_BUFFER and return `len`.
212+
// - On other failure, return 0 and set last_error.
213+
//
214+
// This is how most but not all syscalls indicate the required buffer space.
215+
// Other syscalls may need translation to match this protocol.
209216
//
210217
// Once the syscall has completed (errors bail out early) the second closure is
211-
// yielded the data which has been read from the syscall. The return value
218+
// passed the data which has been read from the syscall. The return value
212219
// from this closure is then the return value of the function.
213220
pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
214221
where

library/std/src/sys/pal/windows/os.rs

+2
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ fn home_dir_crt() -> Option<PathBuf> {
326326

327327
super::fill_utf16_buf(
328328
|buf, mut sz| {
329+
// GetUserProfileDirectoryW does not quite use the usual protocol for
330+
// negotiating the buffer size, so we have to translate.
329331
match c::GetUserProfileDirectoryW(
330332
ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN),
331333
buf,

0 commit comments

Comments
 (0)