diff --git a/spec/std/socket/address_spec.cr b/spec/std/socket/address_spec.cr index 08508940bc7d..e89151844f3c 100644 --- a/spec/std/socket/address_spec.cr +++ b/spec/std/socket/address_spec.cr @@ -456,6 +456,10 @@ end Socket::UNIXAddress.new("some_path").hash.should_not eq Socket::UNIXAddress.new("other_path").hash end + it "accepts `Path` input" do + Socket::UNIXAddress.new(Path.new("some_path")).should eq Socket::UNIXAddress.new("some_path") + end + describe ".parse" do it "parses relative" do address = Socket::UNIXAddress.parse "unix://foo.sock" diff --git a/spec/std/socket/unix_server_spec.cr b/spec/std/socket/unix_server_spec.cr index 60f0279b4091..2bd18e10fc2b 100644 --- a/spec/std/socket/unix_server_spec.cr +++ b/spec/std/socket/unix_server_spec.cr @@ -33,6 +33,18 @@ describe UNIXServer do end end + it "creates the socket file from `Path`" do + with_tempfile("unix_server.sock") do |path| + path = Path.new(path) + UNIXServer.open(path) do + File.exists?(path).should be_true + File.info(path).type.socket?.should be_true + end + + File.exists?(path).should be_false + end + end + it "deletes socket file on close" do with_tempfile("unix_server-close.sock") do |path| server = UNIXServer.new(path) diff --git a/spec/std/socket/unix_socket_spec.cr b/spec/std/socket/unix_socket_spec.cr index 7e5eda4e2b65..e541dac19eca 100644 --- a/spec/std/socket/unix_socket_spec.cr +++ b/spec/std/socket/unix_socket_spec.cr @@ -43,6 +43,29 @@ describe UNIXSocket do end end + it "initializes with `Path` paths" do + with_tempfile("unix_socket.sock") do |path| + path_path = Path.new(path) + UNIXServer.open(path_path) do |server| + server.local_address.family.should eq(Socket::Family::UNIX) + server.local_address.path.should eq(path) + + UNIXSocket.open(path_path) do |client| + client.local_address.family.should eq(Socket::Family::UNIX) + client.local_address.path.should eq(path) + + server.accept do |sock| + sock.local_address.family.should eq(Socket::Family::UNIX) + sock.local_address.path.should eq(path) + + sock.remote_address.family.should eq(Socket::Family::UNIX) + sock.remote_address.path.should eq(path) + end + end + end + end + end + it "sync flag after accept" do with_tempfile("unix_socket-accept.sock") do |path| UNIXServer.open(path) do |server| diff --git a/src/socket/address.cr b/src/socket/address.cr index bac36088152f..c07505ad43ab 100644 --- a/src/socket/address.cr +++ b/src/socket/address.cr @@ -765,7 +765,8 @@ class Socket sizeof(typeof(LibC::SockaddrUn.new.sun_path)) - 1 {% end %} - def initialize(@path : String) + def initialize(path : Path | String) + @path = path.to_s if @path.bytesize > MAX_PATH_SIZE raise ArgumentError.new("Path size exceeds the maximum size of #{MAX_PATH_SIZE} bytes") end diff --git a/src/socket/unix_server.cr b/src/socket/unix_server.cr index 75195a09ff70..e2f9b07b6157 100644 --- a/src/socket/unix_server.cr +++ b/src/socket/unix_server.cr @@ -37,7 +37,8 @@ class UNIXServer < UNIXSocket # ``` # # [Only the stream type is supported on Windows](https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/#unsupportedunavailable). - def initialize(@path : String, type : Type = Type::STREAM, backlog : Int = 128) + def initialize(path : Path | String, type : Type = Type::STREAM, backlog : Int = 128) + @path = path = path.to_s super(Family::UNIX, type) system_bind(UNIXAddress.new(path), path) do |error| @@ -53,15 +54,16 @@ class UNIXServer < UNIXSocket end # Creates a UNIXServer from an already configured raw file descriptor - def initialize(*, fd : Handle, type : Type = Type::STREAM, @path : String? = nil) - super(fd: fd, type: type, path: @path) + def initialize(*, fd : Handle, type : Type = Type::STREAM, path : Path | String? = nil) + @path = path = path.to_s + super(fd: fd, type: type, path: path) end # Creates a new UNIX server and yields it to the block. Eventually closes the # server socket when the block returns. # # Returns the value of the block. - def self.open(path, type : Type = Type::STREAM, backlog = 128, &) + def self.open(path : Path | String, type : Type = Type::STREAM, backlog = 128, &) server = new(path, type, backlog) begin yield server diff --git a/src/socket/unix_socket.cr b/src/socket/unix_socket.cr index d5ce5857c907..914a2a62fd1d 100644 --- a/src/socket/unix_socket.cr +++ b/src/socket/unix_socket.cr @@ -18,7 +18,8 @@ class UNIXSocket < Socket getter path : String? # Connects a named UNIX socket, bound to a filesystem pathname. - def initialize(@path : String, type : Type = Type::STREAM) + def initialize(path : Path | String, type : Type = Type::STREAM) + @path = path = path.to_s super(Family::UNIX, type, Protocol::IP) connect(UNIXAddress.new(path)) do |error| @@ -32,7 +33,8 @@ class UNIXSocket < Socket end # Creates a UNIXSocket from an already configured raw file descriptor - def initialize(*, fd : Handle, type : Type = Type::STREAM, @path : String? = nil) + def initialize(*, fd : Handle, type : Type = Type::STREAM, path : Path | String? = nil) + @path = path.to_s super fd, Family::UNIX, type, Protocol::IP end @@ -40,7 +42,7 @@ class UNIXSocket < Socket # eventually closes the socket when the block returns. # # Returns the value of the block. - def self.open(path, type : Type = Type::STREAM, &) + def self.open(path : Path | String, type : Type = Type::STREAM, &) sock = new(path, type) begin yield sock