summaryrefslogtreecommitdiff
path: root/src/perm.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/perm.erl')
-rw-r--r--src/perm.erl73
1 files changed, 15 insertions, 58 deletions
diff --git a/src/perm.erl b/src/perm.erl
index 5cd2889..ccb23bc 100644
--- a/src/perm.erl
+++ b/src/perm.erl
@@ -6,16 +6,7 @@
-module(perm).
-export([ensurefile/3, readfile/2]).
-fsync([]) ->
- ok;
-fsync([Name | Rest]) ->
- case fsyncport:fsync(Name) of
- ok ->
- fsync(Rest);
- {error, Error} ->
- {error, Error}
- end.
-
+-spec readfile_and_verify(string(), binary()) -> ok | differ | {error, atom()}.
readfile_and_verify(Name, Content) ->
case file:read_file(Name) of
{ok, ContentsRead} when Content == ContentsRead ->
@@ -26,21 +17,7 @@ readfile_and_verify(Name, Content) ->
{error, Error}
end.
-writefile(Name, NurseryName, Content) ->
- case file:open(NurseryName, [write, exclusive]) of
- {ok, File} ->
- %io:format("Write file: ~p~n", [Name]),
- ok = file:write(File, Content),
- file:close(File),
- Result = file:rename(NurseryName, Name),
- Result;
- {error, eexist} ->
- %% Should not happen, file name should be unique
- {error, eexist};
- {error, Error} ->
- {error, Error}
- end.
-
+-spec make_dir(string()) -> ok | {error, atom()}.
make_dir(Name) ->
case file:make_dir(Name) of
ok ->
@@ -51,6 +28,7 @@ make_dir(Name) ->
{error, Error}
end.
+-spec make_dirs([string()]) -> ok | {error, atom()}.
make_dirs([]) ->
ok;
make_dirs([Name | Rest]) ->
@@ -61,6 +39,7 @@ make_dirs([Name | Rest]) ->
{error, Error}
end.
+-spec path_for_key(string(), binary()) -> {[string()], string()}.
path_for_key(Rootdir, Key) ->
Name = hex:bin_to_hexstr(Key),
[C1, C2, C3, C4, C5, C6 | _] = Name,
@@ -70,49 +49,27 @@ path_for_key(Rootdir, Key) ->
Fullpath = Thirdlevel ++ "/" ++ Name,
{[Firstlevel, Secondlevel, Thirdlevel], Fullpath}.
-tempfilename(Base) ->
- {MegaSecs, Secs, MicroSecs} = now(),
- Filename = io_lib:format("~s-~s-~p.~p", [Base, os:getpid(),
- MegaSecs * 1000000 + Secs, MicroSecs]),
- Filename.
-
-exit_with_error(Error, Message) ->
- io:format("~s: ~w~n", [Message, Error]),
- exit({perm, fileerror, Message, Error}).
-
-check_error(ReturnValue, ErrorMessage) ->
- case ReturnValue of
- ok ->
- ok;
- {error, Error} ->
- exit_with_error(Error, ErrorMessage)
- end.
-
+-spec ensurefile(string(), binary(), binary()) -> ok | differ.
ensurefile(Rootdir, Key, Content) ->
{Dirs, Path} = path_for_key(Rootdir, Key),
case readfile_and_verify(Path, Content) of
ok ->
- check_error(fsync([Path, Rootdir | Dirs]), "Error in fsync");
+ util:fsync([Path, Rootdir | Dirs]);
differ ->
differ;
{error, enoent} ->
- check_error(make_dirs([Rootdir, Rootdir ++ "nursery/"] ++ Dirs),
- "Error creating directory"),
+ util:check_error(make_dirs([Rootdir, Rootdir ++ "nursery/"]
+ ++ Dirs),
+ makedir, "Error creating directory"),
NurseryName = Rootdir ++ "nursery/" ++
- tempfilename(hex:bin_to_hexstr(Key)),
- _Result = writefile(Path, NurseryName, Content),
- check_error(fsync([Path, Rootdir | Dirs]), "Error in fsync");
+ util:tempfilename(hex:bin_to_hexstr(Key)),
+ util:write_tempfile_and_rename(Path, NurseryName, Content),
+ util:fsync([Path, Rootdir | Dirs]);
{error, Error} ->
- exit_with_error(Error, "Error reading file")
+ util:exit_with_error(Error, readfile, "Error reading file")
end.
+-spec readfile(string(), binary()) -> binary().
readfile(Rootdir, Key) ->
{_Dirs, Path} = path_for_key(Rootdir, Key),
- case file:read_file(Path) of
- {ok, Contents} ->
- Contents;
- {error, enoent} ->
- noentry;
- {error, Error} ->
- exit_with_error(Error, "Error reading file")
- end.
+ atomic:readfile(Path).