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