childprocess 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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