Skip to content

Support for UNIX endpoints on the abstract file system #25

Description

@herwinw

https://www.man7.org/linux/man-pages/man7/unix.7.html has a very succinct description on it (search for "abstract"). Short version: these are not actual files, but identifiers that start with a null byte. The changes in 0.17.2 have broken them.

Minimal example:

#!/usr/bin/env -S falcon host
# frozen_string_literal: true
load :rack

rack 'localhost' do
  endpoint Async::HTTP::Endpoint.parse('http://localhost:9292')
end

rack 'unixsocket' do
  uri = URI.for('unix', nil, "\x00Falcontest", nil, nil, '', nil, nil, nil, URI)
  endpoint Async::HTTP::Endpoint.new(uri, IO::Endpoint.unix("\x00FalconTest"))
end

(I'm not sure if this is the best way to create a unix socket for an abstract namespace, but this one worked with io-endpoint 0.17.1)

This results in an error:

 0.02s    error: Falcon::Command [ec=0x328] [pid=95335] [2026-03-31 14:22:47 +0200]
               | path name contains null byte
               |   ArgumentError: path name contains null byte
               |   
               |   			FileUtils.mkdir_p(File.dirname(@path))
               |   			                               ^^^^^
               |   → .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/io-endpoint-0.17.2/lib/io/endpoint/unix_endpoint.rb:121 in 'File.dirname'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/io-endpoint-0.17.2/lib/io/endpoint/unix_endpoint.rb:121 in 'IO::Endpoint::UNIXEndpoint#create_symlink_if_required!'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/io-endpoint-0.17.2/lib/io/endpoint/unix_endpoint.rb:95 in 'IO::Endpoint::UNIXEndpoint#bind'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/async-http-0.88.0/lib/async/http/endpoint.rb:216 in 'Async::HTTP::Endpoint#bind'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/io-endpoint-0.17.2/lib/io/endpoint/bound_endpoint.rb:19 in 'IO::Endpoint::BoundEndpoint.bound'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/io-endpoint-0.17.2/lib/io/endpoint/bound_endpoint.rb:105 in 'IO::Endpoint::Generic#bound'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/falcon-0.51.1/lib/falcon/service/server.rb:42 in 'block in Falcon::Service::Server#start'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/async-2.23.1/lib/async/task.rb:200 in 'block in Async::Task#run'
               |     .local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/async-2.23.1/lib/async/task.rb:438 in 'block in Async::Task#schedule'

I would guess the easiest fix is to never try to do anything on the file system if the first byte of the name is a null byte.

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