Skip to content

Commit

Permalink
Merge pull request #421 from CocoaPods/dani_fix_chdir
Browse files Browse the repository at this point in the history
Make chdir chdir again
  • Loading branch information
endocrimes authored Sep 26, 2016
2 parents c8b7277 + 1b48366 commit 4020ac9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 32 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

##### Bug Fixes

* None.
* Cover more cases of the Dir.chdir breakages.
[Danielle Tomlinson](https://github.com/dantoml)
[#421](https://github.com/CocoaPods/Xcodeproj/pull/421)


## 1.3.1 (2016-09-10)
Expand Down
36 changes: 5 additions & 31 deletions lib/xcodeproj/plist/ffi.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,6 @@

module Xcodeproj
module Plist
module Extensions
# Since Xcode 8 beta 4, calling `PBXProject.projectWithFile` breaks subsequent calls to
# `chdir`. While sounding ridiculous, this is unfortunately true and debugging it from the
# userland side showed no difference at all to successful calls to `chdir`, but the working
# directory is simply not changed in the end. This workaround is even more absurd, monkey
# patching all calls to `chdir` to use `__pthread_chdir` which appears to work.
module Dir
def self.chdir(path)
old_dir = Dir.getwd
res = actually_chdir(path)

if block_given?
begin
return yield
ensure
actually_chdir(old_dir)
end
end

res
end

def self.actually_chdir(path)
libc = Fiddle.dlopen '/usr/lib/libc.dylib'
f = Fiddle::Function.new(libc['__pthread_chdir'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
f.call(path.to_s)
end
end
end

# Provides support for loading and serializing property list files via
# Fiddle and CoreFoundation / Xcode.
#
Expand Down Expand Up @@ -171,7 +142,10 @@ def ruby_hash_write_devtoolscore(hash, path)
end

def monkey_patch_chdir
Dir.send(:include, Extensions::Dir)
require 'xcodeproj/plist/ffi/chdir_override'
class << Dir
alias_method :chdir, :cp_chdir
end
end
end
end
Expand Down
27 changes: 27 additions & 0 deletions lib/xcodeproj/plist/ffi/chdir_override.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Since Xcode 8 beta 4, calling `PBXProject.projectWithFile` breaks subsequent calls to
# `chdir`. While sounding ridiculous, this is unfortunately true and debugging it from the
# userland side showed no difference at all to successful calls to `chdir`, but the working
# directory is simply not changed in the end. This workaround is even more absurd, monkey
# patching all calls to `chdir` to use `__pthread_chdir` which appears to work.
class Dir
def self.cp_chdir(path)
old_dir = Dir.getwd
res = cp_actually_chdir(path)

if block_given?
begin
return yield
ensure
cp_actually_chdir(old_dir)
end
end

res
end

def self.cp_actually_chdir(path)
libc = Fiddle.dlopen '/usr/lib/libc.dylib'
f = Fiddle::Function.new(libc['__pthread_chdir'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
f.call(path.to_s)
end
end
9 changes: 9 additions & 0 deletions spec/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ module ProjectSpecs
@project = Xcodeproj::Project.open(@path)
end

it 'does not break the chdir system call' do
require 'pathname'
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
Pathname(dir).realpath.to_s.should == Dir.getwd
end
end
end

it 'sets itself as the owner of the root object' do
# The root object might be referenced by other objects like
# the PBXContainerItemProxy
Expand Down

0 comments on commit 4020ac9

Please sign in to comment.