class DBus::MessageQueue

Constants

MSG_BUF_SIZE

The buffer size for messages.

Attributes

socket[R]

The socket that is used to connect with the bus.

Public Class Methods

new(address) click to toggle source
# File lib/dbus/message_queue.rb, line 18
def initialize(address)
  @address = address
  @buffer = ""
  @is_tcp = false
  connect
end

Public Instance Methods

<<(message)
Alias for: push
buffer_from_socket_nonblock() click to toggle source

Fill (append) the buffer from data that might be available on the socket. EOFError may be raised

# File lib/dbus/message_queue.rb, line 153
def buffer_from_socket_nonblock
  @buffer += @socket.read_nonblock(MSG_BUF_SIZE)
rescue EOFError
  raise                     # the caller expects it
rescue Errno::EAGAIN
  # fine, would block
rescue Exception => e
  puts "Oops:", e
  raise if @is_tcp          # why?
  puts "WARNING: read_nonblock failed, falling back to .recv"
  @buffer += @socket.recv(MSG_BUF_SIZE)
end
message_from_buffer_nonblock() click to toggle source

Get and remove one message from the buffer. Return the message or nil.

# File lib/dbus/message_queue.rb, line 135
def message_from_buffer_nonblock
  return nil if @buffer.empty?
  ret = nil
  begin
    ret, size = Message.new.unmarshall_buffer(@buffer)
    @buffer.slice!(0, size)
  rescue IncompleteBufferException
    # fall through, let ret be null
  end
  ret
end
pop(non_block = false) click to toggle source

TODO failure modes

If non_block is true, return nil instead of waiting EOFError may be raised

# File lib/dbus/message_queue.rb, line 29
def pop(non_block = false)
  buffer_from_socket_nonblock
  message = message_from_buffer_nonblock
  unless non_block
    # we can block
    while message.nil?
      r, d, d = IO.select([@socket])
      if r and r[0] == @socket
        buffer_from_socket_nonblock
        message = message_from_buffer_nonblock
      end
    end
  end
  message
end
push(message) click to toggle source
# File lib/dbus/message_queue.rb, line 45
def push(message)
  @socket.write(message.marshall)
end
Also aliased as: <<

Private Instance Methods

connect() click to toggle source

Connect to the bus and initialize the connection.

# File lib/dbus/message_queue.rb, line 53
def connect
  addresses = @address.split ";"
  # connect to first one that succeeds
  worked = addresses.find do |a|
    transport, keyvaluestring = a.split ":"
    kv_list = keyvaluestring.split ","
    kv_hash = Hash.new
    kv_list.each do |kv|
      key, escaped_value = kv.split "="
      value = escaped_value.gsub(/%(..)/) {|m| [$1].pack "H2" }
      kv_hash[key] = value
    end
    case transport
      when "unix"
      connect_to_unix kv_hash
      when "tcp"
      connect_to_tcp kv_hash
      when "launchd"
      connect_to_launchd kv_hash
      else
      # ignore, report?
    end
  end
  worked
  # returns the address that worked or nil.
  # how to report failure?
end
connect_to_launchd(params) click to toggle source
# File lib/dbus/message_queue.rb, line 119
def connect_to_launchd(params)
  socket_var = params['env']
  socket = %x`launchctl getenv #{socket_var}`.chomp
  connect_to_unix 'path' => socket
end
connect_to_tcp(params) click to toggle source

Connect to a bus over tcp and initialize the connection.

# File lib/dbus/message_queue.rb, line 82
def connect_to_tcp(params)
  #check if the path is sufficient
  if params.key?("host") and params.key?("port")
    begin
      #initialize the tcp socket
      @socket = TCPSocket.new(params["host"],params["port"].to_i)
      @socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
      init_connection
      @is_tcp = true
    rescue Exception => e
      puts "Oops:", e
      puts "Error: Could not establish connection to: #{@path}, will now exit."
      exit(1) #a little harsh
    end
  else
    #Danger, Will Robinson: the specified "path" is not usable
    puts "Error: supplied path: #{@path}, unusable! sorry."
  end
end
connect_to_unix(params) click to toggle source

Connect to an abstract unix bus and initialize the connection.

# File lib/dbus/message_queue.rb, line 103
def connect_to_unix(params)
  @socket = Socket.new(Socket::Constants::PF_UNIX,Socket::Constants::SOCK_STREAM, 0)
  @socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
  if ! params['abstract'].nil?
    if HOST_END == LIL_END
      sockaddr = "\1\0\0#{params['abstract']}"
    else
      sockaddr = "\0\1\0#{params['abstract']}"
    end
  elsif ! params['path'].nil?
    sockaddr = Socket.pack_sockaddr_un(params['path'])
  end
  @socket.connect(sockaddr)
  init_connection
end
init_connection() click to toggle source

Initialize the connection to the bus.

# File lib/dbus/message_queue.rb, line 126
def init_connection
  @client = Client.new(@socket)
  @client.authenticate
end