[erlang-patches] [RFC PATCH] Ignore {error,eexist} in filelib:ensure_dir/1

Tuncer Ayaz tuncer.ayaz@REDACTED
Mon Jan 18 00:41:56 CET 2010


2010/1/17 Björn Gustavsson <bgustavsson@REDACTED>:
>
> I have fixed the indentation and included your patch in 'pu'.
>
>
> However, one problem with the patch is that
> if there already is a file with the same directory
> that you are trying to create, 'ok' will be returned.
>
> One way to fix the problem would be change
> to unconditionally attempt to create each directory.
> If creation fails with eexist, it should be tested
> whether there already is a directory. If yes,
> return 'ok', otherwise return {error,eexist}.

Redid the branch with a new commit which should
address this and also made sure indentation is correct.

git fetch git://github.com/tuncer/otp.git ensure_dir_eexist

-----8<-----
This is about the non-atomicity of filelib:ensure_dir/1.

When using filelib:ensure_dir/1 from multiple processes to create
the same path or parts of the same directory structure (which happens
with rebar's worker processes) it happens quite a lot that between
a file:read_file_info/1 and file:make_dir/1 one of the other procs
has already created the directory we want to create.

mkdir(1) says one of the following for -p depending on which Unix
like system you're on:
"no error if existing"
"no error will be reported if a directory given as an operand already
exists"

I've seen more than one Erlang project where the return value of
ensure_dir/1 is ignored completely.

I think {error,eexist} is safe to ignore and letting ensure_dir/1
ignore eexist will lead to people either removing their own eexist
ignoring wrappers or start caring about ensure_dir/1's return value
now that they can use 'ok = ensure_dir(Path)'.

Signed-off-by: Tuncer Ayaz <tuncer.ayaz@REDACTED>
---
 lib/stdlib/src/filelib.erl |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl
index d65588f..3acc40e 100644
--- a/lib/stdlib/src/filelib.erl
+++ b/lib/stdlib/src/filelib.erl
@@ -228,7 +228,17 @@ ensure_dir(F) ->
 	    ok;
 	false ->
 	    ensure_dir(Dir),
-	    file:make_dir(Dir)
+	    case file:make_dir(Dir) of
+		{error,eexist}=EExist ->
+		    case do_is_dir(Dir, file) of
+			true ->
+			    ok;
+			false ->
+			    EExist
+		    end;
+		Err ->
+		    Err
+	    end
     end.
----->8-----


More information about the erlang-patches mailing list