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