URL: https://docs.rs/tempfile/latest/src/tempfile/file/imp/unix.rs.html
Content-Type: text/html
Method: native

---

---
meta-description: Source of the Rust file `src/file/imp/unix.rs`.
meta-generator: rustdoc
meta-viewport: width=device-width, initial-scale=1.0
title: unix.rs - source
---

[Docs.rs](/)

- [tempfile-3.27.0](# "A library for managing temporary files and directories.")

  - tempfile 3.27.0
  - [Permalink](/tempfile/3.27.0/src/tempfile/file/imp/unix.rs.html "Get a link to this specific version")
  - [Docs.rs crate page](/crate/tempfile/latest "See tempfile in docs.rs")
  - [MIT](https://spdx.org/licenses/MIT) OR [Apache-2.0](https://spdx.org/licenses/Apache-2.0)
  - 28 June 2026
  

  - Links
  - [Homepage](https://stebalien.com/projects/tempfile-rs/)
  - [Repository](https://github.com/Stebalien/tempfile)
  - [crates.io](https://crates.io/crates/tempfile "See tempfile in crates.io")
  - [Source](/crate/tempfile/latest/source/ "Browse source of tempfile-3.27.0")

  - Owners
  - [Stebalien](https://crates.io/users/Stebalien)
  

  - Dependencies
  -     - [fastrand ^2.1.1 *normal*](/fastrand/^2.1.1/)
    - [once_cell ^1.19.0 *normal*](/once_cell/^1.19.0/)
    - [doc-comment ^0.3 *dev*](/doc-comment/^0.3/)
    - [rustix ^1.1.4 *normal*](/rustix/^1.1.4/)
    - [getrandom >=0.3.0, <0.5 *normal* *optional*](/getrandom/%3E=0.3.0,%20%3C0.5/)
    - [windows-sys >=0.52, <0.62 *normal*](/windows-sys/%3E=0.52,%20%3C0.62/)

  - Versions
  -

  

  - [**92.11%** of the crate is documented](/crate/tempfile/latest)

- [Platform](#)
  - [x86_64-unknown-linux-gnu](/crate/tempfile/latest/target-redirect/src/tempfile/file/imp/unix.rs.html)
- [Feature flags](/crate/tempfile/latest/features "Browse available feature flags of tempfile-3.27.0")

- [docs.rs](#)
  - [About docs.rs](/about)
  - [Badges](/about/badges)
  - [Builds](/about/builds)
  - [Metadata](/about/metadata)
  - [Shorthand URLs](/about/redirections)
  - [Download](/about/download)
  - [Rustdoc JSON](/about/rustdoc-json)
  - [Build queue](/releases/queue)
  - [Privacy policy](https://foundation.rust-lang.org/policies/privacy-policy/#docs.rs)

- [Rust](#)
  - [Rust website](https://www.rust-lang.org/)
  - [The Book](https://doc.rust-lang.org/book/)
  - [Standard Library API Reference](https://doc.rust-lang.org/std/)
  - [Rust by Example](https://doc.rust-lang.org/rust-by-example/)
  - [The Cargo Guide](https://doc.rust-lang.org/cargo/guide/)
  - [Clippy Documentation](https://doc.rust-lang.org/nightly/clippy)

[/-/storage-change-detection.html](/-/storage-change-detection.html)

[Skip to main content](#main-content)

# tempfile/file/imp/unix.rs

    [1](#1)use [std::ffi::OsStr](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.OsStr.html);
    [2](#2)use std::fs::{[self](https://doc.rust-lang.org/nightly/std/fs/index.html), [File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html), [OpenOptions](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html)};
    [3](#3)use [std::io](https://doc.rust-lang.org/nightly/std/io/index.html);
    [4](#4)
    [5](#5)use [crate::util](../../lib.rs.html#206);
    [6](#6)use [std::path::Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html);
    [7](#7)
    [8](#8)use {
    [9](#9)    rustix::fs::{[rename](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/abs/fn.rename.html), [unlink](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/abs/fn.unlink.html)},
    [10](#10)    [std::fs::hard_link](https://doc.rust-lang.org/nightly/std/fs/fn.hard_link.html),
    [11](#11)};
    [12](#12)
    [13](#13)pub fn create_named(
    [14](#14)    path: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html),
    [15](#15)    open_options: &mut [OpenOptions](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html),
    [16](#16)    #[cfg_attr(target_os = "wasi", allow(unused))] permissions: [Option](https://doc.rust-lang.org/nightly/core/option/enum.Option.html)<&std::fs::[Permissions](https://doc.rust-lang.org/nightly/std/fs/struct.Permissions.html)>,
    [17](#17)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html)> {
    [18](#18)    [open_options](#15).[read](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.read)(true).[write](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.write)(true).[create_new](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.create_new)(true);
    [19](#19)
    [20](#20)    #[cfg(not(target_os = "wasi"))]
    [21](#21)    {
    [22](#22)        use std::os::unix::fs::{[OpenOptionsExt](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.OpenOptionsExt.html), [PermissionsExt](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.PermissionsExt.html)};
    [23](#23)        [open_options](#15).[mode](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.mode)([permissions](#16).[map](https://doc.rust-lang.org/nightly/core/option/enum.Option.html#method.map)(|p| [p](#23).[mode](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.PermissionsExt.html#tymethod.mode)()).[unwrap_or](https://doc.rust-lang.org/nightly/core/option/enum.Option.html#method.unwrap_or)(0o600));
    [24](#24)    }
    [25](#25)
    [26](#26)    [open_options](#15).[open](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.open)([path](#14))
    [27](#27)}
    [28](#28)
    [29](#29)fn create_unlinked(path: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html)> {
    [30](#30)    let tmp;
    [31](#31)    // shadow this to decrease the lifetime. It can't live longer than `tmp`.
    [32](#32)    let mut path = [path](#29);
    [33](#33)    if ![path](#32).[is_absolute](https://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.is_absolute)() {
    [34](#34)        let cur_dir = std::env::current_dir()?;
    [35](#35)        [tmp](#30) = [cur_dir](#34).[join](https://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.join)([path](#32));
    [36](#36)        [path](#32) = &[tmp](#30);
    [37](#37)    }
    [38](#38)
    [39](#39)    let f = create_named(path, &mut OpenOptions::new(), None)?;
    [40](#40)    // don't care whether the path has already been unlinked,
    [41](#41)    // but perhaps there are some IO error conditions we should send up?
    [42](#42)    let _ = fs::[remove_file](https://doc.rust-lang.org/nightly/std/fs/fn.remove_file.html)([path](#32));
    [43](#43)    [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)([f](#39))
    [44](#44)}
    [45](#45)
    [46](#46)#[cfg(target_os = "linux")]
    [47](#47)pub fn create(dir: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html)> {
    [48](#48)    use rustix::{[fs::OFlags](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.OFlags.html), [io::Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)};
    [49](#49)    use [std::os::unix::fs::OpenOptionsExt](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.OpenOptionsExt.html);
    [50](#50)    [OpenOptions](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html)::[new](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.new)()
    [51](#51)        .[read](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.read)(true)
    [52](#52)        .[write](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.write)(true)
    [53](#53)        .[custom_flags](https://doc.rust-lang.org/nightly/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.custom_flags)([OFlags](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.OFlags.html)::[TMPFILE](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.OFlags.html#associatedconstant.TMPFILE).bits() as [i32](https://doc.rust-lang.org/nightly/std/primitive.i32.html)) // do not mix with `create_new(true)`
    [54](#54)        .[open](https://doc.rust-lang.org/nightly/std/fs/struct.OpenOptions.html#method.open)([dir](#47))
    [55](#55)        .[or_else](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#method.or_else)(|e| {
    [56](#56)            match [Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[from_io_error](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#method.from_io_error)(&[e](#55)) {
    [57](#57)                // These are the three "not supported" error codes for O_TMPFILE.
    [58](#58)                [Some](https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.Some)([Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[OPNOTSUPP](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#associatedconstant.OPNOTSUPP)) | [Some](https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.Some)([Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[ISDIR](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#associatedconstant.ISDIR)) | [Some](https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.Some)([Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[NOENT](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#associatedconstant.NOENT)) => {
    [59](#59)                    [create_unix](#71-79)([dir](#47))
    [60](#60)                }
    [61](#61)                _ => [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)([e](#55)),
    [62](#62)            }
    [63](#63)        })
    [64](#64)}
    [65](#65)
    [66](#66)#[cfg(not(target_os = "linux"))]
    [67](#67)pub fn create(dir: &Path) -> io::Result<File> {
    [68](#68)    create_unix(dir)
    [69](#69)}
    [70](#70)
    [71](#71)fn create_unix(dir: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html)> {
    [72](#72)    util::[create_helper](../../util.rs.html#22-82)(
    [73](#73)        [dir](#71),
    [74](#74)        [OsStr](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.OsStr.html)::[new](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.OsStr.html#method.new)(".tmp"),
    [75](#75)        [OsStr](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.OsStr.html)::[new](https://doc.rust-lang.org/nightly/std/ffi/os_str/struct.OsStr.html#method.new)(""),
    [76](#76)        crate::[NUM_RAND_CHARS](../../lib.rs.html#195),
    [77](#77)        |path| [create_unlinked](#29-44)(&[path](#77)),
    [78](#78)    )
    [79](#79)}
    [80](#80)
    [81](#81)pub fn reopen(file: &[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html), path: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<[File](https://doc.rust-lang.org/nightly/std/fs/struct.File.html)> {
    [82](#82)    let new_file = OpenOptions::new().read(true).write(true).open(path)?;
    [83](#83)    let old_meta = rustix::fs::fstat(file)?;
    [84](#84)    let new_meta = rustix::fs::fstat(&new_file)?;
    [85](#85)    if [old_meta](#83).st_dev != [new_meta](#84).st_dev || [old_meta](#83).st_ino != [new_meta](#84).st_ino {
    [86](#86)        return [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)(io::[Error](https://doc.rust-lang.org/nightly/std/io/error/struct.Error.html)::[new](https://doc.rust-lang.org/nightly/std/io/error/struct.Error.html#method.new)(
    [87](#87)            io::ErrorKind::[NotFound](https://doc.rust-lang.org/nightly/core/io/error/enum.ErrorKind.html#variant.NotFound),
    [88](#88)            "original tempfile has been replaced",
    [89](#89)        ));
    [90](#90)    }
    [91](#91)    [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)([new_file](#82))
    [92](#92)}
    [93](#93)
    [94](#94)pub fn persist(old_path: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html), new_path: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html), overwrite: [bool](https://doc.rust-lang.org/nightly/std/primitive.bool.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<()> {
    [95](#95)    if [overwrite](#94) {
    [96](#96)        rename(old_path, new_path)?;
    [97](#97)    } else {
    [98](#98)        // On Linux, apple and redox operating systems, use `renameat_with` to avoid overwriting an
    [99](#99)        // existing name, if the kernel and the filesystem support it.
    [100](#100)        #[cfg(any(
    [101](#101)            target_os = "android",
    [102](#102)            target_os = "linux",
    [103](#103)            target_os = "macos",
    [104](#104)            target_os = "ios",
    [105](#105)            target_os = "tvos",
    [106](#106)            target_os = "visionos",
    [107](#107)            target_os = "watchos",
    [108](#108)            target_os = "redox",
    [109](#109)        ))]
    [110](#110)        {
    [111](#111)            use rustix::fs::{[renameat_with](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/at/fn.renameat_with.html), [RenameFlags](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.RenameFlags.html), [CWD](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/special/constant.CWD.html)};
    [112](#112)            use [rustix::io::Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html);
    [113](#113)            use std::sync::atomic::{[AtomicBool](https://doc.rust-lang.org/nightly/core/sync/atomic/type.AtomicBool.html), [Ordering::Relaxed](https://doc.rust-lang.org/nightly/core/sync/atomic/enum.Ordering.html#variant.Relaxed)};
    [114](#114)
    [115](#115)            static NOSYS: [AtomicBool](https://doc.rust-lang.org/nightly/core/sync/atomic/type.AtomicBool.html) = [AtomicBool](https://doc.rust-lang.org/nightly/core/sync/atomic/type.AtomicBool.html)::[new](https://doc.rust-lang.org/nightly/core/sync/atomic/struct.Atomic.html#method.new)(false);
    [116](#116)            if ![NOSYS](#115).[load](https://doc.rust-lang.org/nightly/core/sync/atomic/struct.Atomic.html#method.load)([Relaxed](https://doc.rust-lang.org/nightly/core/sync/atomic/enum.Ordering.html#variant.Relaxed)) {
    [117](#117)                match [renameat_with](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/at/fn.renameat_with.html)([CWD](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/special/constant.CWD.html), [old_path](#94), [CWD](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/special/constant.CWD.html), [new_path](#94), [RenameFlags](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.RenameFlags.html)::[NOREPLACE](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/fs/types/struct.RenameFlags.html#associatedconstant.NOREPLACE)) {
    [118](#118)                    [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)(()) => return [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)(()),
    [119](#119)                    [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)([Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[NOSYS](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#associatedconstant.NOSYS)) => [NOSYS](#115).[store](https://doc.rust-lang.org/nightly/core/sync/atomic/struct.Atomic.html#method.store)(true, [Relaxed](https://doc.rust-lang.org/nightly/core/sync/atomic/enum.Ordering.html#variant.Relaxed)),
    [120](#120)                    [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)([Errno](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html)::[INVAL](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/backend/io/errno/struct.Errno.html#associatedconstant.INVAL)) => {}
    [121](#121)                    [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)(e) => return [Err](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Err)([e](#121).[into](https://doc.rust-lang.org/nightly/core/convert/trait.Into.html#tymethod.into)()),
    [122](#122)                }
    [123](#123)            }
    [124](#124)        }
    [125](#125)
    [126](#126)        // Otherwise use `hard_link` to create the new filesystem name, which
    [127](#127)        // will fail if the name already exists, and then `unlink` to remove
    [128](#128)        // the old name.
    [129](#129)        hard_link(old_path, new_path)?;
    [130](#130)
    [131](#131)        // Ignore unlink errors. Can we do better?
    [132](#132)        let _ = [unlink](https://docs.rs/rustix/1.1.4/x86_64-unknown-linux-gnu/rustix/fs/abs/fn.unlink.html)([old_path](#94));
    [133](#133)    }
    [134](#134)    [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)(())
    [135](#135)}
    [136](#136)
    [137](#137)pub fn keep(_: &[Path](https://doc.rust-lang.org/nightly/std/path/struct.Path.html)) -> io::[Result](https://doc.rust-lang.org/nightly/std/io/error/type.Result.html)<()> {
    [138](#138)    [Ok](https://doc.rust-lang.org/nightly/core/result/enum.Result.html#variant.Ok)(())
    [139](#139)}