2015-12-16 08:07:31 +03:00
|
|
|
# frozen_string_literal: false
|
2003-06-18 19:45:12 +04:00
|
|
|
require 'socket'
|
2018-11-02 20:52:33 +03:00
|
|
|
require_relative 'drb'
|
2003-07-21 19:34:18 +04:00
|
|
|
require 'tmpdir'
|
2003-06-18 19:45:12 +04:00
|
|
|
|
2003-10-30 17:43:03 +03:00
|
|
|
raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer)
|
|
|
|
|
2003-06-18 19:45:12 +04:00
|
|
|
module DRb
|
|
|
|
|
2013-01-25 07:25:39 +04:00
|
|
|
# Implements DRb over a UNIX socket
|
|
|
|
#
|
|
|
|
# DRb UNIX socket URIs look like <code>drbunix:<path>?<option></code>. The
|
|
|
|
# option is optional.
|
|
|
|
|
2003-06-18 19:45:12 +04:00
|
|
|
class DRbUNIXSocket < DRbTCPSocket
|
2013-01-25 07:25:39 +04:00
|
|
|
# :stopdoc:
|
2003-06-18 19:45:12 +04:00
|
|
|
def self.parse_uri(uri)
|
2017-12-30 15:10:43 +03:00
|
|
|
if /\Adrbunix:(.*?)(\?(.*))?\z/ =~ uri
|
2011-05-19 01:19:18 +04:00
|
|
|
filename = $1
|
|
|
|
option = $3
|
|
|
|
[filename, option]
|
2003-06-18 19:45:12 +04:00
|
|
|
else
|
2017-12-30 15:10:43 +03:00
|
|
|
raise(DRbBadScheme, uri) unless uri.start_with?('drbunix:')
|
2011-05-19 04:07:25 +04:00
|
|
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.open(uri, config)
|
2010-11-08 23:59:01 +03:00
|
|
|
filename, = parse_uri(uri)
|
2003-06-18 19:45:12 +04:00
|
|
|
soc = UNIXSocket.open(filename)
|
|
|
|
self.new(uri, soc, config)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.open_server(uri, config)
|
2010-11-08 23:59:01 +03:00
|
|
|
filename, = parse_uri(uri)
|
2003-06-18 19:45:12 +04:00
|
|
|
if filename.size == 0
|
2011-05-19 01:19:18 +04:00
|
|
|
soc = temp_server
|
2005-01-22 16:37:37 +03:00
|
|
|
filename = soc.path
|
2011-05-19 01:19:18 +04:00
|
|
|
uri = 'drbunix:' + soc.path
|
2003-06-18 19:45:12 +04:00
|
|
|
else
|
2011-05-19 01:19:18 +04:00
|
|
|
soc = UNIXServer.open(filename)
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|
2003-07-27 05:25:58 +04:00
|
|
|
owner = config[:UNIXFileOwner]
|
|
|
|
group = config[:UNIXFileGroup]
|
|
|
|
if owner || group
|
|
|
|
require 'etc'
|
|
|
|
owner = Etc.getpwnam( owner ).uid if owner
|
|
|
|
group = Etc.getgrnam( group ).gid if group
|
|
|
|
File.chown owner, group, filename
|
|
|
|
end
|
2003-06-18 19:45:12 +04:00
|
|
|
mode = config[:UNIXFileMode]
|
|
|
|
File.chmod(mode, filename) if mode
|
|
|
|
|
|
|
|
self.new(uri, soc, config, true)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.uri_option(uri, config)
|
|
|
|
filename, option = parse_uri(uri)
|
|
|
|
return "drbunix:#{filename}", option
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(uri, soc, config={}, server_mode = false)
|
|
|
|
super(uri, soc, config)
|
|
|
|
set_sockopt(@socket)
|
|
|
|
@server_mode = server_mode
|
|
|
|
@acl = nil
|
|
|
|
end
|
2009-03-06 06:56:38 +03:00
|
|
|
|
2003-06-18 19:45:12 +04:00
|
|
|
# import from tempfile.rb
|
|
|
|
Max_try = 10
|
|
|
|
private
|
|
|
|
def self.temp_server
|
2003-07-23 20:37:35 +04:00
|
|
|
tmpdir = Dir::tmpdir
|
2003-06-18 19:45:12 +04:00
|
|
|
n = 0
|
|
|
|
while true
|
2011-05-19 01:19:18 +04:00
|
|
|
begin
|
|
|
|
tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n)
|
|
|
|
lock = tmpname + '.lock'
|
|
|
|
unless File.exist?(tmpname) or File.exist?(lock)
|
|
|
|
Dir.mkdir(lock)
|
|
|
|
break
|
|
|
|
end
|
|
|
|
rescue
|
|
|
|
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
|
|
|
#sleep(1)
|
|
|
|
end
|
|
|
|
n += 1
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|
|
|
|
soc = UNIXServer.new(tmpname)
|
|
|
|
Dir.rmdir(lock)
|
|
|
|
soc
|
|
|
|
end
|
|
|
|
|
|
|
|
public
|
|
|
|
def close
|
|
|
|
return unless @socket
|
2018-08-25 05:32:15 +03:00
|
|
|
shutdown # DRbProtocol#shutdown
|
2007-11-19 21:30:18 +03:00
|
|
|
path = @socket.path if @server_mode
|
2003-06-18 19:45:12 +04:00
|
|
|
@socket.close
|
|
|
|
File.unlink(path) if @server_mode
|
|
|
|
@socket = nil
|
2014-09-21 21:06:05 +04:00
|
|
|
close_shutdown_pipe
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
def accept
|
2014-09-21 21:06:05 +04:00
|
|
|
s = accept_or_shutdown
|
|
|
|
return nil unless s
|
2003-06-18 19:45:12 +04:00
|
|
|
self.class.new(nil, s, @config)
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_sockopt(soc)
|
2015-05-27 03:43:02 +03:00
|
|
|
# no-op for now
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
DRbProtocol.add_protocol(DRbUNIXSocket)
|
2013-01-25 07:25:39 +04:00
|
|
|
# :startdoc:
|
2003-06-18 19:45:12 +04:00
|
|
|
end
|