2003-06-18 11:45:12 -04:00
|
|
|
require 'socket'
|
|
|
|
require 'drb/drb'
|
2003-07-21 11:34:18 -04:00
|
|
|
require 'tmpdir'
|
2003-06-18 11:45:12 -04:00
|
|
|
|
2003-10-30 09:43:03 -05:00
|
|
|
raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer)
|
|
|
|
|
2003-06-18 11:45:12 -04:00
|
|
|
module DRb
|
|
|
|
|
2013-01-24 22:25:39 -05: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 11:45:12 -04:00
|
|
|
class DRbUNIXSocket < DRbTCPSocket
|
2013-01-24 22:25:39 -05:00
|
|
|
# :stopdoc:
|
2003-06-18 11:45:12 -04:00
|
|
|
def self.parse_uri(uri)
|
2009-03-05 22:56:38 -05:00
|
|
|
if /^drbunix:(.*?)(\?(.*))?$/ =~ uri
|
2011-05-18 17:19:18 -04:00
|
|
|
filename = $1
|
|
|
|
option = $3
|
|
|
|
[filename, option]
|
2003-06-18 11:45:12 -04:00
|
|
|
else
|
2011-05-18 17:19:18 -04:00
|
|
|
raise(DRbBadScheme, uri) unless uri =~ /^drbunix:/
|
2011-05-18 20:07:25 -04:00
|
|
|
raise(DRbBadURI, 'can\'t parse uri:' + uri)
|
2003-06-18 11:45:12 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.open(uri, config)
|
2010-11-08 15:59:01 -05:00
|
|
|
filename, = parse_uri(uri)
|
2003-06-18 11:45:12 -04:00
|
|
|
filename.untaint
|
|
|
|
soc = UNIXSocket.open(filename)
|
|
|
|
self.new(uri, soc, config)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.open_server(uri, config)
|
2010-11-08 15:59:01 -05:00
|
|
|
filename, = parse_uri(uri)
|
2003-06-18 11:45:12 -04:00
|
|
|
if filename.size == 0
|
2011-05-18 17:19:18 -04:00
|
|
|
soc = temp_server
|
2005-01-22 08:37:37 -05:00
|
|
|
filename = soc.path
|
2011-05-18 17:19:18 -04:00
|
|
|
uri = 'drbunix:' + soc.path
|
2003-06-18 11:45:12 -04:00
|
|
|
else
|
2011-05-18 17:19:18 -04:00
|
|
|
soc = UNIXServer.open(filename)
|
2003-06-18 11:45:12 -04:00
|
|
|
end
|
2003-07-26 21: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 11: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-05 22:56:38 -05:00
|
|
|
|
2003-06-18 11:45:12 -04:00
|
|
|
# import from tempfile.rb
|
|
|
|
Max_try = 10
|
|
|
|
private
|
|
|
|
def self.temp_server
|
2003-07-23 12:37:35 -04:00
|
|
|
tmpdir = Dir::tmpdir
|
2003-06-18 11:45:12 -04:00
|
|
|
n = 0
|
|
|
|
while true
|
2011-05-18 17: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 11:45:12 -04:00
|
|
|
end
|
|
|
|
soc = UNIXServer.new(tmpname)
|
|
|
|
Dir.rmdir(lock)
|
|
|
|
soc
|
|
|
|
end
|
|
|
|
|
|
|
|
public
|
|
|
|
def close
|
|
|
|
return unless @socket
|
2007-11-19 13:30:18 -05:00
|
|
|
path = @socket.path if @server_mode
|
2003-06-18 11:45:12 -04:00
|
|
|
@socket.close
|
|
|
|
File.unlink(path) if @server_mode
|
|
|
|
@socket = nil
|
2014-09-21 13:06:05 -04:00
|
|
|
close_shutdown_pipe
|
2003-06-18 11:45:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def accept
|
2014-09-21 13:06:05 -04:00
|
|
|
s = accept_or_shutdown
|
|
|
|
return nil unless s
|
2003-06-18 11:45:12 -04:00
|
|
|
self.class.new(nil, s, @config)
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_sockopt(soc)
|
2011-11-01 19:17:53 -04:00
|
|
|
soc.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::FD_CLOEXEC
|
2003-06-18 11:45:12 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
DRbProtocol.add_protocol(DRbUNIXSocket)
|
2013-01-24 22:25:39 -05:00
|
|
|
# :startdoc:
|
2003-06-18 11:45:12 -04:00
|
|
|
end
|