Skip to content

Windows support (ENOTEMPTY issues) #72

Closed
@joliss

Description

@joliss

I'd like to re-open the discussion about ENOTEMPTY problems on Windows, as previously raised in #25.

Technical background: On Windows, a file can be "busy" when our process or another process still has an open file handle. This can happen unpredictably; e.g. a webserver might have an open connection serving the file, or a virus scanner might be accessing it. When you remove a busy file (with fs.unlinkSync or fs.unlink), unlinkSync will return successfully, but the file sticks around on the file system until the handle is released. As a result, when rimraf removes a file and then tries to rmdir the containing directory, the rmdir operation can fail with ENOTEMPTY. (This is from memory and hearsay, so some details may be wrong!)

This causes random sporadic failures - see e.g. the stack trace reported in broccolijs/broccoli#232.

There is currently a workaround implemented in rimraf (d819b12, fixing #25). However, it is based on retrying repeatedly with setTimeout, and it only works in the asynchronous version. Of course, this seems pretty hackish and potentially unreliable. We're using rimraf a lot in the Broccoli plugin ecosystem, and it makes me worried that we'll have lots of issues on Windows down the line.

So I'd love it if we could find a proper fix for this issue, rather than working around it.

It surely must be possible to find a fix - and this is why I'm opening this issue again: For example, commands like rmdir /s can't possibly be relying on weird workarounds, can they? And Windows Explorer lets you delete directories, without random (flickering) failures stemming from your virus scanner accessing some file.

More detail for people wishing to dig in: this gist by @stefanpenner; this comment in libuv's fs.c; libuv's unlink implementation on Windows. I wonder if libuv's very roundabout unlink implementation (presumably to mimic POSIX) might be a contributor. Could this be fixable in libuv, or could we come up with a platform-specific C implementation for rimraf on Windows that doesn't use libuv?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions