dia 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/dia.gemspec +5 -3
- data/lib/dia.rb +2 -1
- data/lib/dia/application.rb +15 -9
- data/lib/dia/exception_struct.rb +7 -0
- data/lib/dia/exceptions.rb +5 -0
- data/lib/dia/functions.rb +2 -0
- data/lib/dia/profiles.rb +23 -1
- data/lib/dia/ruby_block.rb +143 -91
- data/lib/dia/shared_features.rb +32 -33
- data/test/suite/lib/dia/Application#initialize.rb +21 -0
- data/test/suite/lib/dia/Application#run.rb +16 -0
- data/test/suite/lib/dia/Application#run_nonblock.rb +16 -0
- data/test/suite/lib/dia/RubyBlock#exception.rb +46 -0
- data/test/suite/lib/dia/RubyBlock#exception_raised?.rb +45 -0
- data/test/suite/lib/dia/RubyBlock#redirect_stderr?.rb +27 -0
- data/test/suite/lib/dia/RubyBlock#redirect_stdout?.rb +27 -0
- data/test/suite/lib/dia/RubyBlock#rescue_exception?.rb +28 -0
- data/test/suite/lib/dia/RubyBlock#run.rb +135 -0
- data/test/suite/lib/dia/RubyBlock#run_nonblock.rb +150 -0
- data/test/suite/lib/dia/RubyBlock#stderr.rb +48 -0
- data/test/suite/lib/dia/RubyBlock#stdout.rb +43 -0
- data/test/suite/lib/dia/SharedFeatures#exit_status.rb +26 -0
- data/test/suite/lib/dia/SharedFeatures#pid.rb +26 -0
- data/test/suite/lib/dia/SharedFeatures#running?.rb +37 -0
- data/test/suite/lib/dia/SharedFeatures#terminate.rb +26 -0
- metadata +41 -11
- data/test/suite/lib/dia/exception_struct.rb +0 -40
- data/test/suite/lib/dia/ruby_block.rb +0 -561
- data/test/suite/lib/dia/shared_features.rb +0 -236
data/dia.gemspec
CHANGED
@@ -37,12 +37,14 @@ Gem::Specification.new do |s|
|
|
37
37
|
|
38
38
|
Thanks for installing Dia, #{Dia::VERSION}!
|
39
39
|
|
40
|
-
>=2.0.0 releases
|
41
|
-
|
40
|
+
The >=2.0.0 releases are not backward compatiable with the 1.5
|
41
|
+
releases.
|
42
|
+
|
43
|
+
Details of this release can be read at the mailing list:
|
44
|
+
http://groups.google.com/group/ruby-dia/browse_thread/thread/fc255eeee8c59eeb
|
42
45
|
|
43
46
|
[Github] http://github.com/robgleeson/dia
|
44
47
|
[API Documentation] http://yardoc.org/docs/robgleeson-dia/
|
45
|
-
[Mailing List (new)] http://groups.google.com/group/ruby-dia
|
46
48
|
--------------------------------------------------------------------
|
47
49
|
MESSAGE
|
48
50
|
|
data/lib/dia.rb
CHANGED
@@ -9,6 +9,7 @@ require(File.expand_path('dia/application' , File.dirname(__FILE__)))
|
|
9
9
|
require(File.expand_path('dia/exceptions' , File.dirname(__FILE__)))
|
10
10
|
require(File.expand_path('dia/exception_struct' , File.dirname(__FILE__)))
|
11
11
|
|
12
|
+
# The Dia module provides a namespace for all classes and modules Dia needs to operate.
|
12
13
|
module Dia
|
13
|
-
VERSION = '2.0.
|
14
|
+
VERSION = '2.0.1'
|
14
15
|
end
|
data/lib/dia/application.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Dia
|
2
2
|
|
3
|
+
# The Application class provides an interface for executing an application in a sandbox.
|
3
4
|
class Application
|
4
5
|
include Dia::SharedFeatures
|
5
6
|
|
@@ -9,20 +10,24 @@ module Dia
|
|
9
10
|
#
|
10
11
|
# @param [String] Application Accepts a path to an application.
|
11
12
|
#
|
12
|
-
# @raise [ArgumentError] It
|
13
|
-
#
|
13
|
+
# @raise [ArgumentError] It isn't possible to launch an application with the
|
14
|
+
# {Dia::Profiles::NO_OS_SERVICES} profile, and an ArgumentError will
|
15
|
+
# be raised if you try to.
|
14
16
|
def initialize(profile, app)
|
15
17
|
@profile = profile
|
16
18
|
@app = app
|
17
|
-
raise(ArgumentError, "
|
18
|
-
"
|
19
|
+
raise(ArgumentError, "It is not possible to launch an application with the " \
|
20
|
+
"Dia::Profiles::NO_OS_SERVICES profile at this time") \
|
21
|
+
if @profile == Dia::Profiles::NO_OS_SERVICES
|
19
22
|
end
|
20
23
|
|
21
|
-
# This method will spawn a child process,
|
22
|
-
# to start your application.
|
24
|
+
# This method will spawn a child process, and execute an application in a sandbox.
|
23
25
|
#
|
24
|
-
# @
|
25
|
-
#
|
26
|
+
# @raise [Dia::Exceptions::SandboxException] It will raise {Dia::Exceptions::SandboxException}
|
27
|
+
# in a child process if it is not possible to
|
28
|
+
# initialize a sandbox.
|
29
|
+
#
|
30
|
+
# @return [Fixnum] Returns the Process ID of the spawned process.
|
26
31
|
def run
|
27
32
|
@pid = fork do
|
28
33
|
initialize_sandbox
|
@@ -33,7 +38,8 @@ module Dia
|
|
33
38
|
@pid
|
34
39
|
end
|
35
40
|
|
36
|
-
# An identical but non-blocking form of {#run}.
|
41
|
+
# An identical but non-blocking form of {Dia::Application#run}.
|
42
|
+
# @return [Fixnum]
|
37
43
|
def run_nonblock
|
38
44
|
@pid = fork do
|
39
45
|
initialize_sandbox
|
data/lib/dia/exception_struct.rb
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
+
|
1
2
|
module Dia
|
3
|
+
|
4
|
+
# The instance methods available on this class represent data extracted from an Exception-derived
|
5
|
+
# object.
|
6
|
+
# An instance of this class is returned by {Dia::RubyBlock#exception Dia::RubyBlock#exception}.
|
7
|
+
# This class shouldn't be initialized directly by you.
|
8
|
+
#
|
2
9
|
# @attr_reader [String] klass Returns Exception#class as a String.
|
3
10
|
# @attr_reader [String] message Returns Exception#message as a String.
|
4
11
|
# @attr_reader [String] backtrace Returns Exception#backtrace as a String.
|
data/lib/dia/exceptions.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
module Dia
|
2
|
+
|
3
|
+
# The Exceptions module provides a namespace for exceptions that can be raised by Dia.
|
2
4
|
module Exceptions
|
5
|
+
|
6
|
+
# The SandboxException is raised if it is not possible to initialize a sandbox when using
|
7
|
+
# {Dia::Application Dia::Application} or {Dia::RubyBlock Dia::RubyBlock}.
|
3
8
|
SandboxException = Class.new(StandardError)
|
4
9
|
end
|
5
10
|
end
|
data/lib/dia/functions.rb
CHANGED
data/lib/dia/profiles.rb
CHANGED
@@ -1,16 +1,38 @@
|
|
1
1
|
module Dia
|
2
|
+
|
3
|
+
# The Profiles module provides a list of profiles which can be passed to the constructor of
|
4
|
+
# {Dia::Application Dia::Application} or {Dia::RubyBlock Dia::RubyBlock} to create sandboxes
|
5
|
+
# with different kinds of restrictions.
|
2
6
|
module Profiles
|
3
7
|
extend(FFI::Library)
|
4
8
|
ffi_lib(%w(system))
|
5
|
-
|
9
|
+
|
10
|
+
# The NO_INTERNET profile restricts access to the internet.
|
11
|
+
# @return [String]
|
6
12
|
NO_INTERNET = attach_variable(:kSBXProfileNoInternet,
|
7
13
|
:string).read_string
|
14
|
+
|
15
|
+
# The NO_NETWORKING profile restricts all kinds of networking.
|
16
|
+
# @return [String]
|
8
17
|
NO_NETWORKING = attach_variable(:kSBXProfileNoNetwork,
|
9
18
|
:string).read_string
|
19
|
+
|
20
|
+
# The NO_FILESYSTEM_WRITE profile restricts any attempt to write
|
21
|
+
# to the filesystem.
|
22
|
+
# @return [String]
|
10
23
|
NO_FILESYSTEM_WRITE = attach_variable(:kSBXProfileNoWrite,
|
11
24
|
:string).read_string
|
25
|
+
|
26
|
+
# The NO_FILESYSTEM_WRITE_EXCEPT_TMP profile restricts any attempt to
|
27
|
+
# write to the filesystem, excluding writes to /var/tmp and the directory
|
28
|
+
# specified by _CS_DARWIN_USER_TEMP_DIR.
|
29
|
+
# @return [String]
|
12
30
|
NO_FILESYSTEM_WRITE_EXCEPT_TMP = attach_variable(:kSBXProfileNoWriteExceptTemporary,
|
13
31
|
:string).read_string
|
32
|
+
|
33
|
+
# The NO_OS_SERVICES is the most restrictive profile, and denies access to all
|
34
|
+
# operating system resources(Internet, Networking, FileSystem writes, etc).
|
35
|
+
# @return [String]
|
14
36
|
NO_OS_SERVICES = attach_variable(:kSBXProfilePureComputation,
|
15
37
|
:string).read_string
|
16
38
|
end
|
data/lib/dia/ruby_block.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
module Dia
|
2
2
|
|
3
|
+
# The RubyBlock class provides an interface for executing a block of ruby code in a sandbox.
|
3
4
|
class RubyBlock
|
4
5
|
|
5
6
|
require('io/wait')
|
6
7
|
require('stringio')
|
7
8
|
include Dia::SharedFeatures
|
8
9
|
|
10
|
+
attr_reader :stderr
|
11
|
+
attr_reader :stdout
|
12
|
+
attr_reader :exception
|
13
|
+
|
14
|
+
alias_method :e, :exception
|
9
15
|
|
10
16
|
# @param [String] Profile Accepts one of five profiles which can be found
|
11
17
|
# under the {Dia::Profiles} module.
|
@@ -28,14 +34,21 @@ module Dia
|
|
28
34
|
end
|
29
35
|
|
30
36
|
|
31
|
-
#
|
32
|
-
#
|
37
|
+
# Provides access to the Standard Output stream of the process last used to execute
|
38
|
+
# your sandbox.
|
39
|
+
# This feature is disabled by default.
|
40
|
+
#
|
41
|
+
# @return [String] Returns the contents of stdout as a String.
|
42
|
+
#
|
43
|
+
# @return [nil] Returns nil when no data is available on stdout.
|
44
|
+
#
|
45
|
+
# @return [nil] Returns nil if Dia was not set to redirect stdout before a call
|
46
|
+
# to {#run} or {#run_nonblock}.
|
33
47
|
#
|
34
|
-
# @
|
35
|
-
# Returns nil when no data is available on stdout, or when the
|
36
|
-
# "capture stdout" feature is disabled.
|
48
|
+
# @see #redirect_stdout= Redirection of stdout can be enabled through #redirect_stdout=
|
37
49
|
#
|
38
|
-
# @see #redirect_stdout
|
50
|
+
# @see #redirect_stdout? #redirect_stdout? can tell you if Standard Output is being
|
51
|
+
# redirected.
|
39
52
|
#
|
40
53
|
def stdout
|
41
54
|
if pipes_readable?(@pipes[:stdout_reader], @pipes[:stdout_writer])
|
@@ -46,55 +59,52 @@ module Dia
|
|
46
59
|
@stdout
|
47
60
|
end
|
48
61
|
|
49
|
-
# This method can enable or disable a feature that will capture
|
50
|
-
# in the
|
62
|
+
# This method can enable or disable a feature that will capture Standard Output
|
63
|
+
# in the process that is spawned to execute a sandbox.
|
64
|
+
#
|
65
|
+
# @param [true] Enable Passing true will enable the redirection of Standard Output.
|
66
|
+
#
|
67
|
+
# @param [false] Disable Passing false will disable the redirection of Standard Output.
|
68
|
+
#
|
69
|
+
# @return [void]
|
51
70
|
#
|
52
|
-
# @
|
53
|
-
#
|
54
|
-
# @see #
|
71
|
+
# @see #stdout Standard Output can be accessed through #stdout.
|
72
|
+
#
|
73
|
+
# @see #redirect_stdout? #redirect_stdout? can tell you if Standard Output is
|
74
|
+
# being redirected.
|
55
75
|
def redirect_stdout=(boolean)
|
56
76
|
@redirect_stdout = boolean
|
57
77
|
end
|
58
78
|
|
59
|
-
# This method will tell you if
|
60
|
-
# process
|
79
|
+
# This method will tell you if Standard Output is being redirected in the
|
80
|
+
# process spawned to execute a sandbox.
|
61
81
|
#
|
62
|
-
# @
|
82
|
+
# @return [true] Returns true when Standard Output is being redirected.
|
63
83
|
#
|
64
|
-
# @return [
|
65
|
-
def redirect_stdout?
|
66
|
-
!!@rescue_stdout
|
67
|
-
end
|
68
|
-
|
69
|
-
# This method will tell you if standard error is being redirected in the child process
|
70
|
-
# used to execute your sandbox.
|
84
|
+
# @return [false] Returns false when Standard Output is not being redirected.
|
71
85
|
#
|
72
|
-
# @see #
|
73
|
-
# @return [Boolean] returns true or false.
|
74
|
-
def redirect_stderr?
|
75
|
-
!!@rescue_stderr
|
76
|
-
end
|
77
|
-
|
78
|
-
# This method can enable or disable a feature that will capture standard error output
|
79
|
-
# in the child process that is spawned to execute a sandbox.
|
86
|
+
# @see #redirect_stdout= Redirection of stdout can be enabled through #redirect_stdout=.
|
80
87
|
#
|
81
|
-
# @
|
82
|
-
|
83
|
-
|
84
|
-
def redirect_stderr=(boolean)
|
85
|
-
@redirect_stderr = boolean
|
88
|
+
# @see #stdout Standard Ouput can be accessed through #stdout.
|
89
|
+
def redirect_stdout?
|
90
|
+
!!@redirect_stdout
|
86
91
|
end
|
87
92
|
|
88
|
-
|
89
|
-
#
|
90
|
-
#
|
93
|
+
# Provides access to the Standard Error stream of the process last used to execute
|
94
|
+
# a sandbox.
|
95
|
+
# This feature is disabled by default.
|
91
96
|
#
|
92
|
-
# @return [String
|
93
|
-
# Returns nil when no data is available on stderr, or when the
|
94
|
-
# "capture stderr" feature is disabled.
|
97
|
+
# @return [String] Returns the contents of stderr as a String.
|
95
98
|
#
|
96
|
-
# @
|
97
|
-
#
|
99
|
+
# @return [nil] Returns nil when no data is available on stderr.
|
100
|
+
#
|
101
|
+
# @return [nil] Returns nil if Dia was not set to redirect stderr before a call
|
102
|
+
# to {#run} or {#run_nonblock}.
|
103
|
+
#
|
104
|
+
# @see #redirect_stderr= Redirection of stderr can be enabled through #redirect_stderr=
|
105
|
+
#
|
106
|
+
# @see #redirect_stderr? #redirect_stderr? can tell you if Standard Error output is being
|
107
|
+
# redirected.
|
98
108
|
def stderr
|
99
109
|
if pipes_readable?(@pipes[:stderr_reader], @pipes[:stderr_writer])
|
100
110
|
@pipes[:stderr_writer].close
|
@@ -104,67 +114,106 @@ module Dia
|
|
104
114
|
@stderr
|
105
115
|
end
|
106
116
|
|
107
|
-
# This method
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
117
|
+
# This method can enable or disable a feature that will capture Standard Error output
|
118
|
+
# in the process that is spawned to execute a sandbox.
|
119
|
+
#
|
120
|
+
# @param [true] Enable Passing true will enable the redirection of Standard Error output.
|
121
|
+
#
|
122
|
+
# @param [false] Disable Passing false will disable the redirection of Standard Error output.
|
123
|
+
#
|
124
|
+
# @return [void]
|
125
|
+
#
|
126
|
+
# @see #stderr Standard Error output can be accessed through #stderr.
|
127
|
+
#
|
128
|
+
# @see #redirect_stderr? #redirect_stderr? can tell you if Standard Error output is being
|
129
|
+
# redirected.
|
130
|
+
def redirect_stderr=(boolean)
|
131
|
+
@redirect_stderr = boolean
|
132
|
+
end
|
133
|
+
|
134
|
+
# This method will tell you if Standard Error output is being redirected in the process
|
135
|
+
# spawned to execute a sandbox.
|
111
136
|
#
|
112
|
-
# @
|
113
|
-
#
|
137
|
+
# @return [true] Returns true when Standard Error output is being redirected.
|
138
|
+
#
|
139
|
+
# @return [false] Returns false when Standard Error output is not being redirected.
|
140
|
+
#
|
141
|
+
# @see #redirect_stderr= Redirection of stderr can be enabled through #redirect_stderr=.
|
142
|
+
#
|
143
|
+
# @see #stderr Standard Error output can be accessed through #stderr.
|
144
|
+
def redirect_stderr?
|
145
|
+
!!@redirect_stderr
|
146
|
+
end
|
147
|
+
|
148
|
+
# This method will tell you if an exception has been raised in the process
|
149
|
+
# spawned to execute a sandbox.
|
150
|
+
#
|
151
|
+
# @return [true] Returns true when an exception has been rasied.
|
152
|
+
#
|
153
|
+
# @return [false] Returns false when an exception has not been raised.
|
154
|
+
#
|
155
|
+
# @return [false] Returns false if Dia was not set to capture exceptions
|
156
|
+
# before a call to {#run} or {#run_nonblock}.
|
157
|
+
#
|
158
|
+
# @see #rescue_exception= The capture of exceptions can be enabled or disabled through
|
159
|
+
# #rescue_exception=
|
160
|
+
#
|
161
|
+
# @see #exception An exception can be accessed through the #exception
|
162
|
+
# method.
|
114
163
|
#
|
115
|
-
# @see #exception See the #exception method for accessing an
|
116
|
-
# exception raised in your sandbox.
|
117
164
|
#
|
118
|
-
# @return [Boolean] Returns true or false.
|
119
165
|
def exception_raised?
|
120
166
|
!!exception
|
121
167
|
end
|
122
168
|
|
123
|
-
# This method will tell you if the
|
124
|
-
#
|
169
|
+
# This method will tell you if an exception raised in the process spawned to
|
170
|
+
# spawn a sandbox will be captured/rescued.
|
125
171
|
#
|
126
|
-
# @
|
127
|
-
# of raised exceptions in your sandbox.
|
172
|
+
# @return [true] Returns true when exceptions are being captured.
|
128
173
|
#
|
129
|
-
# @
|
130
|
-
#
|
131
|
-
#
|
132
|
-
# @return [Boolean] Returns true or false.
|
174
|
+
# @return [false] Returns false when are exceptions are not being
|
175
|
+
# captured.
|
133
176
|
# @since 2.0.0
|
177
|
+
#
|
178
|
+
# @see #rescue_exception= The capture of exceptions can be enabled or disabled through
|
179
|
+
# #rescue_exception=
|
134
180
|
def rescue_exception?
|
135
181
|
!!@rescue
|
136
182
|
end
|
137
183
|
|
138
|
-
# This method can enable or disable a feature that will
|
139
|
-
# raised
|
184
|
+
# This method can enable or disable a feature that will capture/rescue
|
185
|
+
# exceptions that are raised in the process spawned to execute your sandbox.
|
140
186
|
#
|
141
|
-
# @param [
|
187
|
+
# @param [true] Enable Passing true will enable the capture of exceptions.
|
142
188
|
#
|
143
|
-
# @
|
189
|
+
# @param [false] Disable Passing false will disable the capture of exceptions.
|
144
190
|
#
|
145
|
-
# @
|
146
|
-
# the data of an exception raised in your sandbox.
|
191
|
+
# @return [void]
|
147
192
|
#
|
193
|
+
# @see #exception An exception can be accessed through the #exception
|
194
|
+
# method.
|
148
195
|
# @since 2.0.0
|
149
196
|
def rescue_exception=(boolean)
|
150
197
|
@rescue = boolean
|
151
198
|
end
|
152
199
|
|
153
|
-
|
154
|
-
# the
|
155
|
-
#
|
156
|
-
#
|
157
|
-
# Every call {#run} or {#run_nonblock} will reset the instance variable referencing the
|
158
|
-
# object storing exception data to nil.
|
200
|
+
|
201
|
+
# Provides access to the data of an exception object raised in the process last used to
|
202
|
+
# execute a sandbox.
|
203
|
+
# This feature is disabled by default.
|
159
204
|
#
|
160
|
-
# @return [Dia::ExceptionStruct
|
161
|
-
#
|
162
|
-
#
|
163
|
-
# @
|
164
|
-
#
|
205
|
+
# @return [Dia::ExceptionStruct] Returns an instance of {ExceptionStruct} when an
|
206
|
+
# exception has been captured.
|
207
|
+
#
|
208
|
+
# @return [nil] Returns nil when there is no exception available.
|
209
|
+
#
|
210
|
+
# @return [nil] Returns nil if Dia was not set to capture exceptions before a
|
211
|
+
# call to {#run} or {#run_nonblock}.
|
165
212
|
#
|
166
|
-
# @see
|
213
|
+
# @see #rescue_exception= The capture of exceptions can be enabled or disabled through
|
214
|
+
# #rescue_exception=
|
167
215
|
#
|
216
|
+
# @see Dia::ExceptionStruct Dia::ExceptionStruct.
|
168
217
|
# @since 1.5
|
169
218
|
def exception
|
170
219
|
if pipes_readable?(@pipes[:exception_reader], @pipes[:exception_writer])
|
@@ -177,26 +226,28 @@ module Dia
|
|
177
226
|
@e
|
178
227
|
end
|
179
228
|
|
180
|
-
# The run method will spawn a child process
|
181
|
-
# in a sandbox.
|
182
|
-
# This method will block. See {#run_nonblock} for the non-blocking form of
|
183
|
-
#
|
229
|
+
# The run method will spawn a child process and execute the block supplied to the constructor
|
230
|
+
# in a sandbox.
|
231
|
+
# This method will block. See {#run_nonblock} for the non-blocking form of this method.
|
232
|
+
#
|
233
|
+
# **Side Effects:**
|
234
|
+
#
|
235
|
+
# * When this method is called, it will reset the instance variables returned by {#exception},
|
236
|
+
# {#stdout}, and {#stderr} to nil.
|
184
237
|
#
|
185
|
-
# @param [Arguments] Arguments A variable amount of arguments that will
|
186
|
-
#
|
187
|
-
# constructer. Optional.
|
238
|
+
# @param [Arguments] Arguments A variable amount of arguments that will be passed onto the
|
239
|
+
# the block supplied to the constructor.
|
188
240
|
#
|
189
|
-
# @raise [SystemCallError] It
|
241
|
+
# @raise [SystemCallError] It will raise a number of subclasses of SystemCallError
|
190
242
|
# in a child process if a sandbox violates imposed
|
191
243
|
# restrictions.
|
192
244
|
#
|
193
|
-
# @raise [Dia::SandboxException] It
|
245
|
+
# @raise [Dia::SandboxException] It will raise
|
194
246
|
# {Dia::Exceptions::SandboxException}
|
195
247
|
# in a child process if it was not possible
|
196
|
-
# to initialize a sandbox
|
248
|
+
# to initialize a sandbox.
|
197
249
|
#
|
198
|
-
# @return [Fixnum]
|
199
|
-
# been launched under.
|
250
|
+
# @return [Fixnum] It returns the Process ID of the spawned process
|
200
251
|
def run(*args)
|
201
252
|
launch(*args)
|
202
253
|
|
@@ -205,7 +256,8 @@ module Dia
|
|
205
256
|
@pid
|
206
257
|
end
|
207
258
|
|
208
|
-
# An identical, but non-blocking form of {#run}.
|
259
|
+
# An identical, but non-blocking form of {Dia::RubyBlock#run}.
|
260
|
+
# @return [Fixnum]
|
209
261
|
def run_nonblock(*args)
|
210
262
|
launch(*args)
|
211
263
|
|
@@ -216,7 +268,7 @@ module Dia
|
|
216
268
|
private
|
217
269
|
# @api private
|
218
270
|
def launch(*args)
|
219
|
-
@e = @stdout = nil
|
271
|
+
@e = @stdout = @stderr = nil
|
220
272
|
close_pipes_if_needed
|
221
273
|
open_pipes_if_needed
|
222
274
|
|