Skip to content

document remove_dir_all returning DirectoryNotEmpty on concurrent write #139958

Closed
@trinity-1686a

Description

@trinity-1686a

Location

https://doc.rust-lang.org/std/fs/fn.remove_dir_all.html

Summary

remove_dir_all can fail with DirectoryNotEmpty. This is somewhat implied by this sentence:

remove_dir_all will fail if remove_dir or remove_file fail on any constituent paths, including the root path.

but when diagnosing an issue related to this function, it really didn't seem to me that DirectoryNotEmpty was an error this function could ever return, especially given the detailed error section, and a platform-specific section mentioning being TOCTOU free (note: i wouldn't consider this a TOCTOU vuln by any mean, but it implied to me a stronger kind of handling for concurrent access than there is).

error reproducer:

use std::fs::{create_dir, remove_dir_all, write};
use std::thread::spawn;

fn main() {
    create_dir("testdir").unwrap();

    for i in 0..100 {
        write(format!("testdir/{i}"), b"test_data").unwrap()
    }

    spawn(|| {
        for i in 0.. {
            if write(format!("testdir/new {i}"), b"test_data").is_err() {
                return;
            }
        }
    });

    remove_dir_all("testdir").unwrap();
}

I think the last line of the Error section could be rewritten as:

This function may emit io::ErrorKind::DirectoryNotEmpty if the directory is concurrently written into, but will only return io::ErrorKind::NotFound if no removal occurs.

Metadata

Metadata

Assignees

Labels

A-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-filesystemArea: `std::fs`T-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions