Erlang-Parser
view release on metacpan or search on metacpan
catch throw:{error, eexist} ->
mkdtemp_n(RngPath, N - 1)
end.
make_dir(Path) ->
case file:make_dir(Path) of
ok ->
ok;
E={error, eexist} ->
throw(E)
end,
%% Small window for a race condition here because dir is created 777
ok = file:write_file_info(Path, #file_info{mode=8#0700}),
Path.
rngpath_fun(Prefix, Suffix, Dir) ->
fun () ->
filename:join([Dir, Prefix ++ rngchars(6) ++ Suffix])
end.
rngchars(0) ->
"";
rngchars(N) ->
[rngchar() | rngchars(N - 1)].
rngchar() ->
rngchar(crypto:rand_uniform(0, tuple_size(?SAFE_CHARS))).
rngchar(C) ->
element(1 + C, ?SAFE_CHARS).
%% @spec gettempdir() -> string()
%% @doc Get a usable temporary directory using the first of these that is a directory:
%% $TMPDIR, $TMP, $TEMP, "/tmp", "/var/tmp", "/usr/tmp", ".".
gettempdir() ->
gettempdir(gettempdir_checks(), fun normalize_dir/1).
gettempdir_checks() ->
[{fun os:getenv/1, ["TMPDIR", "TMP", "TEMP"]},
{fun gettempdir_identity/1, ["/tmp", "/var/tmp", "/usr/tmp"]},
{fun gettempdir_cwd/1, [cwd]}].
gettempdir_identity(L) ->
L.
gettempdir_cwd(cwd) ->
{ok, L} = file:get_cwd(),
L.
gettempdir([{_F, []} | RestF], Normalize) ->
gettempdir(RestF, Normalize);
gettempdir([{F, [L | RestL]} | RestF], Normalize) ->
case Normalize(F(L)) of
false ->
gettempdir([{F, RestL} | RestF], Normalize);
Dir ->
Dir
end.
normalize_dir(False) when False =:= false orelse False =:= "" ->
%% Erlang doesn't have an unsetenv, wtf.
false;
normalize_dir(L) ->
Dir = filename:absname(L),
case filelib:is_dir(Dir) of
false ->
false;
true ->
Dir
end.
%%
%% Tests
%%
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
pushenv(L) ->
[{K, os:getenv(K)} || K <- L].
popenv(L) ->
F = fun ({K, false}) ->
%% Erlang doesn't have an unsetenv, wtf.
os:putenv(K, "");
({K, V}) ->
os:putenv(K, V)
end,
lists:foreach(F, L).
gettempdir_fallback_test() ->
?assertEqual(
"/",
gettempdir([{fun gettempdir_identity/1, ["/--not-here--/"]},
{fun gettempdir_identity/1, ["/"]}],
fun normalize_dir/1)),
?assertEqual(
"/",
%% simulate a true os:getenv unset env
gettempdir([{fun gettempdir_identity/1, [false]},
{fun gettempdir_identity/1, ["/"]}],
fun normalize_dir/1)),
ok.
gettempdir_identity_test() ->
?assertEqual(
"/",
gettempdir([{fun gettempdir_identity/1, ["/"]}], fun normalize_dir/1)),
ok.
gettempdir_cwd_test() ->
{ok, Cwd} = file:get_cwd(),
?assertEqual(
normalize_dir(Cwd),
gettempdir([{fun gettempdir_cwd/1, [cwd]}], fun normalize_dir/1)),
ok.
rngchars_test() ->
crypto:start(),
?assertEqual(
"",
rngchars(0)),
?assertEqual(
10,
length(rngchars(10))),
ok.
rngchar_test() ->
?assertEqual(
$a,
rngchar(0)),
?assertEqual(
$A,
rngchar(26)),
?assertEqual(
$_,
rngchar(62)),
ok.
mkdtemp_n_failonce_test() ->
crypto:start(),
D = mkdtemp(),
Path = filename:join([D, "testdir"]),
%% Toggle the existence of a dir so that it fails
( run in 0.842 second using v1.01-cache-2.11-cpan-39bf76dae61 )