diff --git a/lib/async/io/unix_endpoint.rb b/lib/async/io/unix_endpoint.rb index 5d37aa2..d303634 100644 --- a/lib/async/io/unix_endpoint.rb +++ b/lib/async/io/unix_endpoint.rb @@ -35,8 +35,8 @@ def bind(&block) Socket.bind(@address, **@options, &block) rescue Errno::EADDRINUSE # If you encounter EADDRINUSE from `bind()`, you can check if the socket is actually accepting connections by attempting to `connect()` to it. If the socket is still bound by an active process, the connection will succeed. Otherwise, it should be safe to `unlink()` the path and try again. - if !bound? && File.exist?(@path) - File.unlink(@path) + if !bound? + FileUtils.safe_unlink(@path) retry else raise diff --git a/spec/async/io/unix_endpoint_spec.rb b/spec/async/io/unix_endpoint_spec.rb index 44efd8c..ff4e58e 100644 --- a/spec/async/io/unix_endpoint_spec.rb +++ b/spec/async/io/unix_endpoint_spec.rb @@ -5,7 +5,6 @@ require 'async/io/unix_endpoint' require 'async/io/stream' -require 'fileutils' RSpec.describe Async::IO::UNIXEndpoint do include_context Async::RSpec::Reactor @@ -14,14 +13,6 @@ let(:path) {File.join(__dir__, "unix-socket")} subject {described_class.unix(path)} - before(:each) do - FileUtils.rm_f path - end - - after do - FileUtils.rm_f path - end - it "should echo data back to peer" do server_task = reactor.async do subject.accept do |peer| @@ -39,6 +30,20 @@ server_task.stop end + + it "should not fail to bind if there are no existing bindings on the socket" do + server_task1 = reactor.async do + subject.bind + end + server_task1.stop + + server_task2 = reactor.async do + expect do + subject.bind + end.to_not raise_error + end + server_task2.stop + end it "should fails to bind if there is an existing binding" do condition = Async::Condition.new