dia 1.5.pre → 1.5.pre.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/NEWS.md +32 -15
- data/README.md +35 -0
- data/lib/dia.rb +1 -1
- data/lib/dia/sandbox.rb +62 -15
- data/test/suite/exceptions_text.rb +41 -0
- metadata +5 -3
data/NEWS.md
CHANGED
@@ -1,25 +1,36 @@
|
|
1
1
|
## NEWS
|
2
2
|
|
3
3
|
### 1.5
|
4
|
-
*
|
5
|
-
|
6
|
-
*
|
7
|
-
|
4
|
+
* Added Dia::Sandbox#exception() for inspecting an exception raised in a sandbox
|
5
|
+
from the parent process.
|
6
|
+
* Fixed a small bug introduced in 1.5.pre - a typo, only encountered if
|
7
|
+
Dia::SandboxException was raised.
|
8
|
+
* Dia::Sandbox#running?, Dia::Sandbox#exit_status, and Dia::Sandbox#terminate
|
9
|
+
will return nil if you call them before calling Dia::Sandbox#run().
|
10
|
+
* Added Dia::Sandbox#exit_status for collecting the exit status of a child
|
11
|
+
process running under a sandbox.
|
12
|
+
* Dia::Sandbox#run was not returning the PID of the process running under a
|
13
|
+
sandbox like told in the documentation - it is now.
|
8
14
|
|
9
15
|
### 1.4
|
10
|
-
* A typo broke support for launching applications in a sandbox.
|
16
|
+
* A typo broke support for launching applications in a sandbox.
|
17
|
+
(Bug affects 1.3 and all the 1.4 *pre* releases)
|
11
18
|
* Mac OSX 10.5 reported as working! (Bug fix)
|
12
19
|
Many thanks to Josh Creek for reporting and helping me debug this bug.
|
13
20
|
* Use ffi\_lib() to explicitly load the dynamic library "sandbox", or "System"
|
14
21
|
* Depend explicitly on FFI v0.6.2
|
15
|
-
* Dia::Sandbox#run accepts a variable amount of arguments that will be passed
|
22
|
+
* Dia::Sandbox#run accepts a variable amount of arguments that will be passed
|
23
|
+
onto the block supplied to the constructer.
|
16
24
|
* Added "test/\*\*/*.rb" to the gem specification as test files..
|
17
25
|
|
18
26
|
### 1.3
|
19
|
-
* Added Dia::Sandbox#running? to check if a process running a sandbox is alive
|
20
|
-
|
27
|
+
* Added Dia::Sandbox#running? to check if a process running a sandbox is alive
|
28
|
+
or not.
|
29
|
+
* Dia::Sandbox only exposes its instance variables through getters now.
|
30
|
+
No more setters.
|
21
31
|
* Dia::Sandbox#app_path is now Dia::Sandbox#app
|
22
|
-
* Removed run\_with\_block in favor of passing a block to the constructer.
|
32
|
+
* Removed run\_with\_block in favor of passing a block to the constructer.
|
33
|
+
Dia::Sandbox#run is used to execute a block or an application now,
|
23
34
|
but only one or the other may be supplied to the constructer.
|
24
35
|
* Removed Dia::SandBox in favor of Dia::Sandbox.
|
25
36
|
* Added "has_rdoc = 'yard'" to the gem spec.
|
@@ -27,19 +38,25 @@
|
|
27
38
|
* SandBoxException becomes SandboxException.
|
28
39
|
|
29
40
|
### 1.2
|
30
|
-
* I've decided to use Dia::Sandbox instead of Dia::SandBox but it won't
|
31
|
-
|
41
|
+
* I've decided to use Dia::Sandbox instead of Dia::SandBox but it won't
|
42
|
+
be removed until 1.3 .. (Deprecated for 1.2)
|
43
|
+
* I've decided to remove the explicit exit() call in a sandbox spawned with
|
44
|
+
run\_with\_block .. (Introduced in 1.1 Final)
|
32
45
|
* Added Dia::Sandbox#terminate for terminating a sandbox.
|
33
|
-
* Process.detach(*sandbox pid*) is used in the parent process that spawns a
|
46
|
+
* Process.detach(*sandbox pid*) is used in the parent process that spawns a
|
47
|
+
sandbox to avoid collecting zombies ..
|
34
48
|
|
35
49
|
### 1.1 (final)
|
36
|
-
* Dia::SandBox#run\_with\_block will exit the child process spawned by itself
|
50
|
+
* Dia::SandBox#run\_with\_block will exit the child process spawned by itself
|
51
|
+
incase the user forgets to ..
|
37
52
|
* Added some tests for Dia::Sandbox.new#run\_with\_block ..
|
38
53
|
We ain't got full coverage but we're getting there.
|
39
54
|
* A person reported that ffi 0.6.0 does not work with dia ..
|
40
55
|
Supplied an explicit dependency on ffi 0.5.4 until I figure it out.
|
41
|
-
* You can run a block of ruby under a sandbox now but I had to change the order
|
42
|
-
|
56
|
+
* You can run a block of ruby under a sandbox now but I had to change the order
|
57
|
+
of arguments in the constructer ..
|
58
|
+
First argument is the profile, and (optionally) the second is the application
|
59
|
+
path.
|
43
60
|
If you're running a block of ruby, you can forget about the second.
|
44
61
|
* I documented my methods!
|
45
62
|
|
data/README.md
CHANGED
@@ -86,6 +86,41 @@ If you need to check if a sandbox you have spawned is still running, you can use
|
|
86
86
|
puts sandbox.running? # => true
|
87
87
|
|
88
88
|
|
89
|
+
**Collecting the exit status of a sandbox**
|
90
|
+
|
91
|
+
The sandbox environment is run in a child process, and you can collect its
|
92
|
+
exit status through the #exit_status() method. This method is only available
|
93
|
+
from 0.5.pre onwards.
|
94
|
+
|
95
|
+
require 'rubygems'
|
96
|
+
require 'dia'
|
97
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
98
|
+
exit(10)
|
99
|
+
end
|
100
|
+
|
101
|
+
sandbox.run()
|
102
|
+
sandbox.exit_status() # => 10
|
103
|
+
|
104
|
+
**Accessing an exception raised in a sandbox**
|
105
|
+
|
106
|
+
Since 1.5, an exception raised in a sandbox can be accessed from the parent
|
107
|
+
process. This only works as long as you don't try to capture the exception
|
108
|
+
raised in a block by yourself or if you do, you re-raise the exception after
|
109
|
+
capturing it so Dia can forward the exception to the parent process.
|
110
|
+
|
111
|
+
require 'rubygems'
|
112
|
+
require 'dia'
|
113
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
114
|
+
raise()
|
115
|
+
end
|
116
|
+
|
117
|
+
sandbox.run()
|
118
|
+
sleep(0.1) # Let the parent receive the exception.
|
119
|
+
# Only neccesary for scenarios where an exception is raised
|
120
|
+
# rather quickly.
|
121
|
+
|
122
|
+
puts sandbox.exception().class # prints "RuntimeError"
|
123
|
+
|
89
124
|
.. Please see the yardoc [documentation](http://yardoc.org/docs/robgleeson-Dia) for more in-depth coverage of these methods,
|
90
125
|
in particular the documentation for the `Dia::Sandbox` class.
|
91
126
|
|
data/lib/dia.rb
CHANGED
data/lib/dia/sandbox.rb
CHANGED
@@ -2,13 +2,15 @@ module Dia
|
|
2
2
|
|
3
3
|
class Sandbox
|
4
4
|
|
5
|
+
require('io/wait')
|
6
|
+
|
5
7
|
include Dia::CommonAPI
|
6
8
|
|
7
9
|
attr_reader :app
|
8
10
|
attr_reader :profile
|
9
11
|
attr_reader :pid
|
10
12
|
attr_reader :blk
|
11
|
-
|
13
|
+
|
12
14
|
# The constructer accepts a profile as the first parameter, and an
|
13
15
|
# application path _or_ block as its second parameter.
|
14
16
|
#
|
@@ -48,8 +50,35 @@ module Dia
|
|
48
50
|
@blk = blk
|
49
51
|
@profile = profile
|
50
52
|
@pid = nil
|
53
|
+
initialize_streams()
|
51
54
|
end
|
52
|
-
|
55
|
+
|
56
|
+
# The exception() method returns an instance or subclass instance of
|
57
|
+
# Exception which has been raised in a sandbox.
|
58
|
+
#
|
59
|
+
# This method can be used if you need access(from the parent process)
|
60
|
+
# to an exception raised in your sandbox.
|
61
|
+
#
|
62
|
+
# If the sandbox raises an exception rather quickly, you might need to
|
63
|
+
# sleep(X) (0.3-0.5s on my machine) before the parent process
|
64
|
+
# recieves the exception.
|
65
|
+
#
|
66
|
+
# @return [Exception, nil] Returns an instance or subclass instance of
|
67
|
+
# Exception when successful, and nil when
|
68
|
+
# there is no exception available.
|
69
|
+
# @since 1.5
|
70
|
+
def exception()
|
71
|
+
@write.close()
|
72
|
+
if @read.ready?()
|
73
|
+
ret = Marshal.load(@read.gets())
|
74
|
+
else
|
75
|
+
ret = nil
|
76
|
+
end
|
77
|
+
@read.close()
|
78
|
+
initialize_streams()
|
79
|
+
ret
|
80
|
+
end
|
81
|
+
|
53
82
|
# The run method will spawn a child process and run the application _or_
|
54
83
|
# block supplied to the constructer under a sandbox.
|
55
84
|
# This method will not block.
|
@@ -73,22 +102,33 @@ module Dia
|
|
73
102
|
# @return [Fixnum] The Process ID(PID) that the sandboxed
|
74
103
|
# application is being run under.
|
75
104
|
def run(*args)
|
105
|
+
initialize_streams()
|
76
106
|
@pid = fork do
|
77
|
-
|
78
|
-
|
79
|
-
|
107
|
+
begin
|
108
|
+
if sandbox_init(FFI::MemoryPointer.from_string(@profile),
|
109
|
+
0x0001,
|
110
|
+
err = FFI::MemoryPointer.new(:pointer)) == -1
|
80
111
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
112
|
+
raise(Dia::SandboxException, "Failed to initialize sandbox" \
|
113
|
+
"(#{err.read_pointer.read_string})")
|
114
|
+
end
|
115
|
+
|
116
|
+
if @app
|
117
|
+
exec(@app)
|
118
|
+
else
|
119
|
+
@blk.call(*args)
|
120
|
+
end
|
121
|
+
|
122
|
+
rescue SystemExit, Interrupt => e
|
123
|
+
raise(e)
|
124
|
+
rescue Exception => e
|
125
|
+
@write.write(Marshal.dump(e))
|
126
|
+
ensure
|
127
|
+
@write.close()
|
128
|
+
@read.close()
|
89
129
|
end
|
90
130
|
end
|
91
|
-
|
131
|
+
|
92
132
|
# parent ..
|
93
133
|
@thr = Process.detach(@pid)
|
94
134
|
@pid
|
@@ -102,7 +142,8 @@ module Dia
|
|
102
142
|
# under a sandbox.
|
103
143
|
# Returns nil if Dia::Sandbox#run has not
|
104
144
|
# been called yet, or if the process stopped
|
105
|
-
# abnormally(ie: through SIGKILL, or #terminate).
|
145
|
+
# abnormally(ie: through SIGKILL, or #terminate).
|
146
|
+
# @since 1.5
|
106
147
|
def exit_status()
|
107
148
|
@thr.value().exitstatus() unless @thr.nil?
|
108
149
|
end
|
@@ -143,7 +184,13 @@ module Dia
|
|
143
184
|
end
|
144
185
|
end
|
145
186
|
end
|
187
|
+
|
188
|
+
private
|
146
189
|
|
190
|
+
def initialize_streams()
|
191
|
+
@read, @write = IO.pipe()
|
192
|
+
end
|
193
|
+
|
147
194
|
end
|
148
195
|
|
149
196
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
BareTest.suite('Exceptions', :tags => [ :exception ]) do
|
2
|
+
assert('Dia::SandboxException is raised if a call to sandbox_init() fails') do
|
3
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
4
|
+
# ...
|
5
|
+
end
|
6
|
+
sandbox.instance_variable_set("@profile", "i am going to break")
|
7
|
+
sandbox.run
|
8
|
+
sleep(0.1)
|
9
|
+
equal(Dia::SandboxException, sandbox.exception().class)
|
10
|
+
end
|
11
|
+
|
12
|
+
assert('Dia::Sandbox#exception() will return an exception raised in the sandbox') do
|
13
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
14
|
+
raise()
|
15
|
+
end
|
16
|
+
|
17
|
+
sandbox.run()
|
18
|
+
sleep(0.1)
|
19
|
+
equal(RuntimeError, sandbox.exception.class())
|
20
|
+
end
|
21
|
+
|
22
|
+
assert('Dia::Sandbox#exception() returns nil if called before ' \
|
23
|
+
'Dia::Sandbox#run()') do
|
24
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
25
|
+
# ...
|
26
|
+
end
|
27
|
+
equal(nil, sandbox.exception())
|
28
|
+
end
|
29
|
+
|
30
|
+
assert('Dia::Sandbox#exception() returns nil after a second call') do
|
31
|
+
sandbox = Dia::Sandbox.new(Dia::Profiles::NO_OS_SERVICES) do
|
32
|
+
raise()
|
33
|
+
end
|
34
|
+
|
35
|
+
sandbox.run()
|
36
|
+
sleep(0.1)
|
37
|
+
equal(RuntimeError, sandbox.exception().class)
|
38
|
+
equal(nil, sandbox.exception())
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
CHANGED
@@ -6,7 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 1
|
7
7
|
- 5
|
8
8
|
- pre
|
9
|
-
|
9
|
+
- 2
|
10
|
+
version: 1.5.pre.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Robert Gleeson
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-05-
|
18
|
+
date: 2010-05-07 00:00:00 +01:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -83,7 +84,7 @@ has_rdoc: yard
|
|
83
84
|
homepage:
|
84
85
|
licenses: []
|
85
86
|
|
86
|
-
post_install_message: " ********************************************************************\n Dia (1.5.pre)\n \n Thanks for installing Dia, 1.5.pre! \n \n Keep up with the latest @ GitHub:\n http://github.com/robgleeson/dia\n ********************************************************************\n"
|
87
|
+
post_install_message: " ********************************************************************\n Dia (1.5.pre.2)\n \n Thanks for installing Dia, 1.5.pre.2! \n \n Keep up with the latest @ GitHub:\n http://github.com/robgleeson/dia\n ********************************************************************\n"
|
87
88
|
rdoc_options: []
|
88
89
|
|
89
90
|
require_paths:
|
@@ -114,6 +115,7 @@ summary: Dia allows you to sandbox application(s) or block(s) of rubyon the OSX
|
|
114
115
|
test_files:
|
115
116
|
- test/setup.rb
|
116
117
|
- test/suite/check_if_sandbox_is_alive_test.rb
|
118
|
+
- test/suite/exceptions_text.rb
|
117
119
|
- test/suite/exit_status_test.rb
|
118
120
|
- test/suite/passing_parameters_to_constructer_test.rb
|
119
121
|
- test/suite/run_block_in_sandbox_test.rb
|