Skip to content

Commit 88cbabf

Browse files
Skip :eio files in File.cp_r (#15035)
1 parent 0f67706 commit 88cbabf

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

lib/elixir/lib/file.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,8 @@ defmodule File do
11141114
explicitly disallow this behavior. If `source` is a `file` and `destination`
11151115
is a directory, `{:error, :eisdir}` will be returned.
11161116
1117+
Special files such as device files, sockets, and named pipes are not copied.
1118+
11171119
## Options
11181120
11191121
* `:on_conflict` - (since v1.14.0) Invoked when a file already exists in the destination.
@@ -1262,7 +1264,7 @@ defmodule File do
12621264
end
12631265

12641266
{:ok, _} ->
1265-
{:error, :eio, src}
1267+
acc
12661268

12671269
{:error, reason} ->
12681270
{:error, reason, src}

lib/elixir/test/elixir/file_test.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,35 @@ defmodule FileTest do
815815
%File.Stat{mode: dest_mode} = File.stat!(dest)
816816
assert src_mode == dest_mode
817817
end
818+
819+
@tag :unix
820+
test "cp_r skips sockets and other special files" do
821+
src = tmp_path("src_with_socket")
822+
dest = tmp_path("dest_with_socket")
823+
socket_path = Path.join(src, "test.sock")
824+
regular_file = Path.join(src, "regular.txt")
825+
826+
File.mkdir_p!(src)
827+
File.write!(regular_file, "content")
828+
829+
{:ok, socket} = :gen_tcp.listen(0, [:local, {:ifaddr, {:local, socket_path}}])
830+
831+
try do
832+
assert File.exists?(socket_path)
833+
assert :elixir_utils.read_link_type(socket_path) == {:ok, :other}
834+
835+
{:ok, copied_files} = File.cp_r(src, dest)
836+
837+
assert Path.join(dest, "regular.txt") in copied_files
838+
839+
refute File.exists?(Path.join(dest, "test.sock"))
840+
refute Path.join(dest, "test.sock") in copied_files
841+
after
842+
:gen_tcp.close(socket)
843+
File.rm_rf(src)
844+
File.rm_rf(dest)
845+
end
846+
end
818847
end
819848

820849
defmodule Queries do

0 commit comments

Comments
 (0)