Class: Appear::Lsof

Inherits:
Service show all
Defined in:
lib/appear/lsof.rb

Overview

The LSOF service co-ordinates access to the ‘lsof` system utility. LSOF stands for “list open files”. It can read the “connections” various programs have to a given file, eg, what programs have a file descriptor for a file.

Defined Under Namespace

Classes: Connection, PaneConnection

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from BaseService

delegate, require_service, required_services

Constructor Details

#initialize(*args) ⇒ Lsof

Returns a new instance of Lsof.



82
83
84
85
# File 'lib/appear/lsof.rb', line 82

def initialize(*args)
  super(*args)
  @lsof_memo = Util::Memoizer.new
end

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



15
16
17
# File 'lib/appear/lsof.rb', line 15

def cache
  @cache
end

Instance Method Details

#join_via_tty(tree, panes) ⇒ Array<PaneConnection>

find any intersections where a process in the given tree is present in one of the terminal emulator panes. Performs an LSOF lookup on the TTY of each pane. Returns cases where one of the panes’ ttys also have a connection from a process in the process tree.

This is much faster if each pane includes a .pids method that returns an array of PIDs that could be the PID of the terminal emulator with that pane

Parameters:

  • tree (Array<Process>)
  • panes (Array<Pane>)

Returns:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/appear/lsof.rb', line 98

def join_via_tty(tree, panes)
  hitlist = {}
  tree.each do |process|
    hitlist[process.pid] = process
  end

  ttys = panes.map(&:tty)
  if panes.all? {|p| p.respond_to?(:pids) }
    pids = hitlist.keys + panes.map(&:pids).flatten
    lsofs = lsofs(ttys, :pids => pids)
  else
    lsofs = lsofs(ttys)
  end

  hits = {}
  panes.each do |pane|
    connections = lsofs[pane.tty]
    connections.each do |conn|
      process = hitlist[conn.pid]
      if process
        hits[conn.pid] = PaneConnection.new(pane, conn, process)
      end
    end
  end

  hits.values
end

#lsofs(files, opts = {}) ⇒ Hash<String, Array<Connection>>

list connections to files.

Parameters:

  • files (Array<String>)

    files to query

Returns:

  • (Hash<String, Array<Connection>>)

    map of filename to connections



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/appear/lsof.rb', line 130

def lsofs(files, opts = {})
  mutex = Mutex.new
  results = {}
  threads = files.map do |file|
    Thread.new do
      single_result = lsof(file, opts)
      mutex.synchronize do
        results[file] = single_result
      end
    end
  end
  threads.each { |t| t.join }
  results
end