[DRE-commits] [SCM] ruby-spoon.git branch, master, updated. upstream/0.0.1+git20121127-8-g3f87d68

Hideki Yamane henrich at debian.org
Fri Jan 4 02:48:40 UTC 2013


The following commit has been merged in the master branch:
commit 4ae728dae21ab02233bf65a0ce610af01a5011b6
Author: Hideki Yamane <henrich at debian.org>
Date:   Fri Jan 4 11:46:11 2013 +0900

    Imported Upstream version 0.0.2~git20130104

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5336718
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,144 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as 
+defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that 
+is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that 
+control, are controlled by, or are under common control with that entity. For the purposes 
+of this definition, "control" means (i) the power, direct or indirect, to cause the 
+direction or management of such entity, whether by contract or otherwise, or (ii) ownership 
+of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of 
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by 
+this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not 
+limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of 
+a Source form, including but not limited to compiled object code, generated documentation, 
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available 
+under the License, as indicated by a copyright notice that is included in or attached to the 
+work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on 
+(or derived from) the Work and for which the editorial revisions, annotations, elaborations, 
+or other modifications represent, as a whole, an original work of authorship. For the 
+purposes of this License, Derivative Works shall not include works that remain separable 
+from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works 
+thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work 
+and any modifications or additions to that Work or Derivative Works thereof, that is 
+intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by 
+an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the 
+purposes of this definition, "submitted" means any form of electronic, verbal, or written 
+communication sent to the Licensor or its representatives, including but not limited to 
+communication on electronic mailing lists, source code control systems, and issue tracking 
+systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and 
+improving the Work, but excluding communication that is conspicuously marked or otherwise 
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a 
+Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, 
+publicly display, publicly perform, sublicense, and distribute the Work and such Derivative 
+Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each 
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, 
+royalty-free, irrevocable (except as stated in this section) patent license to make, have 
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license 
+applies only to those patent claims licensable by such Contributor that are necessarily 
+infringed by their Contribution(s) alone or by combination of their Contribution(s) with the 
+Work to which such Contribution(s) was submitted. If You institute patent litigation against 
+any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or 
+a Contribution incorporated within the Work constitutes direct or contributory patent 
+infringement, then any patent licenses granted to You under this License for that Work shall 
+terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works 
+thereof in any medium, with or without modifications, and in Source or Object form, provided 
+that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; 
+and
+
+You must cause any modified files to carry prominent notices stating that You changed the 
+files; and
+
+You must retain, in the Source form of any Derivative Works that You distribute, all 
+copyright, patent, trademark, and attribution notices from the Source form of the Work, 
+excluding those notices that do not pertain to any part of the Derivative Works; and
+
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative 
+Works that You distribute must include a readable copy of the attribution notices contained 
+within such NOTICE file, excluding those notices that do not pertain to any part of the 
+Derivative Works, in at least one of the following places: within a NOTICE text file 
+distributed as part of the Derivative Works; within the Source form or documentation, if 
+provided along with the Derivative Works; or, within a display generated by the Derivative 
+Works, if and wherever such third-party notices normally appear. The contents of the NOTICE 
+file are for informational purposes only and do not modify the License. You may add Your own 
+attribution notices within Derivative Works that You distribute, alongside or as an addendum 
+to the NOTICE text from the Work, provided that such additional attribution notices cannot 
+be construed as modifying the License. You may add Your own copyright statement to Your 
+modifications and may provide additional or different license terms and conditions for use, 
+reproduction, or distribution of Your modifications, or for any such Derivative Works as a 
+whole, provided Your use, reproduction, and distribution of the Work otherwise complies with 
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution 
+intentionally submitted for inclusion in the Work by You to the Licensor shall be under the 
+terms and conditions of this License, without any additional terms or conditions. 
+Notwithstanding the above, nothing herein shall supersede or modify the terms of any 
+separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, 
+service marks, or product names of the Licensor, except as required for reasonable and 
+customary use in describing the origin of the Work and reproducing the content of the NOTICE 
+file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, 
+Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" 
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, 
+without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, 
+MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for 
+determining the appropriateness of using or redistributing the Work and assume any risks 
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort 
+(including negligence), contract, or otherwise, unless required by applicable law (such as 
+deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be 
+liable to You for damages, including any direct, indirect, special, incidental, or 
+consequential damages of any character arising as a result of this License or out of the use 
+or inability to use the Work (including but not limited to damages for loss of goodwill, 
+work stoppage, computer failure or malfunction, or any and all other commercial damages or 
+losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative 
+Works thereof, You may choose to offer, and charge a fee for, acceptance of support, 
+warranty, indemnity, or other liability obligations and/or rights consistent with this 
+License. However, in accepting such obligations, You may act only on Your own behalf and on 
+Your sole responsibility, not on behalf of any other Contributor, and only if You agree to 
+indemnify, defend, and hold each Contributor harmless for any liability incurred by, or 
+claims asserted against, such Contributor by reason of your accepting any such warranty or 
+additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/examples/ls.rb b/examples/ls.rb
new file mode 100644
index 0000000..bb6491f
--- /dev/null
+++ b/examples/ls.rb
@@ -0,0 +1,13 @@
+require 'spoon'
+
+#
+# Do a recursive ls on the current directory, redirecting output to /tmp/ls.out
+#
+
+file_actions = Spoon::FileActions.new
+file_actions.close(1)
+file_actions.open(1, "/tmp/ls.out", File::WRONLY | File::TRUNC | File::CREAT, 0600)
+spawn_attr = Spoon::SpawnAttributes.new
+pid = Spoon.posix_spawn('/usr/bin/env', file_actions, spawn_attr, %w(env ls -R))
+
+Process.waitpid(pid)
diff --git a/examples/vi.rb b/examples/vi.rb
new file mode 100644
index 0000000..6105483
--- /dev/null
+++ b/examples/vi.rb
@@ -0,0 +1,4 @@
+require 'spoon'
+
+Spoon.spawnp 'vi'
+Process.waitall
\ No newline at end of file
diff --git a/lib/spoon.rb b/lib/spoon.rb
old mode 100644
new mode 100755
index 7db99c5..3f11266
--- a/lib/spoon.rb
+++ b/lib/spoon.rb
@@ -1,49 +1,7 @@
-require 'ffi'
+require 'rbconfig'
 
-module Spoon
-  extend FFI::Library
-  ffi_lib 'c'
-  
-  # int
-  # posix_spawn(pid_t *restrict pid, const char *restrict path,
-  #     const posix_spawn_file_actions_t *file_actions,
-  #     const posix_spawnattr_t *restrict attrp, char *const argv[restrict],
-  #     char *const envp[restrict]);
-  
-  attach_function :_posix_spawn, :posix_spawn, [:pointer, :string, :pointer, :pointer, :pointer, :pointer], :int
-  attach_function :_posix_spawnp, :posix_spawnp, [:pointer, :string, :pointer, :pointer, :pointer, :pointer], :int
-  
-  def self.spawn(*args)
-    spawn_args = _prepare_spawn_args(args)
-    _posix_spawn(*spawn_args)
-    spawn_args[0].read_int
-  end
-
-  def self.spawnp(*args)
-    spawn_args = _prepare_spawn_args(args)
-    _posix_spawnp(*spawn_args)
-    spawn_args[0].read_int
-  end
-  
-  private
-  
-  def self._prepare_spawn_args(args)
-    pid_ptr = FFI::MemoryPointer.new(:pid_t, 1)
-
-    args_ary = FFI::MemoryPointer.new(:pointer, args.length + 1)
-    str_ptrs = args.map {|str| FFI::MemoryPointer.from_string(str)}
-    args_ary.put_array_of_pointer(0, str_ptrs)
-
-    env_ary = FFI::MemoryPointer.new(:pointer, ENV.length + 1)
-    env_ptrs = ENV.map {|key,value| FFI::MemoryPointer.from_string("#{key}=#{value}")}
-    env_ary.put_array_of_pointer(0, env_ptrs)
-    
-    [pid_ptr, args[0], nil, nil, args_ary, env_ary]
-  end
-end
-
-if __FILE__ == $0
-  pid = Spoon.spawn('/usr/bin/vim')
-
-  Process.waitpid(pid)
+if RbConfig::CONFIG['host_os'] =~ /mingw|mswin|bccwin/
+  require 'spoon/windows'
+else
+  require 'spoon/unix'
 end
diff --git a/lib/spoon/unix.rb b/lib/spoon/unix.rb
new file mode 100644
index 0000000..dd0e5b3
--- /dev/null
+++ b/lib/spoon/unix.rb
@@ -0,0 +1,165 @@
+# UNIX posix_spawn
+
+require 'ffi'
+
+module Spoon
+  class FileActions
+    attr_reader :pointer
+    SIZE = FFI::Platform.mac? ? FFI.type_size(:pointer) : 128
+
+    def initialize
+      @pointer =  FFI::AutoPointer.new(LibC.malloc(SIZE), self.class)
+      error = LibC.posix_spawn_file_actions_init(@pointer)
+      raise SystemCallError.new("posix_file_actions_init", error) unless error == 0
+    end
+
+    def self.release(ptr)
+      LibC.posix_spawn_file_actions_destroy(ptr)
+      LibC.free(ptr)
+    end
+
+    def open(fd, path, oflag, mode)
+      error = LibC.posix_spawn_file_actions_addopen(@pointer, fd, path, oflag, mode)
+      raise SystemCallError.new("posix_file_actions_addopen", error) unless error == 0
+      self
+    end
+
+    def close(fd)
+      error = LibC.posix_spawn_file_actions_addclose(@pointer, fd)
+      raise SystemCallError.new("posix_file_actions_addclose", error) unless error == 0
+      self
+    end
+
+    def dup2(fd, newfd)
+      error = LibC.posix_spawn_file_actions_adddup2(@pointer, fd, newfd)
+      raise SystemCallError.new("posix_file_actions_adddup2", error) unless error == 0
+      self
+    end
+  end
+
+  class SpawnAttributes
+    attr_reader :pointer
+    SIZE = FFI::Platform.mac? ? FFI.type_size(:pointer) : 128
+
+    def initialize
+      @pointer =  FFI::AutoPointer.new(LibC.malloc(SIZE), self.class)
+      error = LibC.posix_spawnattr_init(@pointer)
+      raise SystemCallError.new("posix_spawnattr_init", error) unless error == 0
+    end
+
+    def self.release(ptr)
+      LibC.posix_spawnattr_destroy(ptr)
+      LibC.free(ptr)
+    end
+
+    def pgroup=(group)
+      error = LibC.posix_spawnattr_setpgroup(pointer, group)
+      raise SystemCallError.new("posix_spawnattr_setpgroup", error) unless error == 0
+      group
+    end
+
+    def pgroup
+      group = FFI::MemoryPointer.new :pid_t
+      error = LibC.posix_spawnattr_getpgroup(pointer, group)
+      raise SystemCallError.new("posix_spawnattr_getpgroup", error) unless error == 0
+      get_pid(group)
+    end
+  end
+
+  def self.posix_spawn(path, file_actions, spawn_attr, argv, env = ENV)
+    pid_ptr, argv_ptr, env_ptr = _prepare_spawn_args(argv, env)
+    error = LibC.posix_spawnp(pid_ptr, path, file_actions, spawn_attr, argv_ptr, env_ptr)
+    raise SystemCallError.new(path, error) unless error == 0
+    get_pid(pid_ptr)
+  end
+
+  def self.posix_spawnp(file, file_actions, spawn_attr, argv, env = ENV)
+    pid_ptr, argv_ptr, env_ptr = _prepare_spawn_args(argv, env)
+    error = LibC.posix_spawnp(pid_ptr, file, file_actions, spawn_attr, argv_ptr, env_ptr)
+    raise SystemCallError.new(file, error) unless error == 0
+    get_pid(pid_ptr)
+  end
+
+  def self.spawn(*args)
+    posix_spawn(args[0], nil, nil, args, ENV)
+  end
+
+  def self.spawnp(*args)
+    posix_spawnp(args[0], nil, nil, args, ENV)
+  end
+  
+  private
+
+  class PointerArray
+    def initialize
+      @ary = []
+    end
+
+    def <<(ptr)
+      @ary << ptr
+      self
+    end
+
+    def pointer
+      if @pointer.nil? || (@pointer.size / @pointer.type_size) <= @ary.length
+	ptr = FFI::MemoryPointer.new(:pointer, @ary.length + 1)
+	ptr.put_array_of_pointer(0, @ary)
+	@pointer = ptr
+      end
+      @pointer
+    end
+  end
+
+  if FFI.type_size(:pid_t) == 4
+    def self.get_pid(ptr)
+      ptr.get_int32(0)
+    end
+  else
+    def self.get_pid(ptr)
+      ptr.get_int64(0)
+    end
+  end
+
+  module LibC
+    extend FFI::Library
+    ffi_lib FFI::Library::LIBC
+
+    class PointerConverter
+      extend FFI::DataConverter
+      native_type FFI::Type::POINTER
+
+      def self.to_native(value, ctx)
+	value ? value.pointer : nil
+      end
+    end
+
+    typedef PointerConverter, :file_actions
+    typedef PointerConverter, :spawn_attr
+    typedef PointerConverter, :ptr_array
+
+    attach_function :posix_spawn, [:pointer, :string, :file_actions, :spawn_attr, :ptr_array, :ptr_array ], :int
+    attach_function :posix_spawnp, [:pointer, :string, :file_actions, :spawn_attr, :ptr_array, :ptr_array ], :int
+    attach_function :posix_spawn_file_actions_init, [ :pointer ], :int
+    attach_function :posix_spawn_file_actions_destroy, [ :pointer ], :int
+    attach_function :posix_spawn_file_actions_adddup2, [ :pointer, :int, :int ], :int
+    attach_function :posix_spawn_file_actions_addclose, [ :pointer, :int ], :int
+    attach_function :posix_spawn_file_actions_addopen, [ :pointer, :int, :string, :int, :mode_t ], :int
+    attach_function :posix_spawnattr_init, [ :pointer ], :int
+    attach_function :posix_spawnattr_destroy, [ :pointer ], :int
+    attach_function :posix_spawnattr_setpgroup, [ :pointer, :pid_t ], :int
+    attach_function :posix_spawnattr_getpgroup, [ :pointer, :pointer ], :int
+    attach_function :malloc, [ :size_t ], :pointer
+    attach_function :free, [ :pointer ], :void
+    attach_function :strerror, [ :int ], :string
+  end
+
+  def self._prepare_spawn_args(argv, env)
+    pid_ptr = FFI::MemoryPointer.new(:pid_t, 1)
+
+    args_ary = argv.inject(PointerArray.new) { |ary, str| ary << FFI::MemoryPointer.from_string(str) }
+    env_ary = PointerArray.new
+    env.each_pair { |key, value| env_ary << FFI::MemoryPointer.from_string("#{key}=#{value}") }
+
+    [pid_ptr, args_ary, env_ary]
+  end
+end
diff --git a/lib/spoon/windows.rb b/lib/spoon/windows.rb
new file mode 100644
index 0000000..57154f7
--- /dev/null
+++ b/lib/spoon/windows.rb
@@ -0,0 +1,38 @@
+# Windows _spawnv
+
+require 'ffi'
+
+module Spoon
+  P_NOWAIT = 1
+  
+  attach_function :_spawnve, [:int, :string, :pointer, :pointer], :int
+  attach_function :_spawnvpe, [:int, :string, :pointer, :pointer], :int
+  
+  ffi_lib 'kernel32'
+  ffi_convention :stdcall
+  attach_function :_get_process_id, :GetProcessId, [:int], :ulong
+  
+  def self.spawn(*args)
+    spawn_args = _prepare_spawn_args(args)
+    _get_process_id(_spawnve(*spawn_args))
+  end
+  
+  def self.spawnp(*args)
+    spawn_args = _prepare_spawn_args(args)
+    _get_process_id(_spawnvpe(*spawn_args))
+  end
+  
+  private
+  
+  def self._prepare_spawn_args(args)
+    args_ary = FFI::MemoryPointer.new(:pointer, args.length + 1)
+    str_ptrs = args.map {|str| FFI::MemoryPointer.from_string(str)}
+    args_ary.put_array_of_pointer(0, str_ptrs)
+
+    env_ary = FFI::MemoryPointer.new(:pointer, ENV.length + 1)
+    env_ptrs = ENV.map {|key,value| FFI::MemoryPointer.from_string("#{key}=#{value}")}
+    env_ary.put_array_of_pointer(0, env_ptrs)
+    
+    [P_NOWAIT, args[0], args_ary, env_ary]
+  end
+end
diff --git a/metadata.yml b/metadata.yml
deleted file mode 100644
index f74f6ea..0000000
--- a/metadata.yml
+++ /dev/null
@@ -1,55 +0,0 @@
---- !ruby/object:Gem::Specification 
-name: spoon
-version: !ruby/object:Gem::Version 
-  version: 0.0.1
-platform: ruby
-authors: 
-  - Charles Oliver Nutter
-autorequire: 
-bindir: bin
-cert_chain: []
-
-date: 2010-01-10 00:00:00 -06:00
-default_executable: 
-dependencies: []
-
-description: Spoon is an FFI binding of the posix_spawn function, providing fork+exec functionality in a single shot.
-email: 
-executables: []
-
-extensions: []
-
-extra_rdoc_files: []
-
-files: 
-  - lib/spoon.rb
-has_rdoc: true
-homepage: 
-licenses: []
-
-post_install_message: 
-rdoc_options: []
-
-require_paths: 
-  - lib
-required_ruby_version: !ruby/object:Gem::Requirement 
-  requirements: 
-    - - ">="
-      - !ruby/object:Gem::Version 
-        version: "0"
-  version: 
-required_rubygems_version: !ruby/object:Gem::Requirement 
-  requirements: 
-    - - ">="
-      - !ruby/object:Gem::Version 
-        version: "0"
-  version: 
-requirements: []
-
-rubyforge_project: 
-rubygems_version: 1.3.5
-signing_key: 
-specification_version: 3
-summary: Spoon is an FFI binding of the posix_spawn function, providing fork+exec functionality in a single shot.
-test_files: []
-
diff --git a/spoon.gemspec b/spoon.gemspec
new file mode 100644
index 0000000..b6a28fb
--- /dev/null
+++ b/spoon.gemspec
@@ -0,0 +1,10 @@
+Gem::Specification.new do |s|
+  s.name = "spoon"
+  s.version = "0.0.2"
+  s.authors = ["Charles Oliver Nutter"]
+  s.date = "2012-04-20"
+  s.description = s.summary = "Spoon is an FFI binding of the posix_spawn function (and Windows equivalent), providing fork+exec functionality in a single shot."
+  s.files = "lib/spoon.rb"
+  s.require_paths = ["lib"]
+  s.add_dependency('ffi') unless defined?(JRUBY_VERSION) # JRuby includes ffi
+end

-- 
ruby-spoon.git



More information about the Pkg-ruby-extras-commits mailing list