# Thread-safe FileUtils.cd

**URL:** <https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820>\
**Category:** Ruby\
**Created:** [September 20, 2009, 7:51pm UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820 "2009-09-20T19:51:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![james-calivar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@james-calivar](https://www.ruby-forum.com/u/james-calivar)\
**Post date:** [September 20, 2009, 7:51pm UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820/1 "2009-09-20T19:51:11Z")

</div>

Hi all,

I have a build tool that I’ve written in Ruby that uses this construct  
to  
enter a directory, perform some long-running (several seconds) tasks  
then  
exit back to the original working directory:

FileUtils.cd(dir) do

# expensive operations

end

Now I’m trying to write another tool that uses this build library to run  
several builds at once in different Threads. Problem is, the  
FileUtils.cd  
commands overlap and conflict with each other, causing the builds to  
fail. I  
have a lot of code already out in production that relies on this  
directory  
being set correctly (users can write hooks into the build system, and  
these  
hooks assume a certain working directory), so I can’t remove the cd()  
call.

My question is, is there a way of setting the working directory on a  
per-thread basis, or is it a global property of the Ruby process that  
cannot  
be made thread-safe?

Cheers,  
James

---

<div class="post-metadata">

**Author:** ![james-calivar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@james-calivar](https://www.ruby-forum.com/u/james-calivar)\
**Post date:** [September 20, 2009, 7:58pm UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820/2 "2009-09-20T19:58:12Z")

</div>

The current working process is a global property of the underlaying  
system process.

A system Process has one currency working directory, not two, or more.

You can do your directory / filename calculations, using the absolute  
directory path, without any race conditions.

–

Markus

---

<div class="post-metadata">

**Author:** ![james-calivar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@james-calivar](https://www.ruby-forum.com/u/james-calivar)\
**Post date:** [September 20, 2009, 8:04pm UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820/3 "2009-09-20T20:04:04Z")

</div>

2009/9/20 Markus S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> The current working process is a global property of the underlaying system  
> process.
> 
> A system Process has one currency working directory, not two, or more.
> 
> You can do your directory / filename calculations, using the absolute  
> directory path, without any race conditions.

Yes, I realise now I should have forced users to use absolute paths, but  
as  
it stands there’s code out in the wild with stuff like:

hook :after\_build do |build|  
FileUtils.cp ‘README’, File.join(build.build\_dir, ‘README’)  
end

So the working directory needs to be set so that ‘README’ can be found  
correctly. Internally the tool uses absolute paths, so e.g.  
`build.build_dir` is an absolute path, but code written by users is  
likely  
to use relative paths.

---

<div class="post-metadata">

**Author:** ![james-calivar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@james-calivar](https://www.ruby-forum.com/u/james-calivar)\
**Post date:** [September 20, 2009, 8:12pm UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820/4 "2009-09-20T20:12:50Z")

</div>

Forcing the users to use absolute paths may just hides the problem.  
Maybe you should expand the users “relative” paths before using them.

Or monkeypatch FileUtils, and maybe dozens ruby core classes to support  
a “thread-safe” cwd.

---

<div class="post-metadata">

**Author:** ![james-calivar](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@james-calivar](https://www.ruby-forum.com/u/james-calivar)\
**Post date:** [September 22, 2009, 10:42am UTC](https://www.ruby-forum.com/t/thread-safe-fileutils-cd/175820/5 "2009-09-22T10:42:05Z")

</div>

2009/9/20 Markus S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Forcing the users to use absolute paths may just hides the problem. Maybe  
> you should expand the users “relative” paths before using them.
> 
> Or monkeypatch FileUtils, and maybe dozens ruby core classes to support a  
> “thread-safe” cwd.

That would be an option but IMHO it would be tedious and error prone.  
You can easily miss a class and introduce unwanted effects.

As far as I can see the only way to make cwd thread safe would be to  
use the block form and synchronize access, i.e. one thread changes  
cwd, does its work and returns cwd to the old status. For obvious  
reasons this is not really a good idea. IMHO the only reasonable way  
to go is to

a) use cwd only in single threaded programs or with explicit  
synchronization guards  
b) do not change cwd and use absolute path names, even if that means  
converting user input / method arguments

Kind regards

robert
