├── lib ├── playpen │ ├── no_write.rb │ ├── no_network.rb │ ├── no_internet.rb │ ├── temp_only_write.rb │ └── computation_only.rb └── playpen.rb ├── ext └── playpen │ ├── extconf.rb │ └── playpen.c ├── Manifest.txt ├── CHANGELOG.rdoc ├── .autotest ├── Rakefile ├── README.rdoc └── test └── test_playpen.rb /lib/playpen/no_write.rb: -------------------------------------------------------------------------------- 1 | require 'playpen' 2 | 3 | Playpen.no_write.apply! 4 | -------------------------------------------------------------------------------- /lib/playpen/no_network.rb: -------------------------------------------------------------------------------- 1 | require 'playpen' 2 | 3 | Playpen.no_network.apply! 4 | -------------------------------------------------------------------------------- /lib/playpen/no_internet.rb: -------------------------------------------------------------------------------- 1 | require 'playpen' 2 | 3 | Playpen.no_internet.apply! 4 | -------------------------------------------------------------------------------- /lib/playpen/temp_only_write.rb: -------------------------------------------------------------------------------- 1 | require 'playpen' 2 | 3 | Playpen.temp_only_write.apply! 4 | -------------------------------------------------------------------------------- /lib/playpen/computation_only.rb: -------------------------------------------------------------------------------- 1 | require 'playpen' 2 | 3 | Playpen.computation_only.apply! 4 | -------------------------------------------------------------------------------- /ext/playpen/extconf.rb: -------------------------------------------------------------------------------- 1 | # :stopdoc: 2 | 3 | require 'mkmf' 4 | 5 | def asplode(lib) 6 | abort "-----\n#{lib} is missing." 7 | end 8 | 9 | asplode "sandbox" unless find_header('sandbox.h') 10 | asplode "sandbox" unless find_library('sandbox', 'sandbox_init') 11 | 12 | create_makefile('playpen/playpen') 13 | # :startdoc: 14 | -------------------------------------------------------------------------------- /Manifest.txt: -------------------------------------------------------------------------------- 1 | .autotest 2 | CHANGELOG.rdoc 3 | Manifest.txt 4 | README.rdoc 5 | Rakefile 6 | ext/playpen/extconf.rb 7 | ext/playpen/playpen.c 8 | lib/playpen.rb 9 | lib/playpen/computation_only.rb 10 | lib/playpen/no_internet.rb 11 | lib/playpen/no_network.rb 12 | lib/playpen/no_write.rb 13 | lib/playpen/temp_only_write.rb 14 | test/test_playpen.rb 15 | -------------------------------------------------------------------------------- /CHANGELOG.rdoc: -------------------------------------------------------------------------------- 1 | === 1.1.0 / 2011-05-12 2 | 3 | * 1 enhancement 4 | 5 | * Added files to be required from the command line. For example, to raise 6 | an exception if bundler tries to access the network: 7 | 8 | $ ruby -rubygems -rplaypen/no_network -S bundle 9 | 10 | === 1.0.0 / 2010-10-07 11 | 12 | * 1 major enhancement 13 | 14 | * Birthday! 15 | 16 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'autotest/restart' 4 | 5 | # Autotest.add_hook :initialize do |at| 6 | # at.extra_files << "../some/external/dependency.rb" 7 | # 8 | # at.libs << ":../some/external" 9 | # 10 | # at.add_exception 'vendor' 11 | # 12 | # at.add_mapping(/dependency.rb/) do |f, _| 13 | # at.files_matching(/test_.*rb$/) 14 | # end 15 | # 16 | # %w(TestA TestB).each do |klass| 17 | # at.extra_class_map[klass] = "test/test_misc.rb" 18 | # end 19 | # end 20 | 21 | # Autotest.add_hook :run_command do |at| 22 | # system "rake build" 23 | # end 24 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'rubygems' 4 | require 'hoe' 5 | gem 'rake-compiler', '>= 0.4.1' 6 | require "rake/extensiontask" 7 | 8 | Hoe.spec 'playpen' do |s| 9 | developer('Aaron Patterson', 'aaron@tenderlovemaking.com') 10 | developer('Evan Phoenix', 'evan@fallingsnow.net') 11 | self.readme_file = 'README.rdoc' 12 | self.history_file = 'CHANGELOG.rdoc' 13 | self.extra_rdoc_files = FileList['*.rdoc'] 14 | self.spec_extras = { :extensions => ["ext/playpen/extconf.rb"] } 15 | 16 | Rake::ExtensionTask.new s.name, spec do |ext| 17 | ext.lib_dir = File.join(*['lib', s.name, ENV['FAT_DIR']].compact) 18 | end 19 | end 20 | 21 | task :test => :compile 22 | 23 | # vim: syntax=ruby 24 | -------------------------------------------------------------------------------- /lib/playpen.rb: -------------------------------------------------------------------------------- 1 | require 'playpen/playpen' 2 | 3 | class Playpen 4 | VERSION = '1.1.0' 5 | 6 | def initialize 7 | @commands = [] 8 | end 9 | 10 | def apply! 11 | @commands.each do |command| 12 | self.class.sandbox_init command, Playpen::SANDBOX_NAMED 13 | end 14 | end 15 | 16 | constants.each do |const| 17 | class_eval(<<-eoruby, __FILE__, __LINE__ + 1) 18 | def #{const.to_s.downcase} 19 | @commands << #{const} 20 | self 21 | end 22 | 23 | def self.#{const.to_s.downcase} 24 | new.#{const.to_s.downcase} 25 | end 26 | eoruby 27 | end 28 | 29 | class << self 30 | alias :no_writes :no_write 31 | alias :temporary_writes :temp_only_write 32 | alias :pure_computation :computation_only 33 | end 34 | 35 | alias :no_writes :no_write 36 | alias :temporary_writes :temp_only_write 37 | alias :pure_computation :computation_only 38 | end 39 | -------------------------------------------------------------------------------- /ext/playpen/playpen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static VALUE playpen_init(VALUE self, VALUE name, VALUE flags) 5 | { 6 | char * error; 7 | if(sandbox_init(StringValuePtr(name), NUM2INT(flags), &error) < 0) { 8 | rb_raise(rb_eRuntimeError, "%s", error); 9 | } 10 | 11 | return self; 12 | } 13 | 14 | void Init_playpen() 15 | { 16 | VALUE cPlaypen = rb_define_class("Playpen", rb_cObject); 17 | rb_define_const(cPlaypen, "SANDBOX_NAMED", INT2NUM(SANDBOX_NAMED)); 18 | rb_define_const(cPlaypen, "NO_INTERNET", rb_str_new2(kSBXProfileNoInternet)); 19 | rb_define_const(cPlaypen, "NO_NETWORK", rb_str_new2(kSBXProfileNoNetwork)); 20 | rb_define_const(cPlaypen, "NO_WRITE", rb_str_new2(kSBXProfileNoWrite)); 21 | rb_define_const(cPlaypen, "TEMP_ONLY_WRITE", rb_str_new2(kSBXProfileNoWriteExceptTemporary)); 22 | rb_define_const(cPlaypen, "COMPUTATION_ONLY", rb_str_new2(kSBXProfilePureComputation)); 23 | rb_define_singleton_method(cPlaypen, "sandbox_init", playpen_init, 2); 24 | } 25 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = playpen 2 | 3 | * http://github.com/tenderlove/playpen 4 | 5 | == DESCRIPTION: 6 | 7 | Playpen wraps OS X sandbox api with a loving embrace. Playpen provides the 8 | same API that the Sandbox class in MacRuby provides. 9 | 10 | == FEATURES/PROBLEMS: 11 | 12 | * AWESOME 13 | * MANY 14 | 15 | == SYNOPSIS: 16 | 17 | From code: 18 | 19 | require 'playpen' 20 | Playpen.no_internet.apply! 21 | 22 | From the command line (with bundler): 23 | 24 | $ ruby -rubygems -rplaypen/computation_only -S bundle 25 | 26 | == REQUIREMENTS: 27 | 28 | * OS X 10.5 or greater 29 | 30 | == INSTALL: 31 | 32 | * gem install playpen 33 | 34 | == LICENSE: 35 | 36 | (The MIT License) 37 | 38 | Copyright (c) 2010-2011 39 | 40 | * Aaron Patterson 41 | * Evan Phoenix 42 | 43 | Permission is hereby granted, free of charge, to any person obtaining 44 | a copy of this software and associated documentation files (the 45 | 'Software'), to deal in the Software without restriction, including 46 | without limitation the rights to use, copy, modify, merge, publish, 47 | distribute, sublicense, and/or sell copies of the Software, and to 48 | permit persons to whom the Software is furnished to do so, subject to 49 | the following conditions: 50 | 51 | The above copyright notice and this permission notice shall be 52 | included in all copies or substantial portions of the Software. 53 | 54 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 55 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 56 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 57 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 58 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 59 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 60 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 61 | -------------------------------------------------------------------------------- /test/test_playpen.rb: -------------------------------------------------------------------------------- 1 | require "test/unit" 2 | require "playpen" 3 | 4 | class TestPlaypen < Test::Unit::TestCase 5 | def test_constant_exists 6 | assert Playpen::SANDBOX_NAMED, 'yay!' 7 | end 8 | 9 | def test_no_internet 10 | assert Playpen::NO_INTERNET, "woop-be-doop!" 11 | end 12 | 13 | def test_no_network 14 | assert Playpen::NO_NETWORK, "woop-be-doop!" 15 | end 16 | 17 | def test_no_write 18 | assert Playpen::NO_WRITE, "woop-be-doop!" 19 | end 20 | 21 | def test_temp_only_write 22 | assert Playpen::TEMP_ONLY_WRITE, "woop-be-doop!" 23 | end 24 | 25 | def test_computation_only 26 | assert Playpen::COMPUTATION_ONLY, "woop-be-doop!" 27 | end 28 | 29 | def test_sanity 30 | Playpen.sandbox_init(Playpen::NO_INTERNET, Playpen::SANDBOX_NAMED) 31 | end 32 | 33 | def test_chaining 34 | x = fake_pp 35 | x.no_internet.no_network.no_writes.temporary_writes.pure_computation.apply! 36 | assert_equal([ 37 | [Playpen::NO_INTERNET, Playpen::SANDBOX_NAMED], 38 | [Playpen::NO_NETWORK, Playpen::SANDBOX_NAMED], 39 | [Playpen::NO_WRITE, Playpen::SANDBOX_NAMED], 40 | [Playpen::TEMP_ONLY_WRITE, Playpen::SANDBOX_NAMED], 41 | [Playpen::COMPUTATION_ONLY, Playpen::SANDBOX_NAMED], 42 | ], x.args) 43 | end 44 | 45 | def test_class_methods 46 | { 47 | 'no_internet' => Playpen::NO_INTERNET, 48 | 'no_network' => Playpen::NO_NETWORK, 49 | 'no_write' => Playpen::NO_WRITE, 50 | 'temporary_writes' => Playpen::TEMP_ONLY_WRITE, 51 | 'pure_computation' => Playpen::COMPUTATION_ONLY, 52 | }.each do |method, const| 53 | x = fake_pp 54 | x.send(method).apply! 55 | assert_equal([[const, Playpen::SANDBOX_NAMED]], x.args) 56 | end 57 | end 58 | 59 | def fake_pp 60 | Class.new(Playpen) do 61 | class << self 62 | attr_accessor :args 63 | def sandbox_init file, flags 64 | self.args << [file, flags] 65 | end 66 | end 67 | self.args = [] 68 | end 69 | end 70 | end 71 | --------------------------------------------------------------------------------