Skip to content

Commit c9df86b

Browse files
committed
fix: avoid panicing on platforms with no sane default tempdir
fixes #365
1 parent c5a0d1c commit c9df86b

File tree

6 files changed

+27
-15
lines changed

6 files changed

+27
-15
lines changed

src/env.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
use std::env;
21
use std::ffi::{OsStr, OsString};
32
use std::path::{Path, PathBuf};
43
use std::sync::{LazyLock, OnceLock};
4+
use std::{env, io};
55

66
#[cfg(doc)]
77
use crate::{tempdir_in, tempfile_in, Builder};
88

9-
static ENV_TEMPDIR: LazyLock<PathBuf> = LazyLock::new(env::temp_dir);
9+
static ENV_TEMPDIR: LazyLock<Option<PathBuf>> =
10+
// Only call env::temp_dir() on platforms known to not panic.
11+
LazyLock::new(if cfg!(any(unix, windows, target_os = "hermit")) {
12+
|| Some(env::temp_dir())
13+
} else {
14+
|| None
15+
});
1016
static DEFAULT_TEMPDIR: OnceLock<PathBuf> = OnceLock::new();
1117
static DEFAULT_PREFIX: OnceLock<OsString> = OnceLock::new();
1218

@@ -36,16 +42,22 @@ pub fn override_temp_dir(path: impl Into<PathBuf>) -> Result<&'static Path, &'st
3642
/// Returns the default temporary directory, used for both temporary directories and files if no
3743
/// directory is explicitly specified.
3844
///
39-
/// This function simply delegates to [`std::env::temp_dir`] unless the default temporary directory
40-
/// has been override by a call to [`override_temp_dir`].
45+
/// Unless the default temporary directory has been overridden by a call to [`override_temp_dir`],
46+
/// this function delegates to [`std::env::temp_dir`] (when supported by the platform). It returns
47+
/// an error on platforms with no default temporary directory (e.g., WASI/WASM) unless
48+
/// [`override_temp_dir`] has already been called to set the temporary directory.
4149
///
4250
/// **NOTE:**
4351
///
4452
/// 1. This function does not check if the returned directory exists and/or is writable.
4553
/// 2. This function caches the result of [`std::env::temp_dir`]. Any future changes to, e.g., the
4654
/// `TMPDIR` environment variable won't have any effect.
47-
pub fn temp_dir() -> &'static Path {
48-
DEFAULT_TEMPDIR.get().unwrap_or_else(|| &ENV_TEMPDIR)
55+
pub fn temp_dir() -> io::Result<&'static Path> {
56+
DEFAULT_TEMPDIR
57+
.get()
58+
.or_else(|| ENV_TEMPDIR.as_ref())
59+
.map(|a| &**a)
60+
.ok_or_else(|| io::Error::other("no temporary directory configured"))
4961
}
5062

5163
/// Override the default prefix for new temporary files (defaults to "tmp"). This function changes

src/file/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ mod imp;
4949
/// # Ok::<(), std::io::Error>(())
5050
/// ```
5151
pub fn tempfile() -> io::Result<File> {
52-
tempfile_in(env::temp_dir())
52+
tempfile_in(env::temp_dir()?)
5353
}
5454

5555
/// Create a new temporary file in the specified directory. Also see [`tempfile`].

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a> Builder<'a> {
498498
/// [security]: struct.NamedTempFile.html#security
499499
/// [resource-leaking]: struct.NamedTempFile.html#resource-leaking
500500
pub fn tempfile(&self) -> io::Result<NamedTempFile> {
501-
self.tempfile_in(env::temp_dir())
501+
self.tempfile_in(env::temp_dir()?)
502502
}
503503

504504
/// Create the named temporary file in the specified directory.
@@ -567,7 +567,7 @@ impl<'a> Builder<'a> {
567567
///
568568
/// [resource-leaking]: struct.TempDir.html#resource-leaking
569569
pub fn tempdir(&self) -> io::Result<TempDir> {
570-
self.tempdir_in(env::temp_dir())
570+
self.tempdir_in(env::temp_dir()?)
571571
}
572572

573573
/// Attempts to make a temporary directory inside of `dir`.
@@ -691,7 +691,7 @@ impl<'a> Builder<'a> {
691691
where
692692
F: FnMut(&MakeParams<'_>) -> io::Result<R>,
693693
{
694-
self.make_in(env::temp_dir(), f)
694+
self.make_in(env::temp_dir()?, f)
695695
}
696696

697697
/// This is the same as [`Builder::make`], except `dir` is used as the base

tests/env.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use std::path::Path;
55
#[test]
66
fn test_override_temp_dir() {
77
#[cfg(not(target_os = "wasi"))]
8-
assert_eq!(tempfile::env::temp_dir(), std::env::temp_dir());
8+
assert_eq!(tempfile::env::temp_dir().unwrap(), std::env::temp_dir());
99

1010
let new_tmp = Path::new("/tmp/override");
1111
tempfile::env::override_temp_dir(new_tmp).unwrap();
12-
assert_eq!(tempfile::env::temp_dir(), new_tmp);
12+
assert_eq!(tempfile::env::temp_dir().unwrap(), new_tmp);
1313

1414
let new_tmp2 = Path::new("/tmp/override2");
1515
tempfile::env::override_temp_dir(new_tmp2).expect_err("override should only be possible once");

tests/namedtempfile.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn test_persist() {
6565

6666
let mut tmpfile = NamedTempFile::new().unwrap();
6767
let old_path = tmpfile.path().to_path_buf();
68-
let persist_path = env::temp_dir().join("persisted_temporary_file");
68+
let persist_path = env::temp_dir().unwrap().join("persisted_temporary_file");
6969
write!(tmpfile, "abcde").unwrap();
7070
{
7171
assert!(exists(&old_path));
@@ -213,7 +213,7 @@ fn test_temppath_persist() {
213213
let tmppath = tmpfile.into_temp_path();
214214

215215
let old_path = tmppath.to_path_buf();
216-
let persist_path = env::temp_dir().join("persisted_temppath_file");
216+
let persist_path = env::temp_dir().unwrap().join("persisted_temppath_file");
217217

218218
{
219219
assert!(exists(&old_path));

tests/spooled.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn test_custom_dir() {
4343
configure_wasi_temp_dir();
4444

4545
{
46-
let mut t = spooled_tempfile_in(10, env::temp_dir());
46+
let mut t = spooled_tempfile_in(10, env::temp_dir().unwrap());
4747
t.roll()
4848
.expect("failed to roll temp file in a specified directory");
4949
}

0 commit comments

Comments
 (0)