Skip to content

File.cp_r fails when there is a socket in the directory #15034

@katafrakt

Description

@katafrakt

Elixir and Erlang/OTP versions

Erlang/OTP 27 [erts-15.2.7.4] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

Elixir 1.19.4 (compiled with Erlang/OTP 27)

Operating system

MacOS (Tahoe)

Current behavior

Probably easiest way to reproduce is with git's fsmonitor daemon:

❯ git clone https://github.com/elixir-lang/elixir.git
❯ cd elixir
❯ git fsmonitor--daemon start
❯ file .git/fsmonitor--daemon.ipc
.git/fsmonitor--daemon.ipc: socket

Now, when we use cp, it skips the socket:

❯ cp -r elixir elixir3
cp: elixir/.git/fsmonitor--daemon.ipc is a socket (not copied).

But Elixir's File.cp_r fails and I don't see any workaround:

iex(1) > File.cp_r("elixir", "elixir2")
{:error, :eio, "elixir/.git/fsmonitor--daemon.ipc"}

This is because anything that is not a regular file, a symlink or a directory is treated as an IO error here.

iex(2) > :elixir_utils.read_link_type("elixir/.git/fsmonitor--daemon.ipc")
{:ok, :other}

While this seems extremely niche, I actually found it while building Expert locally, where copying a mix project with git deps happens - so with fsmonitor daemon enabled globally, it fails.

Expected behavior

It would be great to have a way to somehow replicate cp -r's behaviour, either by skipping non-supported node types like cp -r or at least with an option to File.cp_r/3. I can make a PR, but I'm not sure which direction would be best here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions