childprocess 0.1.3 → 0.1.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
data/childprocess.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{childprocess}
8
- s.version = "0.1.3"
8
+ s.version = "0.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jari Bakken"]
12
- s.date = %q{2010-10-17}
12
+ s.date = %q{2010-11-08}
13
13
  s.description = %q{This gem aims at being a simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.}
14
14
  s.email = %q{jari.bakken@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -19,6 +19,7 @@ module ChildProcess
19
19
  @args = args
20
20
  @started = false
21
21
  @exit_code = nil
22
+ @detach = false
22
23
  end
23
24
 
24
25
  #
@@ -112,6 +113,10 @@ module ChildProcess
112
113
  @started
113
114
  end
114
115
 
116
+ def detach?
117
+ @detach
118
+ end
119
+
115
120
  def log(*args)
116
121
  $stderr.puts "#{self.inspect} : #{args.inspect}" if $DEBUG
117
122
  end
@@ -79,7 +79,7 @@ module ChildProcess
79
79
  exec(*@args)
80
80
  }
81
81
 
82
- ::Process.detach(@pid) if @detach
82
+ ::Process.detach(@pid) if detach?
83
83
  end
84
84
 
85
85
  end # Process
@@ -28,6 +28,17 @@ module ChildProcess
28
28
  [pid, code] if code
29
29
  end
30
30
 
31
+ def dont_inherit(file)
32
+ unless file.respond_to?(:fileno)
33
+ raise ArgumentError, "expected #{file.inspect} to respond to :fileno"
34
+ end
35
+
36
+ handle = Lib.get_os_file_handle(file.fileno)
37
+
38
+ ok = Lib.set_handle_information(handle, HANDLE_FLAG_INHERIT, 0)
39
+ ok or raise Error, Lib.last_error_message
40
+ end
41
+
31
42
  private
32
43
 
33
44
  def no_hang?(flags)
@@ -21,7 +21,7 @@ module ChildProcess::Windows
21
21
 
22
22
  STARTF_USESTDHANDLES = 0x00000100
23
23
  INVALID_HANDLE_VALUE = 0xFFFFFFFF
24
-
24
+ HANDLE_FLAG_INHERIT = 0x00000001
25
25
 
26
26
  module Lib
27
27
  enum :wait_status, [ :wait_object_0, 0,
@@ -8,7 +8,7 @@ module ChildProcess
8
8
  flags = 0
9
9
  inherit = !!opts[:inherit]
10
10
 
11
- flags |= DETACHED_PROCESS if opts[:detach]
11
+ flags |= DETACHED_PROCESS if opts[:detach]
12
12
 
13
13
  si = StartupInfo.new
14
14
  pi = ProcessInfo.new
@@ -183,6 +183,14 @@ module ChildProcess
183
183
 
184
184
  attach_function :_get_osfhandle, :_get_osfhandle, [:int], :long
185
185
 
186
+ # BOOL WINAPI SetHandleInformation(
187
+ # __in HANDLE hObject,
188
+ # __in DWORD dwMask,
189
+ # __in DWORD dwFlags
190
+ # );
191
+
192
+ attach_function :set_handle_information, :SetHandleInformation, [:long, :ulong, :ulong], :bool
193
+
186
194
  end # Lib
187
195
  end # Windows
188
196
  end # ChildProcess
@@ -39,7 +39,7 @@ module ChildProcess
39
39
  def launch_process
40
40
  opts = {
41
41
  :inherit => false,
42
- :detach => @detach,
42
+ :detach => detach?,
43
43
  }
44
44
 
45
45
  if @io
data/lib/childprocess.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'childprocess/errors'
2
2
  require 'childprocess/abstract_process'
3
3
  require 'childprocess/abstract_io'
4
+ require "fcntl"
4
5
 
5
6
  module ChildProcess
6
7
  autoload :Unix, 'childprocess/unix'
@@ -67,6 +68,21 @@ module ChildProcess
67
68
  end
68
69
  )
69
70
  end
71
+
72
+ #
73
+ # By default, a child process will inherit open files and sockets from the parent process.
74
+ # This helper provides a cross-platform way of making sure that doesn't happen for the given file.
75
+ #
70
76
 
71
- end
72
- end
77
+ def close_on_exec(file)
78
+ if windows?
79
+ Windows.dont_inherit file
80
+ elsif file.respond_to?(:fcntl) && defined?(Fcntl::FD_CLOEXEC)
81
+ file.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC
82
+ else
83
+ raise Error, "not sure how to set close-on-exec for #{file.inspect} on #{platform}"
84
+ end
85
+ end
86
+
87
+ end # class << self
88
+ end # ChildProcess
@@ -96,4 +96,17 @@ describe ChildProcess do
96
96
  end
97
97
  end
98
98
 
99
+ it "can set close-on-exec when IO is inherited" do
100
+ server = TCPServer.new("localhost", 4433)
101
+ ChildProcess.close_on_exec server
102
+
103
+ process = sleeping_ruby
104
+ process.io.inherit!
105
+
106
+ process.start
107
+ server.close
108
+
109
+ lambda { TCPServer.new("localhost", 4433).close }.should_not raise_error
110
+ end
111
+
99
112
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
3
4
  require 'childprocess'
4
5
  require 'spec'
5
6
  require 'spec/autorun'
6
7
  require 'tempfile'
8
+ require "socket"
7
9
 
8
10
  module ChildProcessSpecHelper
9
11
  RUBY = defined?(Gem) ? Gem.ruby : 'ruby'
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 3
9
- version: 0.1.3
8
+ - 4
9
+ version: 0.1.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jari Bakken
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-17 00:00:00 +02:00
17
+ date: 2010-11-08 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency