diff options
Diffstat (limited to '1.1.x/src/mochiweb/mochitemp.erl')
-rw-r--r-- | 1.1.x/src/mochiweb/mochitemp.erl | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/1.1.x/src/mochiweb/mochitemp.erl b/1.1.x/src/mochiweb/mochitemp.erl deleted file mode 100644 index bb23d2a6..00000000 --- a/1.1.x/src/mochiweb/mochitemp.erl +++ /dev/null @@ -1,310 +0,0 @@ -%% @author Bob Ippolito <bob@mochimedia.com> -%% @copyright 2010 Mochi Media, Inc. - -%% @doc Create temporary files and directories. Requires crypto to be started. - --module(mochitemp). --export([gettempdir/0]). --export([mkdtemp/0, mkdtemp/3]). --export([rmtempdir/1]). -%% -export([mkstemp/4]). --define(SAFE_CHARS, {$a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, - $n, $o, $p, $q, $r, $s, $t, $u, $v, $w, $x, $y, $z, - $A, $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, - $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z, - $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $_}). --define(TMP_MAX, 10000). - --include_lib("kernel/include/file.hrl"). - -%% TODO: An ugly wrapper over the mktemp tool with open_port and sadness? -%% We can't implement this race-free in Erlang without the ability -%% to issue O_CREAT|O_EXCL. I suppose we could hack something with -%% mkdtemp, del_dir, open. -%% mkstemp(Suffix, Prefix, Dir, Options) -> -%% ok. - -rmtempdir(Dir) -> - case file:del_dir(Dir) of - {error, eexist} -> - ok = rmtempdirfiles(Dir), - ok = file:del_dir(Dir); - ok -> - ok - end. - -rmtempdirfiles(Dir) -> - {ok, Files} = file:list_dir(Dir), - ok = rmtempdirfiles(Dir, Files). - -rmtempdirfiles(_Dir, []) -> - ok; -rmtempdirfiles(Dir, [Basename | Rest]) -> - Path = filename:join([Dir, Basename]), - case filelib:is_dir(Path) of - true -> - ok = rmtempdir(Path); - false -> - ok = file:delete(Path) - end, - rmtempdirfiles(Dir, Rest). - -mkdtemp() -> - mkdtemp("", "tmp", gettempdir()). - -mkdtemp(Suffix, Prefix, Dir) -> - mkdtemp_n(rngpath_fun(Suffix, Prefix, Dir), ?TMP_MAX). - - - -mkdtemp_n(RngPath, 1) -> - make_dir(RngPath()); -mkdtemp_n(RngPath, N) -> - try make_dir(RngPath()) - 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 -%% --include_lib("eunit/include/eunit.hrl"). --ifdef(TEST). -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 - %% the first time and succeeds the second. - F = fun () -> - case filelib:is_dir(Path) of - true -> - file:del_dir(Path); - false -> - file:make_dir(Path) - end, - Path - end, - try - %% Fails the first time - ?assertThrow( - {error, eexist}, - mkdtemp_n(F, 1)), - %% Reset state - file:del_dir(Path), - %% Succeeds the second time - ?assertEqual( - Path, - mkdtemp_n(F, 2)) - after rmtempdir(D) - end, - ok. - -mkdtemp_n_fail_test() -> - {ok, Cwd} = file:get_cwd(), - ?assertThrow( - {error, eexist}, - mkdtemp_n(fun () -> Cwd end, 1)), - ?assertThrow( - {error, eexist}, - mkdtemp_n(fun () -> Cwd end, 2)), - ok. - -make_dir_fail_test() -> - {ok, Cwd} = file:get_cwd(), - ?assertThrow( - {error, eexist}, - make_dir(Cwd)), - ok. - -mkdtemp_test() -> - crypto:start(), - D = mkdtemp(), - ?assertEqual( - true, - filelib:is_dir(D)), - ?assertEqual( - ok, - file:del_dir(D)), - ok. - -rmtempdir_test() -> - crypto:start(), - D1 = mkdtemp(), - ?assertEqual( - true, - filelib:is_dir(D1)), - ?assertEqual( - ok, - rmtempdir(D1)), - D2 = mkdtemp(), - ?assertEqual( - true, - filelib:is_dir(D2)), - ok = file:write_file(filename:join([D2, "foo"]), <<"bytes">>), - D3 = mkdtemp("suffix", "prefix", D2), - ?assertEqual( - true, - filelib:is_dir(D3)), - ok = file:write_file(filename:join([D3, "foo"]), <<"bytes">>), - ?assertEqual( - ok, - rmtempdir(D2)), - ?assertEqual( - {error, enoent}, - file:consult(D3)), - ?assertEqual( - {error, enoent}, - file:consult(D2)), - ok. - -gettempdir_env_test() -> - Env = pushenv(["TMPDIR", "TEMP", "TMP"]), - FalseEnv = [{"TMPDIR", false}, {"TEMP", false}, {"TMP", false}], - try - popenv(FalseEnv), - popenv([{"TMPDIR", "/"}]), - ?assertEqual( - "/", - os:getenv("TMPDIR")), - ?assertEqual( - "/", - gettempdir()), - {ok, Cwd} = file:get_cwd(), - popenv(FalseEnv), - popenv([{"TMP", Cwd}]), - ?assertEqual( - normalize_dir(Cwd), - gettempdir()) - after popenv(Env) - end, - ok. - --endif. |