Class: EventMachine::SystemCommand

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
EM::Deferrable, EM::SystemCommand::PipeHandler
Defined in:
lib/em-systemcommand.rb,
lib/em-systemcommand/pipe.rb,
lib/em-systemcommand/builder.rb,
lib/em-systemcommand/pipe_handler.rb

Defined Under Namespace

Modules: PipeHandler Classes: Builder, Pipe

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ SystemCommand

Prepares a ‘SystemCommand` object.

An easy way is to use the ‘Builder` idea:

cmd = EM::SystemCommand.new 'echo'
cmd << :n
cmd << 'Some text to put out.'
cmd.execute do |on|
  on.success do
    puts 'Yay!'
  end
end


36
37
38
39
40
41
# File 'lib/em-systemcommand.rb', line 36

def initialize *args, &block
  @pipes = {}
  @command = EM::SystemCommand::Builder.new *args

  @execution_proc = block
end

Instance Attribute Details

#pipesObject

Returns the value of attribute pipes.



20
21
22
# File 'lib/em-systemcommand.rb', line 20

def pipes
  @pipes
end

#stderrObject

Returns the value of attribute stderr.



20
21
22
# File 'lib/em-systemcommand.rb', line 20

def stderr
  @stderr
end

#stdinObject

Returns the value of attribute stdin.



20
21
22
# File 'lib/em-systemcommand.rb', line 20

def stdin
  @stdin
end

#stdoutObject

Returns the value of attribute stdout.



20
21
22
# File 'lib/em-systemcommand.rb', line 20

def stdout
  @stdout
end

Class Method Details

.execute(*args, &block) ⇒ Object

Convinience method to quickly execute a command.



45
46
47
48
# File 'lib/em-systemcommand.rb', line 45

def self.execute *args, &block
  sys_cmd = EM::SystemCommand.new *args, &block
  sys_cmd.execute
end

Instance Method Details

#commandObject

Returns the command string.



54
55
56
# File 'lib/em-systemcommand.rb', line 54

def command
  @command.to_s
end

#execute(&block) ⇒ Object

Executes the command from the ‘Builder` object. If there had been given a block at instantiation it will be called after the `popen3` call and after the pipes have been attached.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/em-systemcommand.rb', line 63

def execute &block
  raise 'Previous process still exists' unless pipes.empty?

  # clear callbacks
  @callbacks = []
  @errbacks = []

  pid, stdin, stdout, stderr = POSIX::Spawn.popen4 @command.to_s

  @pid = pid
  @stdin  = attach_pipe_handler :stdin, stdin
  @stdout = attach_pipe_handler :stdout, stdout
  @stderr = attach_pipe_handler :stderr, stderr

  if block
    block.call self
  elsif @execution_proc
    @execution_proc.call self
  end
  self
end

#exit(&block) ⇒ Object

A method to add a callback for when the process unbinds.



141
142
143
# File 'lib/em-systemcommand.rb', line 141

def exit &block
  exit_callbacks << block
end

#exit_callbacksObject

An array of exit callbacks, being called with ‘status` as parameter when the process is unbound.



148
149
150
# File 'lib/em-systemcommand.rb', line 148

def exit_callbacks
  @exit_callbacks ||= []
end

#kill(signal = 'TERM', wait = false) ⇒ Object

Kills the child process.



130
131
132
133
134
135
136
137
# File 'lib/em-systemcommand.rb', line 130

def kill signal = 'TERM', wait = false
  Process.kill signal, self.pid
  val = status if wait
  @stdin.close
  @stdout.close
  @stderr.close
  val
end

#pidObject

Returns the pid of the child process.



93
94
95
# File 'lib/em-systemcommand.rb', line 93

def pid
  @pid
end

#statusObject

Returns the status object of the popen4 call.



99
100
101
# File 'lib/em-systemcommand.rb', line 99

def status
  @status ||= Process.waitpid2(pid)[1]
end

#unbind(name) ⇒ Object

Called by child pipes when they get unbound.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/em-systemcommand.rb', line 108

def unbind name
  pipes.delete name
  if pipes.empty?
    exit_callbacks.each do |cb|
      EM.next_tick do
        cb.call status
      end
    end
    if status.exitstatus == 0
      EM.next_tick do
        succeed self
      end
    else
      EM.next_tick do
        fail self
      end
    end
  end
end