childprocess 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,6 +19,11 @@ module ChildProcess
19
19
  #
20
20
  attr_reader :environment
21
21
 
22
+ #
23
+ # Set the child's current working directory.
24
+ #
25
+ attr_accessor :cwd
26
+
22
27
  #
23
28
  # Create a new process with the given args.
24
29
  #
@@ -66,7 +66,7 @@ module ChildProcess
66
66
  def launch_process(&blk)
67
67
  pb = java.lang.ProcessBuilder.new(@args)
68
68
 
69
- pb.directory java.io.File.new(Dir.pwd)
69
+ pb.directory java.io.File.new(@cwd || Dir.pwd)
70
70
  set_env pb.environment
71
71
 
72
72
  begin
@@ -18,6 +18,10 @@ module ChildProcess
18
18
  end
19
19
 
20
20
  @pid = fork {
21
+ if @cwd
22
+ Dir.chdir(@cwd)
23
+ end
24
+
21
25
  exec_r.close
22
26
  set_env
23
27
 
@@ -1,10 +1,13 @@
1
1
  require 'ffi'
2
+ require 'thread'
2
3
 
3
4
  module ChildProcess
4
5
  module Unix
5
6
  class PosixSpawnProcess < Process
6
7
  private
7
8
 
9
+ @@cwd_lock = Mutex.new
10
+
8
11
  def launch_process
9
12
  pid_ptr = FFI::MemoryPointer.new(:pid_t)
10
13
  actions = Lib::FileActions.new
@@ -41,21 +44,26 @@ module ChildProcess
41
44
  argv = Argv.new(@args)
42
45
  envp = Envp.new(ENV.to_hash.merge(@environment))
43
46
 
44
- if ChildProcess.jruby?
45
- # on JRuby, the current working directory is for some reason not inherited.
46
- # We'll work around it by making a chdir call through FFI.
47
- # TODO: report this to JRuby
48
- Lib.chdir Dir.pwd
49
- end
47
+ ret = 0
48
+ @@cwd_lock.synchronize do
49
+ Dir.chdir(@cwd || Dir.pwd) do
50
+ if ChildProcess.jruby?
51
+ # on JRuby, the current working directory is for some reason not inherited.
52
+ # We'll work around it by making a chdir call through FFI.
53
+ # TODO: report this to JRuby
54
+ Lib.chdir Dir.pwd
55
+ end
50
56
 
51
- ret = Lib.posix_spawnp(
52
- pid_ptr,
53
- @args.first, # TODO: not sure this matches exec() behaviour
54
- actions,
55
- attrs,
56
- argv,
57
- envp
58
- )
57
+ ret = Lib.posix_spawnp(
58
+ pid_ptr,
59
+ @args.first, # TODO: not sure this matches exec() behaviour
60
+ actions,
61
+ attrs,
62
+ argv,
63
+ envp
64
+ )
65
+ end
66
+ end
59
67
 
60
68
  if duplex?
61
69
  io._stdin = writer
@@ -1,3 +1,3 @@
1
1
  module ChildProcess
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
@@ -53,6 +53,7 @@ module ChildProcess
53
53
  builder.detach = detach?
54
54
  builder.duplex = duplex?
55
55
  builder.environment = @environment unless @environment.empty?
56
+ builder.cwd = @cwd
56
57
 
57
58
  if @io
58
59
  builder.stdout = @io.stdout
@@ -1,7 +1,7 @@
1
1
  module ChildProcess
2
2
  module Windows
3
3
  class ProcessBuilder
4
- attr_accessor :inherit, :detach, :duplex, :environment, :stdout, :stderr
4
+ attr_accessor :inherit, :detach, :duplex, :environment, :stdout, :stderr, :cwd
5
5
  attr_reader :stdin
6
6
 
7
7
  def initialize(args)
@@ -11,6 +11,7 @@ module ChildProcess
11
11
  @detach = false
12
12
  @duplex = false
13
13
  @environment = nil
14
+ @cwd = nil
14
15
 
15
16
  @stdout = nil
16
17
  @stderr = nil
@@ -19,11 +20,13 @@ module ChildProcess
19
20
  @flags = 0
20
21
  @cmd_ptr = nil
21
22
  @env_ptr = nil
23
+ @cwd_ptr = nil
22
24
  end
23
25
 
24
26
  def start
25
27
  create_command_pointer
26
28
  create_environment_pointer
29
+ create_cwd_pointer
27
30
 
28
31
  setup_detach
29
32
  setup_io
@@ -63,6 +66,10 @@ module ChildProcess
63
66
  @env_ptr.put_bytes 0, env_str, 0, env_str.bytesize
64
67
  end
65
68
 
69
+ def create_cwd_pointer
70
+ @cwd_ptr = FFI::MemoryPointer.from_string(@cwd || Dir.pwd)
71
+ end
72
+
66
73
  def create_process
67
74
  ok = Lib.create_process(
68
75
  nil, # application name
@@ -72,7 +79,7 @@ module ChildProcess
72
79
  @inherit, # inherit handles
73
80
  @flags, # creation flags
74
81
  @env_ptr, # environment
75
- cwd, # current directory
82
+ @cwd_ptr, # current directory
76
83
  startup_info, # startup info
77
84
  process_info # process info
78
85
  )
@@ -94,10 +101,6 @@ module ChildProcess
94
101
  @flags |= DETACHED_PROCESS if @detach
95
102
  end
96
103
 
97
- def cwd
98
- @cwd ||= FFI::MemoryPointer.from_string(Dir.pwd)
99
- end
100
-
101
104
  def setup_io
102
105
  if @stdout || @stderr
103
106
  startup_info[:dwFlags] ||= 0
@@ -173,4 +176,4 @@ module ChildProcess
173
176
  end
174
177
  end # ProcessBuilder
175
178
  end # Windows
176
- end # ChildProcess
179
+ end # ChildProcess
@@ -168,4 +168,25 @@ describe ChildProcess do
168
168
  lambda { process.poll_for_exit(0.1) }.should raise_error(ChildProcess::TimeoutError)
169
169
  end
170
170
 
171
+ it "can change working directory" do
172
+ process = ruby "print Dir.pwd"
173
+
174
+ with_tmpdir { |dir|
175
+ process.cwd = dir
176
+
177
+ orig_pwd = Dir.pwd
178
+
179
+ Tempfile.open('cwd') do |file|
180
+ process.io.stdout = file
181
+
182
+ process.start
183
+ process.wait
184
+
185
+ file.rewind
186
+ file.read.should == dir
187
+ end
188
+
189
+ Dir.pwd.should == orig_pwd
190
+ }
191
+ end
171
192
  end
@@ -123,6 +123,17 @@ module ChildProcessSpecHelper
123
123
  port
124
124
  end
125
125
 
126
+ def with_tmpdir(&blk)
127
+ name = "#{Time.now.strftime("%Y%m%d")}-#{$$}-#{rand(0x100000000).to_s(36)}"
128
+ FileUtils.mkdir_p(name)
129
+
130
+ begin
131
+ yield File.expand_path(name)
132
+ ensure
133
+ FileUtils.rm_rf name
134
+ end
135
+ end
136
+
126
137
  def wait_until(timeout = 10, &blk)
127
138
  end_time = Time.now + timeout
128
139
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: childprocess
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-20 00:00:00.000000000 Z
12
+ date: 2012-06-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
147
  version: '0'
148
148
  requirements: []
149
149
  rubyforge_project: childprocess
150
- rubygems_version: 1.8.21
150
+ rubygems_version: 1.8.24
151
151
  signing_key:
152
152
  specification_version: 3
153
153
  summary: This gem aims at being a simple and reliable solution for controlling external