spoon 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,144 @@
1
+ Apache License
2
+
3
+ Version 2.0, January 2004
4
+
5
+ http://www.apache.org/licenses/
6
+
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
+
9
+ 1. Definitions.
10
+
11
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as
12
+ defined by Sections 1 through 9 of this document.
13
+
14
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that
15
+ is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all other entities that
18
+ control, are controlled by, or are under common control with that entity. For the purposes
19
+ of this definition, "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or otherwise, or (ii) ownership
21
+ of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of
22
+ such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by
25
+ this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications, including but not
28
+ limited to software source code, documentation source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical transformation or translation of
31
+ a Source form, including but not limited to compiled object code, generated documentation,
32
+ and conversions to other media types.
33
+
34
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available
35
+ under the License, as indicated by a copyright notice that is included in or attached to the
36
+ work (an example is provided in the Appendix below).
37
+
38
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on
39
+ (or derived from) the Work and for which the editorial revisions, annotations, elaborations,
40
+ or other modifications represent, as a whole, an original work of authorship. For the
41
+ purposes of this License, Derivative Works shall not include works that remain separable
42
+ from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works
43
+ thereof.
44
+
45
+ "Contribution" shall mean any work of authorship, including the original version of the Work
46
+ and any modifications or additions to that Work or Derivative Works thereof, that is
47
+ intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by
48
+ an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the
49
+ purposes of this definition, "submitted" means any form of electronic, verbal, or written
50
+ communication sent to the Licensor or its representatives, including but not limited to
51
+ communication on electronic mailing lists, source code control systems, and issue tracking
52
+ systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and
53
+ improving the Work, but excluding communication that is conspicuously marked or otherwise
54
+ designated in writing by the copyright owner as "Not a Contribution."
55
+
56
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a
57
+ Contribution has been received by Licensor and subsequently incorporated within the Work.
58
+
59
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each
60
+ Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
61
+ royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of,
62
+ publicly display, publicly perform, sublicense, and distribute the Work and such Derivative
63
+ Works in Source or Object form.
64
+
65
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each
66
+ Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
67
+ royalty-free, irrevocable (except as stated in this section) patent license to make, have
68
+ made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license
69
+ applies only to those patent claims licensable by such Contributor that are necessarily
70
+ infringed by their Contribution(s) alone or by combination of their Contribution(s) with the
71
+ Work to which such Contribution(s) was submitted. If You institute patent litigation against
72
+ any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or
73
+ a Contribution incorporated within the Work constitutes direct or contributory patent
74
+ infringement, then any patent licenses granted to You under this License for that Work shall
75
+ terminate as of the date such litigation is filed.
76
+
77
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works
78
+ thereof in any medium, with or without modifications, and in Source or Object form, provided
79
+ that You meet the following conditions:
80
+
81
+ You must give any other recipients of the Work or Derivative Works a copy of this License;
82
+ and
83
+
84
+ You must cause any modified files to carry prominent notices stating that You changed the
85
+ files; and
86
+
87
+ You must retain, in the Source form of any Derivative Works that You distribute, all
88
+ copyright, patent, trademark, and attribution notices from the Source form of the Work,
89
+ excluding those notices that do not pertain to any part of the Derivative Works; and
90
+
91
+ If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative
92
+ Works that You distribute must include a readable copy of the attribution notices contained
93
+ within such NOTICE file, excluding those notices that do not pertain to any part of the
94
+ Derivative Works, in at least one of the following places: within a NOTICE text file
95
+ distributed as part of the Derivative Works; within the Source form or documentation, if
96
+ provided along with the Derivative Works; or, within a display generated by the Derivative
97
+ Works, if and wherever such third-party notices normally appear. The contents of the NOTICE
98
+ file are for informational purposes only and do not modify the License. You may add Your own
99
+ attribution notices within Derivative Works that You distribute, alongside or as an addendum
100
+ to the NOTICE text from the Work, provided that such additional attribution notices cannot
101
+ be construed as modifying the License. You may add Your own copyright statement to Your
102
+ modifications and may provide additional or different license terms and conditions for use,
103
+ reproduction, or distribution of Your modifications, or for any such Derivative Works as a
104
+ whole, provided Your use, reproduction, and distribution of the Work otherwise complies with
105
+ the conditions stated in this License.
106
+
107
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution
108
+ intentionally submitted for inclusion in the Work by You to the Licensor shall be under the
109
+ terms and conditions of this License, without any additional terms or conditions.
110
+ Notwithstanding the above, nothing herein shall supersede or modify the terms of any
111
+ separate license agreement you may have executed with Licensor regarding such Contributions.
112
+
113
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks,
114
+ service marks, or product names of the Licensor, except as required for reasonable and
115
+ customary use in describing the origin of the Work and reproducing the content of the NOTICE
116
+ file.
117
+
118
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing,
119
+ Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS"
120
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
121
+ without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
122
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
123
+ determining the appropriateness of using or redistributing the Work and assume any risks
124
+ associated with Your exercise of permissions under this License.
125
+
126
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort
127
+ (including negligence), contract, or otherwise, unless required by applicable law (such as
128
+ deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be
129
+ liable to You for damages, including any direct, indirect, special, incidental, or
130
+ consequential damages of any character arising as a result of this License or out of the use
131
+ or inability to use the Work (including but not limited to damages for loss of goodwill,
132
+ work stoppage, computer failure or malfunction, or any and all other commercial damages or
133
+ losses), even if such Contributor has been advised of the possibility of such damages.
134
+
135
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative
136
+ Works thereof, You may choose to offer, and charge a fee for, acceptance of support,
137
+ warranty, indemnity, or other liability obligations and/or rights consistent with this
138
+ License. However, in accepting such obligations, You may act only on Your own behalf and on
139
+ Your sole responsibility, not on behalf of any other Contributor, and only if You agree to
140
+ indemnify, defend, and hold each Contributor harmless for any liability incurred by, or
141
+ claims asserted against, such Contributor by reason of your accepting any such warranty or
142
+ additional liability.
143
+
144
+ END OF TERMS AND CONDITIONS
@@ -0,0 +1,25 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'spoon'
14
+
15
+ #
16
+ # Do a recursive ls on the current directory, redirecting output to /tmp/ls.out
17
+ #
18
+
19
+ file_actions = Spoon::FileActions.new
20
+ file_actions.close(1)
21
+ file_actions.open(1, "/tmp/ls.out", File::WRONLY | File::TRUNC | File::CREAT, 0600)
22
+ spawn_attr = Spoon::SpawnAttributes.new
23
+ pid = Spoon.posix_spawn('/usr/bin/env', file_actions, spawn_attr, %w(env ls -R))
24
+
25
+ Process.waitpid(pid)
@@ -0,0 +1,16 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'spoon'
14
+
15
+ Spoon.spawnp 'vi'
16
+ Process.waitall
@@ -1,49 +1,19 @@
1
- require 'ffi'
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
2
12
 
3
- module Spoon
4
- extend FFI::Library
5
- ffi_lib 'c'
6
-
7
- # int
8
- # posix_spawn(pid_t *restrict pid, const char *restrict path,
9
- # const posix_spawn_file_actions_t *file_actions,
10
- # const posix_spawnattr_t *restrict attrp, char *const argv[restrict],
11
- # char *const envp[restrict]);
12
-
13
- attach_function :_posix_spawn, :posix_spawn, [:pointer, :string, :pointer, :pointer, :pointer, :pointer], :int
14
- attach_function :_posix_spawnp, :posix_spawnp, [:pointer, :string, :pointer, :pointer, :pointer, :pointer], :int
15
-
16
- def self.spawn(*args)
17
- spawn_args = _prepare_spawn_args(args)
18
- _posix_spawn(*spawn_args)
19
- spawn_args[0].read_int
20
- end
13
+ require 'rbconfig'
21
14
 
22
- def self.spawnp(*args)
23
- spawn_args = _prepare_spawn_args(args)
24
- _posix_spawnp(*spawn_args)
25
- spawn_args[0].read_int
26
- end
27
-
28
- private
29
-
30
- def self._prepare_spawn_args(args)
31
- pid_ptr = FFI::MemoryPointer.new(:pid_t, 1)
32
-
33
- args_ary = FFI::MemoryPointer.new(:pointer, args.length + 1)
34
- str_ptrs = args.map {|str| FFI::MemoryPointer.from_string(str)}
35
- args_ary.put_array_of_pointer(0, str_ptrs)
36
-
37
- env_ary = FFI::MemoryPointer.new(:pointer, ENV.length + 1)
38
- env_ptrs = ENV.map {|key,value| FFI::MemoryPointer.from_string("#{key}=#{value}")}
39
- env_ary.put_array_of_pointer(0, env_ptrs)
40
-
41
- [pid_ptr, args[0], nil, nil, args_ary, env_ary]
42
- end
43
- end
44
-
45
- if __FILE__ == $0
46
- pid = Spoon.spawn('/usr/bin/vim')
47
-
48
- Process.waitpid(pid)
15
+ if RbConfig::CONFIG['host_os'] =~ /mingw|mswin|bccwin/
16
+ require 'spoon/windows'
17
+ else
18
+ require 'spoon/unix'
49
19
  end
@@ -0,0 +1,177 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ # UNIX posix_spawn
14
+
15
+ require 'ffi'
16
+
17
+ module Spoon
18
+ class FileActions
19
+ attr_reader :pointer
20
+ SIZE = FFI::Platform.mac? ? FFI.type_size(:pointer) : 128
21
+
22
+ def initialize
23
+ @pointer = FFI::AutoPointer.new(LibC.malloc(SIZE), self.class)
24
+ error = LibC.posix_spawn_file_actions_init(@pointer)
25
+ raise SystemCallError.new("posix_file_actions_init", error) unless error == 0
26
+ end
27
+
28
+ def self.release(ptr)
29
+ LibC.posix_spawn_file_actions_destroy(ptr)
30
+ LibC.free(ptr)
31
+ end
32
+
33
+ def open(fd, path, oflag, mode)
34
+ error = LibC.posix_spawn_file_actions_addopen(@pointer, fd, path, oflag, mode)
35
+ raise SystemCallError.new("posix_file_actions_addopen", error) unless error == 0
36
+ self
37
+ end
38
+
39
+ def close(fd)
40
+ error = LibC.posix_spawn_file_actions_addclose(@pointer, fd)
41
+ raise SystemCallError.new("posix_file_actions_addclose", error) unless error == 0
42
+ self
43
+ end
44
+
45
+ def dup2(fd, newfd)
46
+ error = LibC.posix_spawn_file_actions_adddup2(@pointer, fd, newfd)
47
+ raise SystemCallError.new("posix_file_actions_adddup2", error) unless error == 0
48
+ self
49
+ end
50
+ end
51
+
52
+ class SpawnAttributes
53
+ attr_reader :pointer
54
+ SIZE = FFI::Platform.mac? ? FFI.type_size(:pointer) : 128
55
+
56
+ def initialize
57
+ @pointer = FFI::AutoPointer.new(LibC.malloc(SIZE), self.class)
58
+ error = LibC.posix_spawnattr_init(@pointer)
59
+ raise SystemCallError.new("posix_spawnattr_init", error) unless error == 0
60
+ end
61
+
62
+ def self.release(ptr)
63
+ LibC.posix_spawnattr_destroy(ptr)
64
+ LibC.free(ptr)
65
+ end
66
+
67
+ def pgroup=(group)
68
+ error = LibC.posix_spawnattr_setpgroup(pointer, group)
69
+ raise SystemCallError.new("posix_spawnattr_setpgroup", error) unless error == 0
70
+ group
71
+ end
72
+
73
+ def pgroup
74
+ group = FFI::MemoryPointer.new :pid_t
75
+ error = LibC.posix_spawnattr_getpgroup(pointer, group)
76
+ raise SystemCallError.new("posix_spawnattr_getpgroup", error) unless error == 0
77
+ get_pid(group)
78
+ end
79
+ end
80
+
81
+ def self.posix_spawn(path, file_actions, spawn_attr, argv, env = ENV)
82
+ pid_ptr, argv_ptr, env_ptr = _prepare_spawn_args(argv, env)
83
+ error = LibC.posix_spawnp(pid_ptr, path, file_actions, spawn_attr, argv_ptr, env_ptr)
84
+ raise SystemCallError.new(path, error) unless error == 0
85
+ get_pid(pid_ptr)
86
+ end
87
+
88
+ def self.posix_spawnp(file, file_actions, spawn_attr, argv, env = ENV)
89
+ pid_ptr, argv_ptr, env_ptr = _prepare_spawn_args(argv, env)
90
+ error = LibC.posix_spawnp(pid_ptr, file, file_actions, spawn_attr, argv_ptr, env_ptr)
91
+ raise SystemCallError.new(file, error) unless error == 0
92
+ get_pid(pid_ptr)
93
+ end
94
+
95
+ def self.spawn(*args)
96
+ posix_spawn(args[0], nil, nil, args, ENV)
97
+ end
98
+
99
+ def self.spawnp(*args)
100
+ posix_spawnp(args[0], nil, nil, args, ENV)
101
+ end
102
+
103
+ private
104
+
105
+ class PointerArray
106
+ def initialize
107
+ @ary = []
108
+ end
109
+
110
+ def <<(ptr)
111
+ @ary << ptr
112
+ self
113
+ end
114
+
115
+ def pointer
116
+ if @pointer.nil? || (@pointer.size / @pointer.type_size) <= @ary.length
117
+ ptr = FFI::MemoryPointer.new(:pointer, @ary.length + 1)
118
+ ptr.put_array_of_pointer(0, @ary)
119
+ @pointer = ptr
120
+ end
121
+ @pointer
122
+ end
123
+ end
124
+
125
+ if FFI.type_size(:pid_t) == 4
126
+ def self.get_pid(ptr)
127
+ ptr.get_int32(0)
128
+ end
129
+ else
130
+ def self.get_pid(ptr)
131
+ ptr.get_int64(0)
132
+ end
133
+ end
134
+
135
+ module LibC
136
+ extend FFI::Library
137
+ ffi_lib FFI::Library::LIBC
138
+
139
+ class PointerConverter
140
+ extend FFI::DataConverter
141
+ native_type FFI::Type::POINTER
142
+
143
+ def self.to_native(value, ctx)
144
+ value ? value.pointer : nil
145
+ end
146
+ end
147
+
148
+ typedef PointerConverter, :file_actions
149
+ typedef PointerConverter, :spawn_attr
150
+ typedef PointerConverter, :ptr_array
151
+
152
+ attach_function :posix_spawn, [:pointer, :string, :file_actions, :spawn_attr, :ptr_array, :ptr_array ], :int
153
+ attach_function :posix_spawnp, [:pointer, :string, :file_actions, :spawn_attr, :ptr_array, :ptr_array ], :int
154
+ attach_function :posix_spawn_file_actions_init, [ :pointer ], :int
155
+ attach_function :posix_spawn_file_actions_destroy, [ :pointer ], :int
156
+ attach_function :posix_spawn_file_actions_adddup2, [ :pointer, :int, :int ], :int
157
+ attach_function :posix_spawn_file_actions_addclose, [ :pointer, :int ], :int
158
+ attach_function :posix_spawn_file_actions_addopen, [ :pointer, :int, :string, :int, :mode_t ], :int
159
+ attach_function :posix_spawnattr_init, [ :pointer ], :int
160
+ attach_function :posix_spawnattr_destroy, [ :pointer ], :int
161
+ attach_function :posix_spawnattr_setpgroup, [ :pointer, :pid_t ], :int
162
+ attach_function :posix_spawnattr_getpgroup, [ :pointer, :pointer ], :int
163
+ attach_function :malloc, [ :size_t ], :pointer
164
+ attach_function :free, [ :pointer ], :void
165
+ attach_function :strerror, [ :int ], :string
166
+ end
167
+
168
+ def self._prepare_spawn_args(argv, env)
169
+ pid_ptr = FFI::MemoryPointer.new(:pid_t, 1)
170
+
171
+ args_ary = argv.inject(PointerArray.new) { |ary, str| ary << FFI::MemoryPointer.from_string(str) }
172
+ env_ary = PointerArray.new
173
+ env.each_pair { |key, value| env_ary << FFI::MemoryPointer.from_string("#{key}=#{value}") }
174
+
175
+ [pid_ptr, args_ary, env_ary]
176
+ end
177
+ end
@@ -0,0 +1,50 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ # Windows _spawnv
14
+
15
+ require 'ffi'
16
+
17
+ module Spoon
18
+ P_NOWAIT = 1
19
+
20
+ attach_function :_spawnve, [:int, :string, :pointer, :pointer], :int
21
+ attach_function :_spawnvpe, [:int, :string, :pointer, :pointer], :int
22
+
23
+ ffi_lib 'kernel32'
24
+ ffi_convention :stdcall
25
+ attach_function :_get_process_id, :GetProcessId, [:int], :ulong
26
+
27
+ def self.spawn(*args)
28
+ spawn_args = _prepare_spawn_args(args)
29
+ _get_process_id(_spawnve(*spawn_args))
30
+ end
31
+
32
+ def self.spawnp(*args)
33
+ spawn_args = _prepare_spawn_args(args)
34
+ _get_process_id(_spawnvpe(*spawn_args))
35
+ end
36
+
37
+ private
38
+
39
+ def self._prepare_spawn_args(args)
40
+ args_ary = FFI::MemoryPointer.new(:pointer, args.length + 1)
41
+ str_ptrs = args.map {|str| FFI::MemoryPointer.from_string(str)}
42
+ args_ary.put_array_of_pointer(0, str_ptrs)
43
+
44
+ env_ary = FFI::MemoryPointer.new(:pointer, ENV.length + 1)
45
+ env_ptrs = ENV.map {|key,value| FFI::MemoryPointer.from_string("#{key}=#{value}")}
46
+ env_ary.put_array_of_pointer(0, env_ptrs)
47
+
48
+ [P_NOWAIT, args[0], args_ary, env_ary]
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "spoon"
3
+ s.version = "0.0.3"
4
+ s.authors = ["Charles Oliver Nutter"]
5
+ s.date = "2013-03-29"
6
+ 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."
7
+ s.files = `git ls-files`.lines.map(&:chomp)
8
+ s.require_paths = ["lib"]
9
+ s.add_dependency('ffi')
10
+ end
metadata CHANGED
@@ -1,55 +1,67 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: spoon
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
- - Charles Oliver Nutter
8
- autorequire:
7
+ authors:
8
+ - Charles Oliver Nutter
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2010-01-10 00:00:00 -06:00
13
- default_executable:
14
- dependencies: []
15
-
16
- description: Spoon is an FFI binding of the posix_spawn function, providing fork+exec functionality in a single shot.
17
- email:
12
+ date: 2013-03-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ none: false
28
+ prerelease: false
29
+ type: :runtime
30
+ description: Spoon is an FFI binding of the posix_spawn function (and Windows equivalent), providing fork+exec functionality in a single shot.
31
+ email:
18
32
  executables: []
19
-
20
33
  extensions: []
21
-
22
34
  extra_rdoc_files: []
23
-
24
- files:
25
- - lib/spoon.rb
26
- has_rdoc: true
27
- homepage:
35
+ files:
36
+ - LICENSE
37
+ - examples/ls.rb
38
+ - examples/vi.rb
39
+ - lib/spoon.rb
40
+ - lib/spoon/unix.rb
41
+ - lib/spoon/windows.rb
42
+ - spoon.gemspec
43
+ homepage:
28
44
  licenses: []
29
-
30
- post_install_message:
45
+ post_install_message:
31
46
  rdoc_options: []
32
-
33
- require_paths:
34
- - lib
35
- required_ruby_version: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: "0"
40
- version:
41
- required_rubygems_version: !ruby/object:Gem::Requirement
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- version: "0"
46
- version:
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ none: false
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ none: false
47
61
  requirements: []
48
-
49
- rubyforge_project:
50
- rubygems_version: 1.3.5
51
- signing_key:
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.24
64
+ signing_key:
52
65
  specification_version: 3
53
- summary: Spoon is an FFI binding of the posix_spawn function, providing fork+exec functionality in a single shot.
66
+ summary: Spoon is an FFI binding of the posix_spawn function (and Windows equivalent), providing fork+exec functionality in a single shot.
54
67
  test_files: []
55
-