- require IO::Socket::INET6; # works for IPv4, too
- my %o = (
- LocalAddr => $l,
- ReuseAddr => 1,
- Proto => 'tcp',
- );
- if (my $s = IO::Socket::INET6->new(%o)) {
+ my (%o, $sock_pkg);
+ if (index($l, '/') == 0) {
+ $sock_pkg = 'IO::Socket::UNIX';
+ eval "use $sock_pkg";
+ die $@ if $@;
+ %o = (Type => SOCK_STREAM, Peer => $l);
+ if (-S $l) {
+ my $c = $sock_pkg->new(%o);
+ if (!defined($c) && $!{ECONNREFUSED}) {
+ unlink $l or die
+"failed to unlink stale socket=$l: $!\n";
+ } # else: let the bind fail
+ }
+ $o{Local} = delete $o{Peer};
+ } else {
+ # both work for IPv4, too
+ for (qw(IO::Socket::IP IO::Socket::INET6)) {
+ $sock_pkg = $_;
+ eval "use $sock_pkg";
+ $@ or last;
+ }
+ die $@ if $@;
+ %o = (LocalAddr => $l, ReuseAddr => 1, Proto => 'tcp');
+ }
+ $o{Listen} = 1024;
+ my $prev = umask 0000;
+ my $s = eval { $sock_pkg->new(%o) };
+ warn "error binding $l: $! ($@)\n" unless $s;
+ umask $prev;
+
+ if ($s) {