~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to lib/shell/system-command.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
2
#   shell/system-command.rb -
3
 
#       $Release Version: 0.7 $
4
 
#       $Revision: 25189 $
5
 
#       by Keiju ISHITSUKA(keiju@ruby-lang.org)
 
3
#       $Release Version: 0.7 $
 
4
#       $Revision: 31641 $
 
5
#       by Keiju ISHITSUKA(keiju@ruby-lang.org)
6
6
#
7
7
# --
8
8
#
15
15
  class SystemCommand < Filter
16
16
    def initialize(sh, command, *opts)
17
17
      if t = opts.find{|opt| !opt.kind_of?(String) && opt.class}
18
 
        Shell.Fail Error::TypeError, t.class, "String"
 
18
        Shell.Fail Error::TypeError, t.class, "String"
19
19
      end
20
20
      super(sh)
21
21
      @command = command
41
41
    def input=(inp)
42
42
      super
43
43
      if active?
44
 
        start_export
 
44
        start_export
45
45
      end
46
46
    end
47
47
 
49
49
      notify([@command, *@opts].join(" "))
50
50
 
51
51
      @pid, @pipe_in, @pipe_out = @shell.process_controller.sfork(self) {
52
 
        Dir.chdir @shell.pwd
53
 
        $0 = @command
54
 
        exec(@command, *@opts)
 
52
        Dir.chdir @shell.pwd
 
53
        $0 = @command
 
54
        exec(@command, *@opts)
55
55
      }
56
56
      if @input
57
 
        start_export
 
57
        start_export
58
58
      end
59
59
      start_import
60
60
    end
65
65
 
66
66
    def terminate
67
67
      begin
68
 
        @pipe_in.close
 
68
        @pipe_in.close
69
69
      rescue IOError
70
70
      end
71
71
      begin
72
 
        @pipe_out.close
 
72
        @pipe_out.close
73
73
      rescue IOError
74
74
      end
75
75
    end
76
76
 
77
77
    def kill(sig)
78
78
      if @pid
79
 
        Process.kill(sig, @pid)
 
79
        Process.kill(sig, @pid)
80
80
      end
81
81
    end
82
82
 
84
84
      notify "Job(%id) start imp-pipe.", @shell.debug?
85
85
      rs = @shell.record_separator unless rs
86
86
      _eop = true
87
 
      th = Thread.start {
88
 
        begin
89
 
          while l = @pipe_in.gets
90
 
            @input_queue.push l
91
 
          end
92
 
          _eop = false
93
 
        rescue Errno::EPIPE
94
 
          _eop = false
95
 
        ensure
96
 
          if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
97
 
            notify("warn: Process finishing...",
98
 
                   "wait for Job[%id] to finish pipe importing.",
99
 
                   "You can use Shell#transact or Shell#check_point for more safe execution.")
100
 
            redo
101
 
          end
102
 
          notify "job(%id}) close imp-pipe.", @shell.debug?
103
 
          @input_queue.push :EOF
104
 
          @pipe_in.close
105
 
        end
 
87
      Thread.start {
 
88
        begin
 
89
          while l = @pipe_in.gets
 
90
            @input_queue.push l
 
91
          end
 
92
          _eop = false
 
93
        rescue Errno::EPIPE
 
94
          _eop = false
 
95
        ensure
 
96
          if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
 
97
            notify("warn: Process finishing...",
 
98
                   "wait for Job[%id] to finish pipe importing.",
 
99
                   "You can use Shell#transact or Shell#check_point for more safe execution.")
 
100
            redo
 
101
          end
 
102
          notify "job(%id}) close imp-pipe.", @shell.debug?
 
103
          @input_queue.push :EOF
 
104
          @pipe_in.close
 
105
        end
106
106
      }
107
107
    end
108
108
 
109
109
    def start_export
110
110
      notify "job(%id) start exp-pipe.", @shell.debug?
111
111
      _eop = true
112
 
      th = Thread.start{
113
 
        begin
114
 
          @input.each do |l|
115
 
            ProcessController::block_output_synchronize do
116
 
              @pipe_out.print l
117
 
            end
118
 
          end
119
 
          _eop = false
120
 
        rescue Errno::EPIPE, Errno::EIO
121
 
          _eop = false
122
 
        ensure
123
 
          if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
124
 
            notify("shell: warn: Process finishing...",
125
 
                   "wait for Job(%id) to finish pipe exporting.",
126
 
                   "You can use Shell#transact or Shell#check_point for more safe execution.")
127
 
            redo
128
 
          end
129
 
          notify "job(%id) close exp-pipe.", @shell.debug?
130
 
          @pipe_out.close
131
 
        end
 
112
      Thread.start{
 
113
        begin
 
114
          @input.each do |l|
 
115
            ProcessController::block_output_synchronize do
 
116
              @pipe_out.print l
 
117
            end
 
118
          end
 
119
          _eop = false
 
120
        rescue Errno::EPIPE, Errno::EIO
 
121
          _eop = false
 
122
        ensure
 
123
          if !ProcessController::USING_AT_EXIT_WHEN_PROCESS_EXIT and _eop
 
124
            notify("shell: warn: Process finishing...",
 
125
                   "wait for Job(%id) to finish pipe exporting.",
 
126
                   "You can use Shell#transact or Shell#check_point for more safe execution.")
 
127
            redo
 
128
          end
 
129
          notify "job(%id) close exp-pipe.", @shell.debug?
 
130
          @pipe_out.close
 
131
        end
132
132
      }
133
133
    end
134
134
 
135
135
    alias super_each each
136
136
    def each(rs = nil)
137
137
      while (l = @input_queue.pop) != :EOF
138
 
        yield l
 
138
        yield l
139
139
      end
140
140
    end
141
141
 
142
142
    # ex)
143
143
    #    if you wish to output:
144
 
    #       "shell: job(#{@command}:#{@pid}) close pipe-out."
145
 
    #    then
146
 
    #       mes: "job(%id) close pipe-out."
 
144
    #       "shell: job(#{@command}:#{@pid}) close pipe-out."
 
145
    #    then
 
146
    #       mes: "job(%id) close pipe-out."
147
147
    #    yorn: Boolean(@shell.debug? or @shell.verbose?)
148
148
    def notify(*opts, &block)
149
149
      @shell.notify(*opts) do |mes|
150
 
        yield mes if iterator?
 
150
        yield mes if iterator?
151
151
 
152
 
        mes.gsub!("%id", "#{@command}:##{@pid}")
153
 
        mes.gsub!("%name", "#{@command}")
154
 
        mes.gsub!("%pid", "#{@pid}")
155
 
        mes
 
152
        mes.gsub!("%id", "#{@command}:##{@pid}")
 
153
        mes.gsub!("%name", "#{@command}")
 
154
        mes.gsub!("%pid", "#{@pid}")
 
155
        mes
156
156
      end
157
157
    end
158
158
  end