Skip to content

Tempfile V4#327

Draft
Stebalien wants to merge 16 commits intomasterfrom
steb/v4-changes
Draft

Tempfile V4#327
Stebalien wants to merge 16 commits intomasterfrom
steb/v4-changes

Conversation

@Stebalien
Copy link
Owner

@Stebalien Stebalien commented Feb 15, 2025

This is a stack of changes for tempfile v4. My plan is to wait for the next Debian stable release then set the MSRV to that, although I may merge and cut an RC before then. This version tries to be minimally breaking in "normal" code but it will still break some code (ideally code that was already broken/buggy).

Other than the MSRV bump (letting us drop once_cell), changes include:

  • Implement AsRef<Path> on &NamedTempFile (and friends) instead of directly on NamedTempFile. That way, functions accepting AsRef<Path> won't be able to take (then drop) NamedTempFile by value. See Got bitten by Drop impl running to early when passing TempDir to fn(p: impl AsRef<Path>) #115.
  • Temporary directories are created with 0700 permissions by default instead of 0755 to match temporary files.
  • Temporary filenames no longer start with a . by default. Temporary files shouldn't generally be hidden. Additionally, it's now possible to configure the default temporary-filename prefix via the env package.
  • The Builder can now has a single lifetime instead of separate ones for prefix and suffix. It can also be constructed with a const Builder::new if desired.
  • Temporary file names are validated to be valid file-names, not including path separators, etc. It's still not safe to allow an attacker to control the prefix/suffix, but this gives us a little extra safety.
  • The closure passed to Builder::make used to take a &Path but now takes an &MakeParams struct (that dereferences to a &Path). This lets us pass additional builder parameters like the desired permissions.
  • The deprecated TempDir::into_path is removed in favor of TempDir::keep.
  • SpooledTempDir::new is now const.
  • tempfile::env::temp_dir() now returns a result and won't panic on platforms where std::env::temp_dir would panic.

TBD:

  • Figure out how to deal with inaccessible parent directories #40. I'd love to fix this but... I'd need to keep open a parent-directory file descriptor and I'd rather not do that if I don't have to. I should probably poke around and see what other temporary file libraries do.
  • Prevent temporary file cleanup by taking a shared advisory locks on all named temporary files to prevent temporary file cleaners from deleting them. This could break some things so we have to be careful, but taking a shared lock is probably reasonable? Possibly only do this if the parent directory is +t (sticky)? We can also make it configurable in the builder, the question will be: what's the default behavior?

Fixes:

@Imberflur
Copy link
Contributor

Imberflur commented Mar 13, 2025

One minor annoyance I noticed with TempDir::close is that you no longer have access to the path for error reporting, so it has to be copied beforehand.

edit: nvm I missed that this actually attaches the path to the error. Didn't realize you could do that and still return a std::io::Error

@Stebalien Stebalien force-pushed the steb/v4-changes branch 6 times, most recently from 9011a9a to 2803c79 Compare May 12, 2025 12:33
@Stebalien Stebalien force-pushed the steb/v4-changes branch 6 times, most recently from 2e6fbb3 to c9df86b Compare August 29, 2025 20:56
@NobodyXu
Copy link
Contributor

debian trixie has released with rust 1.85, though IIRC one of the other popular distro (centos or fedora, I can't remember) still on 1.84

@Stebalien Stebalien force-pushed the steb/v4-changes branch 15 times, most recently from 429443f to c87ede0 Compare March 14, 2026 18:50
I'm testing specific compiler versions, not the MSRV. This seems to be
the easiest way to do this reliably.

I've also changed the cargo config to by-default allow incompatible
versions. That way, people running `cargo test` locally will get the
latest dependencies instead of outdated dependencies. I expect anyone
working on tempfile to use the latest compiler anyways.

Also, auto-detect MSRV
Otherwise it's really easy to pass a temporary file handle by reference,
causing it to be dropped by the receiver deleting the underlying file.

fixes #115
1. Default to "tmp" as the file prefix instead of ".tmp".
2. Make it possible to construct the builder in a constfn.
3. Use a single lifetime in the builder.
That way, we can pass through additional builder options. This new
struct implements AsRef<Path> and Deref<Target=Path> so breakage should
be minimal.
Cursors are stable in rust as of 1.79. This change lets us keep a global
scratch file behind a Mutex.
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