summaryrefslogtreecommitdiff
path: root/lib/shell
diff options
context:
space:
mode:
Diffstat (limited to 'lib/shell')
-rw-r--r--lib/shell/builtin-command.rb40
-rw-r--r--lib/shell/command-processor.rb157
-rw-r--r--lib/shell/error.rb11
-rw-r--r--lib/shell/filter.rb13
-rw-r--r--lib/shell/process-controller.rb173
-rw-r--r--lib/shell/system-command.rb73
-rw-r--r--lib/shell/version.rb13
7 files changed, 267 insertions, 213 deletions
diff --git a/lib/shell/builtin-command.rb b/lib/shell/builtin-command.rb
index 02025c5d42..e489da4eca 100644
--- a/lib/shell/builtin-command.rb
+++ b/lib/shell/builtin-command.rb
@@ -1,13 +1,12 @@
#
-# shell/builtin-command.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.1 $
-# $Date: 2001/05/17 10:02:48 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# shell/builtin-command.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
require "shell/filter"
@@ -22,12 +21,22 @@ class Shell
end
end
+ class Void < BuiltInCommand
+ def initialize(sh, *opts)
+ super sh
+ end
+
+ def each(rs = nil)
+ # do nothing
+ end
+ end
+
class Echo < BuiltInCommand
def initialize(sh, *strings)
super sh
@strings = strings
end
-
+
def each(rs = nil)
rs = @shell.record_separator unless rs
for str in @strings
@@ -58,20 +67,17 @@ class Shell
super sh
@pattern = pattern
- Thread.critical = true
- back = Dir.pwd
- begin
- Dir.chdir @shell.cwd
- @files = Dir[pattern]
- ensure
- Dir.chdir back
- Thread.critical = false
- end
end
def each(rs = nil)
+ if @pattern[0] == ?/
+ @files = Dir[@pattern]
+ else
+ prefix = @shell.pwd+"/"
+ @files = Dir[prefix+@pattern].collect{|p| p.sub(prefix, "")}
+ end
rs = @shell.record_separator unless rs
- for f in @files
+ for f in @files
yield f+rs
end
end
diff --git a/lib/shell/command-processor.rb b/lib/shell/command-processor.rb
index f08440e457..f3f2bf05b6 100644
--- a/lib/shell/command-processor.rb
+++ b/lib/shell/command-processor.rb
@@ -1,17 +1,15 @@
#
-# shell/command-controller.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.8.2.2 $
-# $Date: 2004/04/18 23:20:33 $
-# by Keiju ISHITSUKA(Nippon Rational Inc.)
+# shell/command-controller.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
require "e2mmap"
-require "ftools"
require "thread"
require "shell/error"
@@ -26,16 +24,22 @@ class Shell
#
# initialize of Shell and related classes.
#
- NoDelegateMethods = ["initialize", "expand_path"]
+ m = [:initialize, :expand_path]
+ if Object.methods.first.kind_of?(String)
+ NoDelegateMethods = m.collect{|x| x.id2name}
+ else
+ NoDelegateMethods = m
+ end
+
def self.initialize
install_builtin_commands
- # define CommandProccessor#methods to Shell#methods and Filter#methods
+ # define CommandProcessor#methods to Shell#methods and Filter#methods
for m in CommandProcessor.instance_methods(false) - NoDelegateMethods
add_delegate_command_to_shell(m)
end
-
+
def self.method_added(id)
add_delegate_command_to_shell(id)
end
@@ -80,7 +84,7 @@ class Shell
# Shell#test
#
# -
- #
+ #
# CommandProcessor#foreach(path, rs)
# path: String
# rs: String - record separator
@@ -111,13 +115,20 @@ class Shell
# Dir#open (when path is directory)
# mode has an effect only when path is a file
#
- def open(path, mode)
+ def open(path, mode = nil, perm = 0666, &b)
path = expand_path(path)
if File.directory?(path)
- Dir.open(path)
+ Dir.open(path, &b)
else
- effect_umask do
- File.open(path, mode)
+ if @shell.umask
+ f = File.open(path, mode, perm)
+ File.chmod(perm & ~@shell.umask, path)
+ if block_given?
+ f.each(&b)
+ end
+ f
+ else
+ f = File.open(path, mode, perm, &b)
end
end
end
@@ -130,12 +141,15 @@ class Shell
# File#unlink (when path is file)
#
def unlink(path)
+ @shell.check_point
+
path = expand_path(path)
if File.directory?(path)
Dir.unlink(path)
else
IO.unlink(path)
end
+ Void.new(@shell)
end
#
@@ -154,7 +168,8 @@ class Shell
# sh["e", "foo"]
# sh[:exists?, "foo"]
# sh["exists?", "foo"]
- #
+ #
+ alias top_level_test test
def test(command, file1, file2=nil)
file1 = expand_path(file1)
file2 = expand_path(file2) if file2
@@ -162,7 +177,11 @@ class Shell
case command
when Integer
- top_level_test(command, file1, file2)
+ if file2
+ top_level_test(command, file1, file2)
+ else
+ top_level_test(command, file1)
+ end
when String
if command.size == 1
if file2
@@ -192,22 +211,40 @@ class Shell
# CommandProcessor#mkdir(*path)
# path: String
# same as Dir.mkdir()
- #
+ #
def mkdir(*path)
+ @shell.check_point
+ notify("mkdir #{path.join(' ')}")
+
+ perm = nil
+ if path.last.kind_of?(Integer)
+ perm = path.pop
+ end
for dir in path
- Dir.mkdir(expand_path(dir))
+ d = expand_path(dir)
+ if perm
+ Dir.mkdir(d, perm)
+ else
+ Dir.mkdir(d)
+ end
+ File.chmod(d, 0666 & ~@shell.umask) if @shell.umask
end
+ Void.new(@shell)
end
#
# CommandProcessor#rmdir(*path)
# path: String
# same as Dir.rmdir()
- #
+ #
def rmdir(*path)
+ @shell.check_point
+ notify("rmdir #{path.join(' ')}")
+
for dir in path
Dir.rmdir(expand_path(dir))
end
+ Void.new(@shell)
end
#
@@ -219,7 +256,7 @@ class Shell
# example:
# print sh.system("ls", "-l")
# sh.system("ls", "-l") | sh.head > STDOUT
- #
+ #
def system(command, *opts)
if opts.empty?
if command =~ /\*|\?|\{|\}|\[|\]|<|>|\(|\)|~|&|\||\\|\$|;|'|`|"|\n/
@@ -299,35 +336,17 @@ class Shell
# %pwd, %cwd -> @pwd
def notify(*opts, &block)
- Thread.exclusive do
- Shell.notify(*opts) {|mes|
- yield mes if iterator?
-
- mes.gsub!("%pwd", "#{@cwd}")
- mes.gsub!("%cwd", "#{@cwd}")
- }
- end
+ Shell.notify(*opts) {|mes|
+ yield mes if iterator?
+
+ mes.gsub!("%pwd", "#{@cwd}")
+ mes.gsub!("%cwd", "#{@cwd}")
+ }
end
#
# private functions
#
- def effect_umask
- if @shell.umask
- Thread.critical = true
- save = File.umask
- begin
- yield
- ensure
- File.umask save
- Thread.critical = false
- end
- else
- yield
- end
- end
- private :effect_umask
-
def find_system_command(command)
return command if /^\// =~ command
case path = @system_commands[command]
@@ -343,7 +362,7 @@ class Shell
for p in @shell.system_path
path = join(p, command)
- if FileTest.exists?(path)
+ if FileTest.exist?(path)
@system_commands[command] = path
return path
end
@@ -364,10 +383,10 @@ class Shell
SystemCommand.new(@shell, '#{path}', *opts)
end]), nil, __FILE__, __LINE__ - 1)
rescue SyntaxError
- Shell.notify "warn: Can't define #{command} path: #{path}."
+ Shell.notify "warn: Can't define #{command} path: #{path}."
end
Shell.notify "Define #{command} path: #{path}.", Shell.debug?
- Shell.notify("Definition of #{command}: ", d,
+ Shell.notify("Definition of #{command}: ", d,
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
end
@@ -399,7 +418,7 @@ class Shell
@shell.__send__(:#{command},
*(CommandProcessor.alias_map[:#{ali}].call *opts))
end]), nil, __FILE__, __LINE__ - 1)
-
+
else
args = opts.collect{|opt| '"' + opt + '"'}.join(",")
eval((d = %Q[def #{ali}(*opts)
@@ -407,22 +426,22 @@ class Shell
end]), nil, __FILE__, __LINE__ - 1)
end
rescue SyntaxError
- Shell.notify "warn: Can't alias #{ali} command: #{command}."
+ Shell.notify "warn: Can't alias #{ali} command: #{command}."
Shell.notify("Definition of #{ali}: ", d)
raise
end
Shell.notify "Define #{ali} command: #{command}.", Shell.debug?
- Shell.notify("Definition of #{ali}: ", d,
+ Shell.notify("Definition of #{ali}: ", d,
Shell.debug.kind_of?(Integer) && Shell.debug > 1)
self
end
-
+
def self.unalias_command(ali)
ali = ali.id2name if ali.kind_of?(Symbol)
@alias_map.delete ali.intern
undef_system_command(ali)
end
-
+
#
# CommandProcessor.def_builtin_commands(delegation_class, command_specs)
# delegation_class: Class or Module
@@ -453,8 +472,8 @@ class Shell
#{delegation_class}.#{meth}(#{call_arg_str})
end]
Shell.notify "Define #{meth}(#{arg_str})", Shell.debug?
- Shell.notify("Definition of #{meth}: ", d,
- Shell.debug.kind_of?(Integer) && Shell.debug > 1)
+ Shell.notify("Definition of #{meth}: ", d,
+ Shell.debug.kind_of?(Integer) && Shell.debug > 1)
eval d
end
end
@@ -494,14 +513,14 @@ class Shell
#----------------------------------------------------------------------
#
- # class initializing methods -
+ # class initializing methods -
#
#----------------------------------------------------------------------
def self.add_delegate_command_to_shell(id)
id = id.intern if id.kind_of?(String)
name = id.id2name
if Shell.method_defined?(id)
- Shell.notify "warn: override definnition of Shell##{name}."
+ Shell.notify "warn: override definition of Shell##{name}."
Shell.notify "warn: alias Shell##{name} to Shell##{name}_org.\n"
Shell.module_eval "alias #{name}_org #{name}"
end
@@ -517,7 +536,7 @@ class Shell
end], __FILE__, __LINE__)
if Shell::Filter.method_defined?(id)
- Shell.notify "warn: override definnition of Shell::Filter##{name}."
+ Shell.notify "warn: override definition of Shell::Filter##{name}."
Shell.notify "warn: alias Shell##{name} to Shell::Filter##{name}_org."
Filter.module_eval "alias #{name}_org #{name}"
end
@@ -542,7 +561,7 @@ class Shell
normal_delegation_file_methods = [
["atime", ["FILENAME"]],
["basename", ["fn", "*opts"]],
- ["chmod", ["mode", "*FILENAMES"]],
+ ["chmod", ["mode", "*FILENAMES"]],
["chown", ["owner", "group", "*FILENAME"]],
["ctime", ["FILENAMES"]],
["delete", ["*FILENAMES"]],
@@ -565,27 +584,9 @@ class Shell
alias_method :rm, :delete
# method related FileTest
- def_builtin_commands(FileTest,
+ def_builtin_commands(FileTest,
FileTest.singleton_methods(false).collect{|m| [m, ["FILENAME"]]})
- # method related ftools
- normal_delegation_ftools_methods = [
- ["syscopy", ["FILENAME_FROM", "FILENAME_TO"]],
- ["copy", ["FILENAME_FROM", "FILENAME_TO"]],
- ["move", ["FILENAME_FROM", "FILENAME_TO"]],
- ["compare", ["FILENAME_FROM", "FILENAME_TO"]],
- ["safe_unlink", ["*FILENAMES"]],
- ["makedirs", ["*FILENAMES"]],
- # ["chmod", ["mode", "*FILENAMES"]],
- ["install", ["FILENAME_FROM", "FILENAME_TO", "mode"]],
- ]
- def_builtin_commands(File,
- normal_delegation_ftools_methods)
- alias_method :cmp, :compare
- alias_method :mv, :move
- alias_method :cp, :copy
- alias_method :rm_f, :safe_unlink
- alias_method :mkpath, :makedirs
end
end
diff --git a/lib/shell/error.rb b/lib/shell/error.rb
index 2f176862a8..dbb788a6fc 100644
--- a/lib/shell/error.rb
+++ b/lib/shell/error.rb
@@ -1,13 +1,12 @@
#
-# shell/error.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.2 $
-# $Date: 2003/02/07 19:00:21 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# shell/error.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
require "e2mmap"
diff --git a/lib/shell/filter.rb b/lib/shell/filter.rb
index 12cc5206f8..3f88d0f5d2 100644
--- a/lib/shell/filter.rb
+++ b/lib/shell/filter.rb
@@ -1,13 +1,12 @@
#
-# shell/filter.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.3.2.1 $
-# $Date: 2004/03/21 12:21:11 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# shell/filter.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
class Shell
@@ -29,7 +28,7 @@ class Shell
def input=(filter)
@input = filter
end
-
+
def each(rs = nil)
rs = @shell.record_separator unless rs
if @input
diff --git a/lib/shell/process-controller.rb b/lib/shell/process-controller.rb
index 573edb6829..2198b88d51 100644
--- a/lib/shell/process-controller.rb
+++ b/lib/shell/process-controller.rb
@@ -1,33 +1,37 @@
#
-# shell/process-controller.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.3 $
-# $Date: 2003/10/16 17:47:19 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# shell/process-controller.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
#
+#
+require "forwardable"
-require "mutex_m"
-require "monitor"
+require "thread"
require "sync"
class Shell
class ProcessController
@ProcessControllers = {}
- @ProcessControllers.extend Mutex_m
+ @ProcessControllersMonitor = Mutex.new
+ @ProcessControllersCV = ConditionVariable.new
- class<<self
+ @BlockOutputMonitor = Mutex.new
+ @BlockOutputCV = ConditionVariable.new
- def process_controllers_exclusive
- begin
- @ProcessControllers.lock unless Thread.critical
- yield
- ensure
- @ProcessControllers.unlock unless Thread.critical
+ class << self
+ extend Forwardable
+
+ def_delegator("@ProcessControllersMonitor",
+ "synchronize", "process_controllers_exclusive")
+
+ def active_process_controllers
+ process_controllers_exclusive do
+ @ProcessControllers.dup
end
end
@@ -43,6 +47,7 @@ class Shell
if @ProcessControllers[pc]
if (@ProcessControllers[pc] -= 1) == 0
@ProcessControllers.delete(pc)
+ @ProcessControllersCV.signal
end
end
end
@@ -55,6 +60,34 @@ class Shell
end
end
end
+
+ def block_output_synchronize(&b)
+ @BlockOutputMonitor.synchronize(&b)
+ end
+
+ def wait_to_finish_all_process_controllers
+ process_controllers_exclusive do
+ while !@ProcessControllers.empty?
+ Shell::notify("Process finishing, but active shell exists",
+ "You can use Shell#transact or Shell#check_point for more safe execution.")
+ if Shell.debug?
+ for pc in @ProcessControllers.keys
+ Shell::notify(" Not finished jobs in "+pc.shell.to_s)
+ for com in pc.jobs
+ com.notify(" Jobs: %id")
+ end
+ end
+ end
+ @ProcessControllersCV.wait(@ProcessControllersMonitor)
+ end
+ end
+ end
+ end
+
+ # for shell-command complete finish at this process exit.
+ USING_AT_EXIT_WHEN_PROCESS_EXIT = true
+ at_exit do
+ wait_to_finish_all_process_controllers unless $@
end
def initialize(shell)
@@ -67,6 +100,8 @@ class Shell
@job_condition = ConditionVariable.new
end
+ attr_reader :shell
+
def jobs
jobs = []
@jobs_sync.synchronize(:SH) do
@@ -83,7 +118,7 @@ class Shell
def waiting_jobs
@waiting_jobs
end
-
+
def jobs_exist?
@jobs_sync.synchronize(:SH) do
@active_jobs.empty? or @waiting_jobs.empty?
@@ -122,15 +157,19 @@ class Shell
@waiting_jobs.delete command
else
command = @waiting_jobs.shift
+# command.notify "job(%id) pre-start.", @shell.debug?
+
return unless command
end
@active_jobs.push command
command.start
+# command.notify "job(%id) post-start.", @shell.debug?
# start all jobs that input from the job
- for job in @waiting_jobs
+ for job in @waiting_jobs.dup
start_job(job) if job.input == command
end
+# command.notify "job(%id) post2-start.", @shell.debug?
end
end
@@ -152,6 +191,7 @@ class Shell
@active_jobs.delete command
ProcessController.inactivate(self)
if @active_jobs.empty?
+ command.notify("start_job in terminate_job(%id)", Shell::debug?)
start_job
end
end
@@ -159,7 +199,7 @@ class Shell
# kill a job
def kill_job(sig, command)
- @jobs_sync.synchronize(:SH) do
+ @jobs_sync.synchronize(:EX) do
if @waiting_jobs.delete command
ProcessController.inactivate(self)
return
@@ -183,6 +223,9 @@ class Shell
begin
while !jobs.empty?
@job_condition.wait(@job_monitor)
+ for job in jobs
+ job.notify("waiting job(%id)", Shell::debug?)
+ end
end
ensure
redo unless jobs.empty?
@@ -194,66 +237,82 @@ class Shell
def sfork(command, &block)
pipe_me_in, pipe_peer_out = IO.pipe
pipe_peer_in, pipe_me_out = IO.pipe
- Thread.critical = true
-
- STDOUT.flush
- ProcessController.each_active_object do |pc|
- for jobs in pc.active_jobs
- jobs.flush
- end
- end
-
- pid = fork {
- Thread.critical = true
- Thread.list.each do |th|
- th.kill unless [Thread.main, Thread.current].include?(th)
- end
- STDIN.reopen(pipe_peer_in)
- STDOUT.reopen(pipe_peer_out)
+ pid = nil
+ pid_mutex = Mutex.new
+ pid_cv = ConditionVariable.new
- ObjectSpace.each_object(IO) do |io|
- if ![STDIN, STDOUT, STDERR].include?(io)
- io.close unless io.closed?
+ Thread.start do
+ ProcessController.block_output_synchronize do
+ STDOUT.flush
+ ProcessController.each_active_object do |pc|
+ for jobs in pc.active_jobs
+ jobs.flush
+ end
end
+
+ pid = fork {
+ Thread.list.each do |th|
+# th.kill unless [Thread.main, Thread.current].include?(th)
+ th.kill unless Thread.current == th
+ end
+
+ STDIN.reopen(pipe_peer_in)
+ STDOUT.reopen(pipe_peer_out)
+
+ ObjectSpace.each_object(IO) do |io|
+ if ![STDIN, STDOUT, STDERR].include?(io)
+ io.close unless io.closed?
+ end
+ end
+
+ yield
+ }
end
- yield
- }
+ pid_cv.signal
- pipe_peer_in.close
- pipe_peer_out.close
- command.notify "job(%name:##{pid}) start", @shell.debug?
- Thread.critical = false
+ pipe_peer_in.close
+ pipe_peer_out.close
+ command.notify "job(%name:##{pid}) start", @shell.debug?
- th = Thread.start {
- Thread.critical = true
begin
_pid = nil
command.notify("job(%id) start to waiting finish.", @shell.debug?)
- Thread.critical = false
_pid = Process.waitpid(pid, nil)
rescue Errno::ECHILD
- command.notify "warn: job(%id) was done already waitipd."
+ command.notify "warn: job(%id) was done already waitpid."
_pid = true
+ # rescue
+ # STDERR.puts $!
ensure
- # when the process ends, wait until the command termintes
- if _pid
+ command.notify("Job(%id): Wait to finish when Process finished.", @shell.debug?)
+ # when the process ends, wait until the command terminates
+ if USING_AT_EXIT_WHEN_PROCESS_EXIT or _pid
else
command.notify("notice: Process finishing...",
"wait for Job[%id] to finish.",
"You can use Shell#transact or Shell#check_point for more safe execution.")
redo
end
- Thread.exclusive do
- @job_monitor.synchronize do
- terminate_job(command)
- @job_condition.signal
- command.notify "job(%id) finish.", @shell.debug?
- end
+
+# command.notify "job(%id) pre-pre-finish.", @shell.debug?
+ @job_monitor.synchronize do
+# command.notify "job(%id) pre-finish.", @shell.debug?
+ terminate_job(command)
+# command.notify "job(%id) pre-finish2.", @shell.debug?
+ @job_condition.signal
+ command.notify "job(%id) finish.", @shell.debug?
end
end
- }
+ end
+
+ pid_mutex.synchronize do
+ while !pid
+ pid_cv.wait(pid_mutex)
+ end
+ end
+
return pid, pipe_me_in, pipe_me_out
end
end
diff --git a/lib/shell/system-command.rb b/lib/shell/system-command.rb
index 8b1cba98c8..af9b0a8e37 100644
--- a/lib/shell/system-command.rb
+++ b/lib/shell/system-command.rb
@@ -1,13 +1,12 @@
#
-# shell/system-command.rb -
-# $Release Version: 0.6.0 $
-# $Revision: 1.2.2.1 $
-# $Date: 2004/03/21 12:21:11 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# shell/system-command.rb -
+# $Release Version: 0.7 $
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
require "shell/filter"
@@ -21,7 +20,7 @@ class Shell
super(sh)
@command = command
@opts = opts
-
+
@input_queue = Queue.new
@pid = nil
@@ -47,12 +46,15 @@ class Shell
end
def start
+ notify([@command, *@opts].join(" "))
+
@pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
Dir.chdir @shell.pwd
+ $0 = @command
exec(@command, *@opts)
}
if @input
- start_export
+ start_export
end
start_import
end
@@ -78,17 +80,12 @@ class Shell
end
end
-
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
@@ -96,19 +93,15 @@ class Shell
rescue Errno::EPIPE
_eop = false
ensure
- if _eop
+ if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _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
+ notify "job(%id}) close imp-pipe.", @shell.debug?
+ @input_queue.push :EOF
+ @pipe_in.close
end
}
end
@@ -117,25 +110,24 @@ class Shell
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}
+ @input.each do |l|
+ ProcessController::block_output_synchronize do
+ @pipe_out.print l
+ end
+ end
_eop = false
- rescue Errno::EPIPE
+ rescue Errno::EPIPE, Errno::EIO
_eop = false
ensure
- if _eop
+ if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _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
+ notify "job(%id) close exp-pipe.", @shell.debug?
+ @pipe_out.close
end
}
end
@@ -148,20 +140,19 @@ class Shell
end
# ex)
- # if you wish to output:
+ # if you wish to output:
# "shell: job(#{@command}:#{@pid}) close pipe-out."
- # then
+ # then
# mes: "job(%id) close pipe-out."
# yorn: Boolean(@shell.debug? or @shell.verbose?)
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}")
- }
+ @shell.notify(*opts) do |mes|
+ yield mes if iterator?
+
+ mes.gsub!("%id", "#{@command}:##{@pid}")
+ mes.gsub!("%name", "#{@command}")
+ mes.gsub!("%pid", "#{@pid}")
+ mes
end
end
end
diff --git a/lib/shell/version.rb b/lib/shell/version.rb
index 46b3425afa..6e4c170351 100644
--- a/lib/shell/version.rb
+++ b/lib/shell/version.rb
@@ -1,16 +1,15 @@
#
# version.rb - shell version definition file
-# $Release Version: 0.6.0$
-# $Revision: 1.1 $
-# $Date: 2001/05/17 10:02:48 $
-# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
+# $Release Version: 0.7$
+# $Revision$
+# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#
# --
#
-#
+#
#
class Shell
- @RELEASE_VERSION = "0.6.0"
- @LAST_UPDATE_DATE = "01/03/19"
+ @RELEASE_VERSION = "0.7"
+ @LAST_UPDATE_DATE = "07/03/20"
end