Skip to content

Conversation

@MisterDA
Copy link
Contributor

We can use the WinAPI to get the temporary directory. It's what Rust and Golang do.
A caveat is that GetTempPath2 is only available since Windows 10 21H1. As older Windows 10 versions are still supported by Microsoft, we need to fallback to GetTempPath if GetTempPath2 isn't found.
I use a one-time initialization object (available since Vista) to avoid races when initializing the function pointer to either GetTempPath2 or GetTempPath.

Comment on lines 187 to 188
Under Windows, it uses [GetTempPath2] (since Windows 10 21H1), or
[GetTempPath], and returns:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Under Windows, it uses [GetTempPath2] (since Windows 10 21H1), or
[GetTempPath], and returns:
Under Windows:

(how it is implemented is an implementation detail)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it because the standard libraries of Rust and Golang documented it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't do this anywhere else, so it would be a bit unusual to add it here.


let temp_dir_name =
try Sys.getenv "TMPDIR" with Not_found -> "/tmp"
let temp_dir_name = temp_dir_name ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you say a few words about this (seemingly unrelated) change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to move the Windows code to C. It wasn't clear what to return from caml_sys_temp_dir_name for Unix, and as I needed to add an external ... to filename.ml, it seemed more appropriate to move all the code to the C side, including for Unix, rather than adding a dummy symbol for Unix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you convinced by this part of the change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine, yes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly less convinced (just on the idea of unintended consequences) - for #12624, we decided it was OK to have "asymmetric" primitives for this kind of thing. That feels OK here, too - so just have the Unix side of the primitive return an empty string and simply not use it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so just have the Unix side of the primitive return an empty string and simply not use it

Applied, thanks!

@MisterDA MisterDA changed the title win32unix: use GetTempPath2 for Filename.get_temp_dir_name On Windows, use GetTempPath2 for Filename.get_temp_dir_name Sep 12, 2024
Copy link
Contributor

@nojb nojb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

A second approval is necessary I think. @dra27: could you take a look? Thanks!

Copy link
Member

@dra27 dra27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely for this change, thanks, but it would be good to be motivating it from the security standpoint (what other languages are doing is reassuring, but it's not a reason in and of itself). I'm puzzled by the way InitOnceExecuteOnce is being used - I thought the point of it was to eliminate static variables where the initialisation state was unclear, but I may well be missing a subtlety (cf. the example on MSDN where the point is that there is no static HANDLE value)


let temp_dir_name =
try Sys.getenv "TMPDIR" with Not_found -> "/tmp"
let temp_dir_name = temp_dir_name ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly less convinced (just on the idea of unintended consequences) - for #12624, we decided it was OK to have "asymmetric" primitives for this kind of thing. That feels OK here, too - so just have the Unix side of the primitive return an empty string and simply not use it?

@MisterDA MisterDA marked this pull request as draft September 16, 2024 14:21
@MisterDA MisterDA force-pushed the gettemppath branch 2 times, most recently from 50ee123 to 9b794bd Compare September 16, 2024 15:39
@MisterDA MisterDA marked this pull request as ready for review September 16, 2024 16:42
@MisterDA
Copy link
Contributor Author

Thanks for the reviews @dra27, @nojb! The code is more simple now. You seem to have divergent opinions on the documentation. I'm more inclined to just mention GetTempPath2 and GetTempPath rather than restating their behavior.

Note that there is also a call to GetTempPath in my socketpair emulation for Windows. I have a couple of bug-fixes for that code that I'll submit shortly, I'll join the switch to GetTempPath2 alongside.

@MisterDA
Copy link
Contributor Author

I think the CI failure is transient, I cannot reproduce it locally.

Co-authored-by: David Allsopp <david.allsopp@metastack.com>
@dra27 dra27 merged commit 78c6505 into ocaml:trunk Sep 19, 2024
@dra27
Copy link
Member

dra27 commented Sep 19, 2024

Thanks, @MisterDA!

@MisterDA MisterDA deleted the gettemppath branch September 25, 2024 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants