summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2011-09-21 13:44:41 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2011-09-21 13:44:41 +0100
commit603625e1d63f38e15669f20a52a5c57e9723cd23 (patch)
tree5febe7daa317629dff6eab351e4c130a820a9277
parent496b4284d232a3c45136a5a1deac5b56780b953c (diff)
downloadrabbitmq-server-603625e1d63f38e15669f20a52a5c57e9723cd23.tar.gz
move file functions from misc to rabbit_file
-rw-r--r--src/rabbit_error_logger_file_h.erl6
-rw-r--r--src/rabbit_file.erl293
-rw-r--r--src/rabbit_guid.erl4
-rw-r--r--src/rabbit_misc.erl255
-rw-r--r--src/rabbit_mnesia.erl12
-rw-r--r--src/rabbit_msg_store.erl8
-rw-r--r--src/rabbit_prelaunch.erl4
-rw-r--r--src/rabbit_queue_index.erl35
-rw-r--r--src/rabbit_sasl_report_file_h.erl6
-rw-r--r--src/rabbit_tests.erl2
-rw-r--r--src/rabbit_upgrade.erl4
-rw-r--r--src/rabbit_version.erl4
12 files changed, 335 insertions, 298 deletions
diff --git a/src/rabbit_error_logger_file_h.erl b/src/rabbit_error_logger_file_h.erl
index 7e9ebc4f..7c3b95a1 100644
--- a/src/rabbit_error_logger_file_h.erl
+++ b/src/rabbit_error_logger_file_h.erl
@@ -29,7 +29,7 @@
%% Used only when swapping handlers in log rotation
init({{File, Suffix}, []}) ->
- case rabbit_misc:append_file(File, Suffix) of
+ case rabbit_file:append_file(File, Suffix) of
ok -> ok;
{error, Error} ->
rabbit_log:error("Failed to append contents of "
@@ -46,10 +46,10 @@ init({{File, _}, error}) ->
init({File, []}) ->
init(File);
init({File, _Type} = FileInfo) ->
- rabbit_misc:ensure_parent_dirs_exist(File),
+ rabbit_file:ensure_parent_dirs_exist(File),
error_logger_file_h:init(FileInfo);
init(File) ->
- rabbit_misc:ensure_parent_dirs_exist(File),
+ rabbit_file:ensure_parent_dirs_exist(File),
error_logger_file_h:init(File).
handle_event(Event, State) ->
diff --git a/src/rabbit_file.erl b/src/rabbit_file.erl
new file mode 100644
index 00000000..b5a3f68a
--- /dev/null
+++ b/src/rabbit_file.erl
@@ -0,0 +1,293 @@
+%% The contents of this file are subject to the Mozilla Public License
+%% Version 1.1 (the "License"); you may not use this file except in
+%% compliance with the License. You may obtain a copy of the License
+%% at http://www.mozilla.org/MPL/
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and
+%% limitations under the License.
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developer of the Original Code is VMware, Inc.
+%% Copyright (c) 2011 VMware, Inc. All rights reserved.
+%%
+
+-module(rabbit_file).
+
+-include_lib("kernel/include/file.hrl").
+
+-export([is_file/1, is_dir/1, file_size/1, ensure_dir/1, wildcard/2, list_dir/1]).
+-export([read_term_file/1, write_term_file/2, write_file/2, write_file/3]).
+-export([append_file/2, ensure_parent_dirs_exist/1]).
+-export([rename/2, delete/1, recursive_delete/1, recursive_copy/2]).
+-export([lock_file/1]).
+
+%%----------------------------------------------------------------------------
+
+-ifdef(use_specs).
+
+-type(ok_or_error() :: rabbit_types:ok_or_error(any())).
+
+-spec(is_file/1 :: ((file:filename())) -> boolean()).
+-spec(is_dir/1 :: ((file:filename())) -> boolean()).
+-spec(file_size/1 :: ((file:filename())) -> non_neg_integer()).
+-spec(ensure_dir/1 :: ((file:filename())) -> ok_or_error()).
+-spec(wildcard/2 :: (string(), file:filename()) -> [file:filename()]).
+-spec(list_dir/1 :: (file:filename()) -> [file:filename()]).
+-spec(read_term_file/1 ::
+ (file:filename()) -> {'ok', [any()]} | rabbit_types:error(any())).
+-spec(write_term_file/2 :: (file:filename(), [any()]) -> ok_or_error()).
+-spec(write_file/2 :: (file:filename(), iodata()) -> ok_or_error()).
+-spec(write_file/3 :: (file:filename(), iodata(), [any()]) -> ok_or_error()).
+-spec(append_file/2 :: (file:filename(), string()) -> ok_or_error()).
+-spec(ensure_parent_dirs_exist/1 :: (string()) -> 'ok').
+-spec(rename/2 ::
+ (file:filename(), file:filename()) -> ok_or_error()).
+-spec(delete/1 :: ([file:filename()]) -> ok_or_error()).
+-spec(recursive_delete/1 ::
+ ([file:filename()])
+ -> rabbit_types:ok_or_error({file:filename(), any()})).
+-spec(recursive_copy/2 ::
+ (file:filename(), file:filename())
+ -> rabbit_types:ok_or_error({file:filename(), file:filename(), any()})).
+-spec(lock_file/1 :: (file:filename()) -> rabbit_types:ok_or_error('eexist')).
+
+-endif.
+
+%%----------------------------------------------------------------------------
+
+is_file(File) ->
+ case read_file_info(File) of
+ {ok, #file_info{type=regular}} -> true;
+ {ok, #file_info{type=directory}} -> true;
+ _ -> false
+ end.
+
+is_dir(Dir) -> is_dir_internal(read_file_info(Dir)).
+is_dir_no_handle(Dir) -> is_dir_internal(prim_file:read_file_info(Dir)).
+
+is_dir_internal({ok, #file_info{type=directory}}) -> true;
+is_dir_internal(_) -> false.
+
+file_size(File) ->
+ case read_file_info(File) of
+ {ok, #file_info{size=Size}} -> Size;
+ _ -> 0
+ end.
+
+ensure_dir(File) -> with_fhc_handle(fun () -> ensure_dir_internal(File) end).
+
+ensure_dir_internal("/") ->
+ ok;
+ensure_dir_internal(File) ->
+ Dir = filename:dirname(File),
+ case is_dir_no_handle(Dir) of
+ true -> ok;
+ false -> ensure_dir_internal(Dir),
+ prim_file:make_dir(Dir)
+ end.
+
+wildcard(Pattern, Dir) ->
+ {ok, Files} = list_dir(Dir),
+ {ok, RE} = re:compile(Pattern, [anchored]),
+ [File || File <- Files, match =:= re:run(File, RE, [{capture, none}])].
+
+list_dir(Dir) ->
+ with_fhc_handle(fun () -> prim_file:list_dir(Dir) end).
+
+read_file_info(File) ->
+ with_fhc_handle(fun () -> prim_file:read_file_info(File) end).
+
+with_fhc_handle(Fun) ->
+ ok = file_handle_cache:obtain(),
+ try Fun()
+ after ok = file_handle_cache:release()
+ end.
+
+read_term_file(File) ->
+ try
+ {ok, Data} = with_fhc_handle(fun () -> prim_file:read_file(File) end),
+ {ok, Tokens, _} = erl_scan:string(binary:bin_to_list(Data)),
+ TokenGroups = group_tokens(Tokens),
+ {ok, [begin
+ {ok, Term} = erl_parse:parse_term(Tokens1),
+ Term
+ end || Tokens1 <- TokenGroups]}
+ catch
+ error:{badmatch, Error} -> Error
+ end.
+
+group_tokens([]) ->
+ [];
+group_tokens([{_, N, _} | _] = Tokens) ->
+ lists:reverse(group_tokens([], N, Tokens));
+group_tokens([{_, N} | _] = Tokens) ->
+ lists:reverse(group_tokens([], N, Tokens)).
+
+group_tokens(Cur, _, []) ->
+ [lists:reverse(Cur)];
+group_tokens(Cur, N, [Tok = {_, N} | Toks]) ->
+ group_tokens([Tok | Cur], N, Toks);
+group_tokens(Cur, _, [{_, M} | _] = Toks) ->
+ [lists:reverse(Cur) | group_tokens([], M, Toks)];
+group_tokens(Cur, N, [Tok = {_, N, _} | Toks]) ->
+ group_tokens([Tok | Cur], N, Toks);
+group_tokens(Cur, _, [{_, M, _} | _] = Toks) ->
+ [lists:reverse(Cur) | group_tokens([], M, Toks)].
+
+write_term_file(File, Terms) ->
+ write_file(File, list_to_binary([io_lib:format("~w.~n", [Term]) ||
+ Term <- Terms])).
+
+write_file(Path, Data) ->
+ write_file(Path, Data, []).
+
+%% write_file/3 and make_binary/1 are both based on corresponding
+%% functions in the kernel/file.erl module of the Erlang R14B02
+%% release, which is licensed under the EPL. That implementation of
+%% write_file/3 does not do an fsync prior to closing the file, hence
+%% the existence of this version. APIs are otherwise identical.
+write_file(Path, Data, Modes) ->
+ Modes1 = [binary, write | (Modes -- [binary, write])],
+ case make_binary(Data) of
+ Bin when is_binary(Bin) ->
+ with_fhc_handle(
+ fun () -> case prim_file:open(Path, Modes1) of
+ {ok, Hdl} -> try prim_file:write(Hdl, Bin) of
+ ok -> prim_file:sync(Hdl);
+ {error, _} = E -> E
+ after
+ prim_file:close(Hdl)
+ end;
+ {error, _} = E -> E
+ end
+ end);
+ {error, _} = E -> E
+ end.
+
+make_binary(Bin) when is_binary(Bin) ->
+ Bin;
+make_binary(List) ->
+ try
+ iolist_to_binary(List)
+ catch error:Reason ->
+ {error, Reason}
+ end.
+
+
+append_file(File, Suffix) ->
+ case read_file_info(File) of
+ {ok, FInfo} -> append_file(File, FInfo#file_info.size, Suffix);
+ {error, enoent} -> append_file(File, 0, Suffix);
+ Error -> Error
+ end.
+
+append_file(_, _, "") ->
+ ok;
+append_file(File, 0, Suffix) ->
+ with_fhc_handle(fun () ->
+ case prim_file:open([File, Suffix], [append]) of
+ {ok, Fd} -> prim_file:close(Fd);
+ Error -> Error
+ end
+ end);
+append_file(File, _, Suffix) ->
+ case with_fhc_handle(fun () -> prim_file:read_file(File) end) of
+ {ok, Data} -> write_file([File, Suffix], Data, [append]);
+ Error -> Error
+ end.
+
+ensure_parent_dirs_exist(Filename) ->
+ case ensure_dir(Filename) of
+ ok -> ok;
+ {error, Reason} ->
+ throw({error, {cannot_create_parent_dirs, Filename, Reason}})
+ end.
+
+rename(Old, New) -> with_fhc_handle(fun () -> prim_file:rename(Old, New) end).
+
+delete(File) -> with_fhc_handle(fun () -> prim_file:delete(File) end).
+
+recursive_delete(Files) ->
+ with_fhc_handle(
+ fun () -> lists:foldl(fun (Path, ok) -> recursive_delete1(Path);
+ (_Path, {error, _Err} = Error) -> Error
+ end, ok, Files)
+ end).
+
+recursive_delete1(Path) ->
+ case is_dir_no_handle(Path) and not(is_symlink_no_handle(Path)) of
+ false -> case prim_file:delete(Path) of
+ ok -> ok;
+ {error, enoent} -> ok; %% Path doesn't exist anyway
+ {error, Err} -> {error, {Path, Err}}
+ end;
+ true -> case prim_file:list_dir(Path) of
+ {ok, FileNames} ->
+ case lists:foldl(
+ fun (FileName, ok) ->
+ recursive_delete1(
+ filename:join(Path, FileName));
+ (_FileName, Error) ->
+ Error
+ end, ok, FileNames) of
+ ok ->
+ case prim_file:del_dir(Path) of
+ ok -> ok;
+ {error, Err} -> {error, {Path, Err}}
+ end;
+ {error, _Err} = Error ->
+ Error
+ end;
+ {error, Err} ->
+ {error, {Path, Err}}
+ end
+ end.
+
+is_symlink_no_handle(File) ->
+ case prim_file:read_link(File) of
+ {ok, _} -> true;
+ _ -> false
+ end.
+
+recursive_copy(Src, Dest) ->
+ %% Note that this uses the 'file' module and, hence, shouldn't be
+ %% run on many processes at once.
+ case is_dir(Src) of
+ false -> case file:copy(Src, Dest) of
+ {ok, _Bytes} -> ok;
+ {error, enoent} -> ok; %% Path doesn't exist anyway
+ {error, Err} -> {error, {Src, Dest, Err}}
+ end;
+ true -> case file:list_dir(Src) of
+ {ok, FileNames} ->
+ case file:make_dir(Dest) of
+ ok ->
+ lists:foldl(
+ fun (FileName, ok) ->
+ recursive_copy(
+ filename:join(Src, FileName),
+ filename:join(Dest, FileName));
+ (_FileName, Error) ->
+ Error
+ end, ok, FileNames);
+ {error, Err} ->
+ {error, {Src, Dest, Err}}
+ end;
+ {error, Err} ->
+ {error, {Src, Dest, Err}}
+ end
+ end.
+
+%% TODO: When we stop supporting Erlang prior to R14, this should be
+%% replaced with file:open [write, exclusive]
+lock_file(Path) ->
+ case is_file(Path) of
+ true -> {error, eexist};
+ false -> with_fhc_handle(
+ fun () -> {ok, Lock} = prim_file:open(Path, [write]),
+ ok = prim_file:close(Lock)
+ end)
+ end.
diff --git a/src/rabbit_guid.erl b/src/rabbit_guid.erl
index 234bc55b..cf3fea1a 100644
--- a/src/rabbit_guid.erl
+++ b/src/rabbit_guid.erl
@@ -52,13 +52,13 @@ start_link() ->
update_disk_serial() ->
Filename = filename:join(rabbit_mnesia:dir(), ?SERIAL_FILENAME),
- Serial = case rabbit_misc:read_term_file(Filename) of
+ Serial = case rabbit_file:read_term_file(Filename) of
{ok, [Num]} -> Num;
{error, enoent} -> 0;
{error, Reason} ->
throw({error, {cannot_read_serial_file, Filename, Reason}})
end,
- case rabbit_misc:write_term_file(Filename, [Serial + 1]) of
+ case rabbit_file:write_term_file(Filename, [Serial + 1]) of
ok -> ok;
{error, Reason1} ->
throw({error, {cannot_write_serial_file, Filename, Reason1}})
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index cd28bd54..d47041d6 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -18,8 +18,6 @@
-include("rabbit.hrl").
-include("rabbit_framing.hrl").
--include_lib("kernel/include/file.hrl").
-
-export([method_record_type/1, polite_pause/0, polite_pause/1]).
-export([die/1, frame_error/2, amqp_error/4,
protocol_error/3, protocol_error/4, protocol_error/1]).
@@ -40,28 +38,22 @@
-export([upmap/2, map_in_order/2]).
-export([table_filter/3]).
-export([dirty_read_all/1, dirty_foreach_key/2, dirty_dump_log/1]).
--export([read_term_file/1, write_term_file/2, write_file/2, write_file/3]).
--export([append_file/2, ensure_parent_dirs_exist/1]).
--export([is_file/1, is_dir/1, file_size/1, ensure_dir/1, wildcard/2, list_dir/1]).
-export([format_stderr/2, with_local_io/1]).
-export([start_applications/1, stop_applications/1]).
-export([unfold/2, ceil/1, queue_fold/3]).
-export([sort_field_table/1]).
-export([pid_to_string/1, string_to_pid/1]).
-export([version_compare/2, version_compare/3]).
--export([delete/1, recursive_delete/1, recursive_copy/2]).
-export([dict_cons/3, orddict_cons/3]).
-export([get_options/2]).
-export([all_module_attributes/1, build_acyclic_graph/3]).
-export([now_ms/0]).
--export([lock_file/1]).
-export([const_ok/0, const/1]).
-export([ntoa/1, ntoab/1]).
-export([is_process_alive/1]).
-export([pget/2, pget/3, pget_or_die/2]).
-export([format_message_queue/2]).
-export([append_rpc_all_nodes/4]).
--export([with_fhc_handle/1]).
%%----------------------------------------------------------------------------
@@ -161,13 +153,6 @@
-spec(dirty_foreach_key/2 :: (fun ((any()) -> any()), atom())
-> 'ok' | 'aborted').
-spec(dirty_dump_log/1 :: (file:filename()) -> ok_or_error()).
--spec(read_term_file/1 ::
- (file:filename()) -> {'ok', [any()]} | rabbit_types:error(any())).
--spec(write_term_file/2 :: (file:filename(), [any()]) -> ok_or_error()).
--spec(write_file/2 :: (file:filename(), iodata()) -> ok_or_error()).
--spec(write_file/3 :: (file:filename(), iodata(), [any()]) -> ok_or_error()).
--spec(append_file/2 :: (file:filename(), string()) -> ok_or_error()).
--spec(ensure_parent_dirs_exist/1 :: (string()) -> 'ok').
-spec(format_stderr/2 :: (string(), [any()]) -> 'ok').
-spec(with_local_io/1 :: (fun (() -> A)) -> A).
-spec(start_applications/1 :: ([atom()]) -> 'ok').
@@ -183,12 +168,6 @@
-spec(version_compare/3 ::
(string(), string(), ('lt' | 'lte' | 'eq' | 'gte' | 'gt'))
-> boolean()).
--spec(recursive_delete/1 ::
- ([file:filename()])
- -> rabbit_types:ok_or_error({file:filename(), any()})).
--spec(recursive_copy/2 ::
- (file:filename(), file:filename())
- -> rabbit_types:ok_or_error({file:filename(), file:filename(), any()})).
-spec(dict_cons/3 :: (any(), any(), dict()) -> dict()).
-spec(orddict_cons/3 :: (any(), any(), orddict:orddict()) -> orddict:orddict()).
-spec(get_options/2 :: ([optdef()], [string()])
@@ -202,7 +181,6 @@
{bad_edge, [digraph:vertex()]}),
digraph:vertex(), digraph:vertex()})).
-spec(now_ms/0 :: () -> non_neg_integer()).
--spec(lock_file/1 :: (file:filename()) -> rabbit_types:ok_or_error('eexist')).
-spec(const_ok/0 :: () -> 'ok').
-spec(const/1 :: (A) -> thunk(A)).
-spec(ntoa/1 :: (inet:ip_address()) -> string()).
@@ -528,155 +506,6 @@ dirty_dump_log1(LH, {K, Terms, BadBytes}) ->
io:format("Bad Chunk, ~p: ~p~n", [BadBytes, Terms]),
dirty_dump_log1(LH, disk_log:chunk(LH, K)).
-
-read_term_file(File) ->
- try
- {ok, Data} = with_fhc_handle(fun () -> prim_file:read_file(File) end),
- {ok, Tokens, _} = erl_scan:string(binary:bin_to_list(Data)),
- TokenGroups = group_tokens(Tokens),
- {ok, [begin
- {ok, Term} = erl_parse:parse_term(Tokens1),
- Term
- end || Tokens1 <- TokenGroups]}
- catch
- error:{badmatch, Error} -> Error
- end.
-
-group_tokens([]) ->
- [];
-group_tokens([{_, N, _} | _] = Tokens) ->
- lists:reverse(group_tokens([], N, Tokens));
-group_tokens([{_, N} | _] = Tokens) ->
- lists:reverse(group_tokens([], N, Tokens)).
-
-group_tokens(Cur, _, []) ->
- [lists:reverse(Cur)];
-group_tokens(Cur, N, [Tok = {_, N} | Toks]) ->
- group_tokens([Tok | Cur], N, Toks);
-group_tokens(Cur, _, [{_, M} | _] = Toks) ->
- [lists:reverse(Cur) | group_tokens([], M, Toks)];
-group_tokens(Cur, N, [Tok = {_, N, _} | Toks]) ->
- group_tokens([Tok | Cur], N, Toks);
-group_tokens(Cur, _, [{_, M, _} | _] = Toks) ->
- [lists:reverse(Cur) | group_tokens([], M, Toks)].
-
-write_term_file(File, Terms) ->
- write_file(File, list_to_binary([io_lib:format("~w.~n", [Term]) ||
- Term <- Terms])).
-
-write_file(Path, Data) ->
- write_file(Path, Data, []).
-
-%% write_file/3 and make_binary/1 are both based on corresponding
-%% functions in the kernel/file.erl module of the Erlang R14B02
-%% release, which is licensed under the EPL. That implementation of
-%% write_file/3 does not do an fsync prior to closing the file, hence
-%% the existence of this version. APIs are otherwise identical.
-write_file(Path, Data, Modes) ->
- Modes1 = [binary, write | (Modes -- [binary, write])],
- case make_binary(Data) of
- Bin when is_binary(Bin) ->
- with_fhc_handle(
- fun () -> case prim_file:open(Path, Modes1) of
- {ok, Hdl} -> try prim_file:write(Hdl, Bin) of
- ok -> prim_file:sync(Hdl);
- {error, _} = E -> E
- after
- prim_file:close(Hdl)
- end;
- {error, _} = E -> E
- end
- end);
- {error, _} = E -> E
- end.
-
-make_binary(Bin) when is_binary(Bin) ->
- Bin;
-make_binary(List) ->
- try
- iolist_to_binary(List)
- catch error:Reason ->
- {error, Reason}
- end.
-
-
-append_file(File, Suffix) ->
- case read_file_info(File) of
- {ok, FInfo} -> append_file(File, FInfo#file_info.size, Suffix);
- {error, enoent} -> append_file(File, 0, Suffix);
- Error -> Error
- end.
-
-append_file(_, _, "") ->
- ok;
-append_file(File, 0, Suffix) ->
- with_fhc_handle(fun () ->
- case prim_file:open([File, Suffix], [append]) of
- {ok, Fd} -> prim_file:close(Fd);
- Error -> Error
- end
- end);
-append_file(File, _, Suffix) ->
- case with_fhc_handle(fun () -> prim_file:read_file(File) end) of
- {ok, Data} -> write_file([File, Suffix], Data, [append]);
- Error -> Error
- end.
-
-ensure_parent_dirs_exist(Filename) ->
- case ensure_dir(Filename) of
- ok -> ok;
- {error, Reason} ->
- throw({error, {cannot_create_parent_dirs, Filename, Reason}})
- end.
-
-is_file(File) ->
- case read_file_info(File) of
- {ok, #file_info{type=regular}} -> true;
- {ok, #file_info{type=directory}} -> true;
- _ -> false
- end.
-
-is_dir(Dir) -> is_dir_internal(read_file_info(Dir)).
-is_dir_no_handle(Dir) -> is_dir_internal(prim_file:read_file_info(Dir)).
-
-is_dir_internal({ok, #file_info{type=directory}}) -> true;
-is_dir_internal(_) -> false.
-
-file_size(File) ->
- case read_file_info(File) of
- {ok, #file_info{size=Size}} -> Size;
- _ -> 0
- end.
-
-ensure_dir(File) -> with_fhc_handle(fun () -> ensure_dir_internal(File) end).
-
-ensure_dir_internal("/") ->
- ok;
-ensure_dir_internal(File) ->
- Dir = filename:dirname(File),
- case is_dir_no_handle(Dir) of
- true -> ok;
- false -> ensure_dir_internal(Dir),
- prim_file:make_dir(Dir)
- end.
-
-wildcard(Pattern, Dir) ->
- {ok, Files} = list_dir(Dir),
- {ok, RE} = re:compile(Pattern, [anchored]),
- [File || File <- Files, match =:= re:run(File, RE, [{capture, none}])].
-
-list_dir(Dir) ->
- with_fhc_handle(fun () -> prim_file:list_dir(Dir) end).
-
-read_file_info(File) ->
- with_fhc_handle(fun () -> prim_file:read_file_info(File) end).
-
-with_fhc_handle(Fun) ->
- ok = file_handle_cache:obtain(),
- try Fun()
- after ok = file_handle_cache:release()
- end.
-
format_stderr(Fmt, Args) ->
case os:type() of
{unix, _} ->
@@ -827,79 +656,6 @@ version_compare(A, B) ->
dropdot(A) -> lists:dropwhile(fun (X) -> X =:= $. end, A).
-delete(File) -> with_fhc_handle(fun () -> prim_file:delete(File) end).
-
-recursive_delete(Files) ->
- with_fhc_handle(
- fun () -> lists:foldl(fun (Path, ok) -> recursive_delete1(Path);
- (_Path, {error, _Err} = Error) -> Error
- end, ok, Files)
- end).
-
-recursive_delete1(Path) ->
- case is_dir_no_handle(Path) and not(is_symlink_no_handle(Path)) of
- false -> case prim_file:delete(Path) of
- ok -> ok;
- {error, enoent} -> ok; %% Path doesn't exist anyway
- {error, Err} -> {error, {Path, Err}}
- end;
- true -> case prim_file:list_dir(Path) of
- {ok, FileNames} ->
- case lists:foldl(
- fun (FileName, ok) ->
- recursive_delete1(
- filename:join(Path, FileName));
- (_FileName, Error) ->
- Error
- end, ok, FileNames) of
- ok ->
- case prim_file:del_dir(Path) of
- ok -> ok;
- {error, Err} -> {error, {Path, Err}}
- end;
- {error, _Err} = Error ->
- Error
- end;
- {error, Err} ->
- {error, {Path, Err}}
- end
- end.
-
-is_symlink_no_handle(File) ->
- case prim_file:read_link(File) of
- {ok, _} -> true;
- _ -> false
- end.
-
-recursive_copy(Src, Dest) ->
- %% Note that this uses the 'file' module and, hence, shouldn't be
- %% run on many processes at once.
- case is_dir(Src) of
- false -> case file:copy(Src, Dest) of
- {ok, _Bytes} -> ok;
- {error, enoent} -> ok; %% Path doesn't exist anyway
- {error, Err} -> {error, {Src, Dest, Err}}
- end;
- true -> case file:list_dir(Src) of
- {ok, FileNames} ->
- case file:make_dir(Dest) of
- ok ->
- lists:foldl(
- fun (FileName, ok) ->
- recursive_copy(
- filename:join(Src, FileName),
- filename:join(Dest, FileName));
- (_FileName, Error) ->
- Error
- end, ok, FileNames);
- {error, Err} ->
- {error, {Src, Dest, Err}}
- end;
- {error, Err} ->
- {error, {Src, Dest, Err}}
- end
- end.
-
dict_cons(Key, Value, Dict) ->
dict:update(Key, fun (List) -> [Value | List] end, [Value], Dict).
@@ -989,17 +745,6 @@ build_acyclic_graph(VertexFun, EdgeFun, Graph) ->
{error, Reason}
end.
-%% TODO: When we stop supporting Erlang prior to R14, this should be
-%% replaced with file:open [write, exclusive]
-lock_file(Path) ->
- case is_file(Path) of
- true -> {error, eexist};
- false -> with_fhc_handle(
- fun () -> {ok, Lock} = prim_file:open(Path, [write]),
- ok = prim_file:close(Lock)
- end)
- end.
-
const_ok() -> ok.
const(X) -> fun () -> X end.
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 665b15c5..9348896a 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -434,7 +434,7 @@ cluster_nodes_config_filename() ->
create_cluster_nodes_config(ClusterNodes) ->
FileName = cluster_nodes_config_filename(),
- case rabbit_misc:write_term_file(FileName, [ClusterNodes]) of
+ case rabbit_file:write_term_file(FileName, [ClusterNodes]) of
ok -> ok;
{error, Reason} ->
throw({error, {cannot_create_cluster_nodes_config,
@@ -443,7 +443,7 @@ create_cluster_nodes_config(ClusterNodes) ->
read_cluster_nodes_config() ->
FileName = cluster_nodes_config_filename(),
- case rabbit_misc:read_term_file(FileName) of
+ case rabbit_file:read_term_file(FileName) of
{ok, [ClusterNodes]} -> ClusterNodes;
{error, enoent} ->
{ok, ClusterNodes} = application:get_env(rabbit, cluster_nodes),
@@ -471,12 +471,12 @@ record_running_nodes() ->
Nodes = running_clustered_nodes() -- [node()],
%% Don't check the result: we're shutting down anyway and this is
%% a best-effort-basis.
- rabbit_misc:write_term_file(FileName, [Nodes]),
+ rabbit_file:write_term_file(FileName, [Nodes]),
ok.
read_previously_running_nodes() ->
FileName = running_nodes_filename(),
- case rabbit_misc:read_term_file(FileName) of
+ case rabbit_file:read_term_file(FileName) of
{ok, [Nodes]} -> Nodes;
{error, enoent} -> [];
{error, Reason} -> throw({error, {cannot_read_previous_nodes_file,
@@ -638,7 +638,7 @@ move_db() ->
copy_db(Destination) ->
ok = ensure_mnesia_not_running(),
- rabbit_misc:recursive_copy(dir(), Destination).
+ rabbit_file:recursive_copy(dir(), Destination).
create_tables() -> create_tables(disc).
@@ -745,7 +745,7 @@ reset(Force) ->
end,
ok = delete_cluster_nodes_config(),
%% remove persisted messages and any other garbage we find
- ok = rabbit_misc:recursive_delete(filelib:wildcard(dir() ++ "/*")),
+ ok = rabbit_file:recursive_delete(filelib:wildcard(dir() ++ "/*")),
ok.
leave_cluster([], _) -> ok;
diff --git a/src/rabbit_msg_store.erl b/src/rabbit_msg_store.erl
index cc12eb5d..fc3cbebd 100644
--- a/src/rabbit_msg_store.erl
+++ b/src/rabbit_msg_store.erl
@@ -589,7 +589,7 @@ init([Server, BaseDir, ClientRefs, StartupFunState]) ->
AttemptFileSummaryRecovery =
case ClientRefs of
- undefined -> ok = rabbit_misc:recursive_delete([Dir]),
+ undefined -> ok = rabbit_file:recursive_delete([Dir]),
ok = filelib:ensure_dir(filename:join(Dir, "nothing")),
false;
_ -> ok = filelib:ensure_dir(filename:join(Dir, "nothing")),
@@ -1340,11 +1340,11 @@ recover_index_and_client_refs(IndexModule, true, ClientRefs, Dir, Server) ->
end.
store_recovery_terms(Terms, Dir) ->
- rabbit_misc:write_term_file(filename:join(Dir, ?CLEAN_FILENAME), Terms).
+ rabbit_file:write_term_file(filename:join(Dir, ?CLEAN_FILENAME), Terms).
read_recovery_terms(Dir) ->
Path = filename:join(Dir, ?CLEAN_FILENAME),
- case rabbit_misc:read_term_file(Path) of
+ case rabbit_file:read_term_file(Path) of
{ok, Terms} -> case file:delete(Path) of
ok -> {true, Terms};
{error, Error} -> {false, Error}
@@ -1901,7 +1901,7 @@ transform_dir(BaseDir, Store, TransformFun) ->
end.
transform_msg_file(FileOld, FileNew, TransformFun) ->
- ok = rabbit_misc:ensure_parent_dirs_exist(FileNew),
+ ok = rabbit_file:ensure_parent_dirs_exist(FileNew),
{ok, RefOld} = file_handle_cache:open(FileOld, [raw, binary, read], []),
{ok, RefNew} = file_handle_cache:open(FileNew, [raw, binary, write],
[{write_buffer,
diff --git a/src/rabbit_prelaunch.erl b/src/rabbit_prelaunch.erl
index 9fe073d9..cd0c322b 100644
--- a/src/rabbit_prelaunch.erl
+++ b/src/rabbit_prelaunch.erl
@@ -70,7 +70,7 @@ start() ->
AppVersions},
%% Write it out to $RABBITMQ_PLUGINS_EXPAND_DIR/rabbit.rel
- rabbit_misc:write_file(RootName ++ ".rel", io_lib:format("~p.~n", [RDesc])),
+ rabbit_file:write_file(RootName ++ ".rel", io_lib:format("~p.~n", [RDesc])),
%% We exclude mochiweb due to its optional use of fdsrv.
XRefExclude = [mochiweb],
@@ -139,7 +139,7 @@ determine_version(App) ->
{App, Vsn}.
delete_recursively(Fn) ->
- case rabbit_misc:recursive_delete([Fn]) of
+ case rabbit_file:recursive_delete([Fn]) of
ok -> ok;
{error, {Path, E}} -> {error, {cannot_delete, Path, E}};
Error -> Error
diff --git a/src/rabbit_queue_index.erl b/src/rabbit_queue_index.erl
index 9febaf47..f1751e95 100644
--- a/src/rabbit_queue_index.erl
+++ b/src/rabbit_queue_index.erl
@@ -229,7 +229,7 @@
init(Name, OnSyncFun) ->
State = #qistate { dir = Dir } = blank_state(Name),
- false = rabbit_misc:is_file(Dir), %% is_file == is file or dir
+ false = rabbit_file:is_file(Dir), %% is_file == is file or dir
State #qistate { on_sync = OnSyncFun }.
shutdown_terms(Name) ->
@@ -256,7 +256,7 @@ terminate(Terms, State) ->
delete_and_terminate(State) ->
{_SegmentCounts, State1 = #qistate { dir = Dir }} = terminate(State),
- ok = rabbit_misc:recursive_delete([Dir]),
+ ok = rabbit_file:recursive_delete([Dir]),
State1.
publish(MsgId, SeqId, MsgProps, IsPersistent,
@@ -359,16 +359,16 @@ recover(DurableQueues) ->
{[dict:fetch(QueueDirName, DurableDict) | DurableAcc],
TermsAcc1};
false ->
- ok = rabbit_misc:recursive_delete([QueueDirPath]),
+ ok = rabbit_file:recursive_delete([QueueDirPath]),
{DurableAcc, TermsAcc}
end
end, {[], []}, QueueDirNames),
{DurableTerms, {fun queue_index_walker/1, {start, DurableQueueNames}}}.
all_queue_directory_names(Dir) ->
- case rabbit_misc:list_dir(Dir) of
+ case rabbit_file:list_dir(Dir) of
{ok, Entries} -> [ Entry || Entry <- Entries,
- rabbit_misc:is_dir(
+ rabbit_file:is_dir(
filename:join(Dir, Entry)) ];
{error, enoent} -> []
end.
@@ -392,18 +392,18 @@ blank_state(QueueName) ->
clean_file_name(Dir) -> filename:join(Dir, ?CLEAN_FILENAME).
detect_clean_shutdown(Dir) ->
- case rabbit_misc:delete(clean_file_name(Dir)) of
+ case rabbit_file:delete(clean_file_name(Dir)) of
ok -> true;
{error, enoent} -> false
end.
read_shutdown_terms(Dir) ->
- rabbit_misc:read_term_file(clean_file_name(Dir)).
+ rabbit_file:read_term_file(clean_file_name(Dir)).
store_clean_shutdown(Terms, Dir) ->
CleanFileName = clean_file_name(Dir),
- ok = rabbit_misc:ensure_dir(CleanFileName),
- rabbit_misc:write_term_file(CleanFileName, Terms).
+ ok = rabbit_file:ensure_dir(CleanFileName),
+ rabbit_file:write_term_file(CleanFileName, Terms).
init_clean(RecoveredCounts, State) ->
%% Load the journal. Since this is a clean recovery this (almost)
@@ -603,8 +603,8 @@ flush_journal(State = #qistate { segments = Segments }) ->
Segments1 =
segment_fold(
fun (#segment { unacked = 0, path = Path }, SegmentsN) ->
- case rabbit_misc:is_file(Path) of
- true -> ok = rabbit_misc:delete(Path);
+ case rabbit_file:is_file(Path) of
+ true -> ok = rabbit_file:delete(Path);
false -> ok
end,
SegmentsN;
@@ -630,7 +630,7 @@ append_journal_to_segment(#segment { journal_entries = JEntries,
get_journal_handle(State = #qistate { journal_handle = undefined,
dir = Dir }) ->
Path = filename:join(Dir, ?JOURNAL_FILENAME),
- ok = rabbit_misc:ensure_dir(Path),
+ ok = rabbit_file:ensure_dir(Path),
{ok, Hdl} = file_handle_cache:open(Path, ?WRITE_MODE,
[{write_buffer, infinity}]),
{Hdl, State #qistate { journal_handle = Hdl }};
@@ -735,7 +735,7 @@ all_segment_nums(#qistate { dir = Dir, segments = Segments }) ->
lists:takewhile(fun (C) -> $0 =< C andalso C =< $9 end,
SegName)), Set)
end, sets:from_list(segment_nums(Segments)),
- rabbit_misc:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)))).
+ rabbit_file:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)))).
segment_find_or_new(Seg, Dir, Segments) ->
case segment_find(Seg, Segments) of
@@ -836,7 +836,7 @@ segment_entries_foldr(Fun, Init,
%%
%% Does not do any combining with the journal at all.
load_segment(KeepAcked, #segment { path = Path }) ->
- case rabbit_misc:is_file(Path) of
+ case rabbit_file:is_file(Path) of
false -> {array_new(), 0};
true -> {ok, Hdl} = file_handle_cache:open(Path, ?READ_AHEAD_MODE, []),
{ok, 0} = file_handle_cache:position(Hdl, bof),
@@ -1040,12 +1040,12 @@ foreach_queue_index(Funs) ->
transform_queue(Dir, Gatherer, {JournalFun, SegmentFun}) ->
ok = transform_file(filename:join(Dir, ?JOURNAL_FILENAME), JournalFun),
[ok = transform_file(filename:join(Dir, Seg), SegmentFun)
- || Seg <- rabbit_misc:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)],
+ || Seg <- rabbit_file:wildcard(".*\\" ++ ?SEGMENT_EXTENSION, Dir)],
ok = gatherer:finish(Gatherer).
transform_file(Path, Fun) ->
PathTmp = Path ++ ".upgrade",
- case rabbit_misc:file_size(Path) of
+ case rabbit_file:file_size(Path) of
0 -> ok;
Size -> {ok, PathTmpHdl} =
file_handle_cache:open(PathTmp, ?WRITE_MODE,
@@ -1059,8 +1059,7 @@ transform_file(Path, Fun) ->
ok = drive_transform_fun(Fun, PathTmpHdl, Content),
ok = file_handle_cache:close(PathTmpHdl),
- ok = rabbit_misc:with_fhc_handle(
- fun () -> prim_file:rename(PathTmp, Path) end)
+ ok = rabbit_file:rename(PathTmp, Path)
end.
drive_transform_fun(Fun, Hdl, Contents) ->
diff --git a/src/rabbit_sasl_report_file_h.erl b/src/rabbit_sasl_report_file_h.erl
index 6f3c5c75..c708de32 100644
--- a/src/rabbit_sasl_report_file_h.erl
+++ b/src/rabbit_sasl_report_file_h.erl
@@ -30,7 +30,7 @@
%% Used only when swapping handlers and performing
%% log rotation
init({{File, Suffix}, []}) ->
- case rabbit_misc:append_file(File, Suffix) of
+ case rabbit_file:append_file(File, Suffix) of
ok -> ok;
{error, Error} ->
rabbit_log:error("Failed to append contents of "
@@ -47,10 +47,10 @@ init({{File, _}, error}) ->
init({File, []}) ->
init(File);
init({File, _Type} = FileInfo) ->
- rabbit_misc:ensure_parent_dirs_exist(File),
+ rabbit_file:ensure_parent_dirs_exist(File),
sasl_report_file_h:init(FileInfo);
init(File) ->
- rabbit_misc:ensure_parent_dirs_exist(File),
+ rabbit_file:ensure_parent_dirs_exist(File),
sasl_report_file_h:init({File, sasl_error_logger_type()}).
handle_event(Event, State) ->
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index 7e84251f..b1ed46dd 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -1765,7 +1765,7 @@ test_file_handle_cache() ->
[filename:join(TmpDir, Str) || Str <- ["file1", "file2", "file3", "file4"]],
Content = <<"foo">>,
CopyFun = fun (Src, Dst) ->
- ok = rabbit_misc:write_file(Src, Content),
+ ok = rabbit_file:write_file(Src, Content),
{ok, SrcHdl} = file_handle_cache:open(Src, [read], []),
{ok, DstHdl} = file_handle_cache:open(Dst, [write], []),
Size = size(Content),
diff --git a/src/rabbit_upgrade.erl b/src/rabbit_upgrade.erl
index e7a302f8..717d94a8 100644
--- a/src/rabbit_upgrade.erl
+++ b/src/rabbit_upgrade.erl
@@ -115,7 +115,7 @@ ensure_backup_removed() ->
end.
remove_backup() ->
- ok = rabbit_misc:recursive_delete([backup_dir()]),
+ ok = rabbit_file:recursive_delete([backup_dir()]),
info("upgrades: Mnesia backup removed~n", []).
maybe_upgrade_mnesia() ->
@@ -249,7 +249,7 @@ maybe_upgrade_local() ->
%% -------------------------------------------------------------------
apply_upgrades(Scope, Upgrades, Fun) ->
- ok = rabbit_misc:lock_file(lock_filename()),
+ ok = rabbit_file:lock_file(lock_filename()),
info("~s upgrades: ~w to apply~n", [Scope, length(Upgrades)]),
rabbit_misc:ensure_ok(mnesia:start(), cannot_start_mnesia),
Fun(),
diff --git a/src/rabbit_version.erl b/src/rabbit_version.erl
index 400abc10..f6bcbb7f 100644
--- a/src/rabbit_version.erl
+++ b/src/rabbit_version.erl
@@ -49,12 +49,12 @@
%% -------------------------------------------------------------------
-recorded() -> case rabbit_misc:read_term_file(schema_filename()) of
+recorded() -> case rabbit_file:read_term_file(schema_filename()) of
{ok, [V]} -> {ok, V};
{error, _} = Err -> Err
end.
-record(V) -> ok = rabbit_misc:write_term_file(schema_filename(), [V]).
+record(V) -> ok = rabbit_file:write_term_file(schema_filename(), [V]).
recorded_for_scope(Scope) ->
case recorded() of