Class: Shell::SystemCommand

Inherits:
Filter
  • Object
show all
Defined in:
lib/shell/system-command.rb

Instance Attribute Summary collapse

Attributes inherited from Filter

#input

Instance Method Summary collapse

Methods inherited from Filter

#+, #<, #>, #>>, #inspect, #to_a, #to_s, #|

Constructor Details

#initialize(sh, command, *opts) ⇒ SystemCommand

Returns a new instance of SystemCommand.



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/shell/system-command.rb', line 17

def initialize(sh, command, *opts)
  if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
	Shell.Fail Error::TypeError, t.class, "String"
  end
  super(sh)
  @command = command
  @opts = opts
  
  @input_queue = Queue.new
  @pid = nil

  sh.process_controller.add_schedule(self)
end

Instance Attribute Details

#commandObject (readonly) Also known as: name

Returns the value of attribute command.



31
32
33
# File 'lib/shell/system-command.rb', line 31

def command
  @command
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/shell/system-command.rb', line 38

def active?
  @shell.process_controller.active_job?(self)
end

#each(rs = nil) ⇒ Object



144
145
146
147
148
# File 'lib/shell/system-command.rb', line 144

def each(rs = nil)
  while (l = @input_queue.pop) != :EOF
	yield l
  end
end

#flushObject



60
61
62
# File 'lib/shell/system-command.rb', line 60

def flush
  @pipe_out.flush if @pipe_out and !@pipe_out.closed?
end

#input=(inp) ⇒ Object



42
43
44
45
46
47
# File 'lib/shell/system-command.rb', line 42

def input=(inp)
  super
  if active?
	start_export
  end
end

#kill(sig) ⇒ Object



75
76
77
78
79
# File 'lib/shell/system-command.rb', line 75

def kill(sig)
  if @pid
	Process.kill(sig, @pid)
  end
end

#notify(*opts, &block) ⇒ Object

ex)

  if you wish to output: 
   "shell: job(#{@command}:#{@pid}) close pipe-out."
then 
   mes: "job(%id) close pipe-out."
  yorn: Boolean(@shell.debug? or @shell.verbose?)


156
157
158
159
160
161
162
163
164
165
166
# File 'lib/shell/system-command.rb', line 156

def notify(*opts, &block)
  Thread.exclusive do
	@shell.notify(*opts) {|mes|
	  yield mes if iterator?

	  mes.gsub!("%id", "#{@command}:##{@pid}")
	  mes.gsub!("%name", "#{@command}")
	  mes.gsub!("%pid", "#{@pid}")
	}
  end
end

#startObject



49
50
51
52
53
54
55
56
57
58
# File 'lib/shell/system-command.rb', line 49

def start
  @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
	Dir.chdir @shell.pwd
	exec(@command, *@opts)
  }
  if @input
	start_export
  end
  start_import
end

#start_exportObject



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/shell/system-command.rb', line 116

def start_export
  notify "job(%id) start exp-pipe.", @shell.debug?
  _eop = true
  th = Thread.start{
	Thread.critical = true
	begin
	  Thread.critical = false
	  @input.each{|l| @pipe_out.print l}
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
 notify("shell: warn: Process finishing...",
 "wait for Job(%id) to finish pipe exporting.",
 "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
 redo
	  end
	  Thread.exclusive do
 notify "job(%id) close exp-pipe.", @shell.debug?
 @pipe_out.close
	  end
	end
  }
end

#start_importObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/shell/system-command.rb', line 82

def start_import
#      Thread.critical = true
  notify "Job(%id) start imp-pipe.", @shell.debug?
  rs = @shell.record_separator unless rs
  _eop = true
#      Thread.critical = false
  th = Thread.start {
	Thread.critical = true
	begin
	  Thread.critical = false
	  while l = @pipe_in.gets
 @input_queue.push l
	  end
	  _eop = false
	rescue Errno::EPIPE
	  _eop = false
	ensure
	  if _eop
 notify("warn: Process finishing...",
 "wait for Job[%id] to finish pipe importing.",
 "You can use Shell#transact or Shell#check_point for more safe execution.")
#	    Tracer.on
 Thread.current.run
 redo
	  end
	  Thread.exclusive do
 notify "job(%id}) close imp-pipe.", @shell.debug?
 @input_queue.push :EOF
 @pipe_in.close
	  end
	end
  }
end

#super_eachObject



143
# File 'lib/shell/system-command.rb', line 143

alias super_each each

#terminateObject



64
65
66
67
68
69
70
71
72
73
# File 'lib/shell/system-command.rb', line 64

def terminate
  begin
	@pipe_in.close
  rescue IOError
  end
  begin
	@pipe_out.close
  rescue IOError
  end
end

#wait?Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/shell/system-command.rb', line 34

def wait?
  @shell.process_controller.waiting_job?(self)
end