Class: Mach::Port

Inherits:
Object
  • Object
show all
Includes:
Functions
Defined in:
lib/mach/port.rb

Overview

Michael Weber's "Some Fun with Mach Ports" was an indispensable resource in learning the Mach ports API.

Direct Known Subclasses

Host, Semaphore, Task

Defined Under Namespace

Classes: ReceiveRightMsg, SendRightMsg

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Functions

attach_mach_function, error_check, error_check_bootstrap, new_memory_pointer, #new_memory_pointer

Methods included from Types

#enum, #find_type, typedefs

Constructor Details

#initialize(opts = {}) ⇒ Port

is wrapped in a new Port object; otherwise a new port is allocated according to the other options

Parameters:

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :ipc_space (Integer)

    defaults to +mach_task_self+

  • :right (MachPortRight)

    defaults to +:receive+

  • :port (Port, Integer)

    if given, the existing port



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/mach/port.rb', line 40

def initialize(opts = {})
  @ipc_space = opts[:ipc_space] || mach_task_self
  right = opts[:right] || :receive

  @port = if opts[:port]
            opts[:port].to_i
          else
            mem = new_memory_pointer(:mach_port_right_t)
            mach_port_allocate(@ipc_space.to_i, right, mem)
            mem.get_uint(0)
          end
end

Instance Attribute Details

#ipc_spaceObject (readonly)

Returns the value of attribute ipc_space



29
30
31
# File 'lib/mach/port.rb', line 29

def ipc_space
  @ipc_space
end

#portObject (readonly) Also known as: to_i

Returns the value of attribute port



29
30
31
# File 'lib/mach/port.rb', line 29

def port
  @port
end

Instance Method Details

#==(other) ⇒ Object



62
63
64
# File 'lib/mach/port.rb', line 62

def ==(other)
  (port == other.port) && (ipc_space == other.ipc_space)
end

#copy_send(remote_port) ⇒ Object

Copy the send right on this port and send it in a message to +remote_port+. The current task must have an existing send right on this Port.



123
124
125
# File 'lib/mach/port.rb', line 123

def copy_send(remote_port)
  send_right(:copy_send, remote_port)
end

#deallocate(opts = {}) ⇒ Object



71
72
73
74
# File 'lib/mach/port.rb', line 71

def deallocate(opts = {})
  ipc_space = opts[:ipc_space] || @ipc_space
  mach_port_deallocate(ipc_space.to_i, @port)
end

#destroy(opts = {}) ⇒ Object



66
67
68
69
# File 'lib/mach/port.rb', line 66

def destroy(opts = {})
  ipc_space = opts[:ipc_space] || @ipc_space
  mach_port_destroy(ipc_space, @port)
end

#insert_right(right, opts = {}) ⇒ Object

Insert +right+ into another ipc space. The current task must have sufficient rights to insert the requested right.

+right+ will be inserted; defaults to this port's ipc_space

have in :ipc_space; defaults to the same name as this port

Parameters:

  • right (MsgType)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :ipc_space (Port, Integer)

    the space (task port) into which

  • :port (Port, Integer)

    the name the port right should



88
89
90
91
92
93
# File 'lib/mach/port.rb', line 88

def insert_right(right, opts = {})
  ipc_space = opts[:ipc_space] || @ipc_space
  port_name = opts[:port_name] || @port
  
  mach_port_insert_right(ipc_space.to_i, port_name.to_i, @port, right)
end

#receive_rightObject

Create a new Port by receiving a port right message on this port.



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/mach/port.rb', line 129

def receive_right
  msg = ReceiveRightMsg.new
  
  mach_msg(msg,
           2, # RCV_MSG,
           0,
           msg.size,
           port,
           MSG_TIMEOUT_NONE,
           PORT_NULL)

  self.class.new :port => msg[:port][:name]
end

#send_right(right, remote_port) ⇒ Object

Send +right+ on this Port to +remote_port+. The current task must already have the requisite rights allowing it to send +right+.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/mach/port.rb', line 98

def send_right(right, remote_port)
  msg = SendRightMsg.new

  msg[:header].tap do |h|
    h[:remote_port] = remote_port.to_i
    h[:local_port] = PORT_NULL
    h[:bits] =
      (MsgType[right] | (0 << 8)) | 0x80000000 # MACH_MSGH_BITS_COMPLEX
    h[:size] = 40 # msg.size
  end

  msg[:body][:descriptor_count] = 1

  msg[:port].tap do |p|
    p[:name] = port
    p[:disposition] = MsgType[right]
    p[:type] = 0 # MSG_PORT_DESCRIPTOR;
  end
  
  mach_msg_send msg
end

#to_sObject



58
59
60
# File 'lib/mach/port.rb', line 58

def to_s
  "#<#{self.class} #{to_i}>"
end