summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2014-09-25 08:35:07 +0200
committerMagnus Ahltorp <map@kth.se>2014-09-25 08:35:07 +0200
commitbd4e605633b98267041ab4653e055c18ffd9674a (patch)
treef38aca29999a70cda2d57ca988c2211e15a2fc87
parentae9f673d35ec0140a7276297cee002bfd3a15852 (diff)
perm: Don't crash if file content is different, tell caller instead. Better error handling.
-rw-r--r--src/perm.erl54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/perm.erl b/src/perm.erl
index 2ce5b46..34f431c 100644
--- a/src/perm.erl
+++ b/src/perm.erl
@@ -6,17 +6,25 @@
-module(perm).
-export([ensurefile/3]).
-fsync(Name) ->
- fsyncport:fsync(Name).
+fsync([]) ->
+ ok;
+fsync([Name | Rest]) ->
+ case fsyncport:fsync(Name) of
+ ok ->
+ fsync(Rest);
+ {error, Error} ->
+ {error, Error}
+ end.
readfile_and_verify(Name, Content) ->
case file:read_file(Name) of
{ok, ContentsReadBinary} ->
ContentsRead = binary_to_list(ContentsReadBinary),
- if Content == ContentsRead ->
+ if
+ Content == ContentsRead ->
ok;
- true ->
- {error, "File contents differ"}
+ true ->
+ differ
end;
{error, Error} ->
{error, Error}
@@ -72,24 +80,32 @@ tempfilename(Base) ->
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.
+
ensurefile(Rootdir, Key, Content) ->
{Dirs, Path} = path_for_key(Rootdir, Key),
case readfile_and_verify(Path, Content) of
ok ->
- lists:foreach(fun (Dir) -> fsync(Dir) end, [Path, Rootdir | Dirs]);
+ check_error(fsync([Path, Rootdir | Dirs]), "Error in fsync");
+ differ ->
+ differ;
{error, enoent} ->
- case make_dirs([Rootdir, Rootdir ++ "nursery/"] ++ Dirs) of
- ok ->
- NurseryName = Rootdir ++ "nursery/" ++
- tempfilename(hex:bin_to_hexstr(Key)),
- _Result = writefile(Path, NurseryName, Content),
- lists:foreach(fun (Dir) ->
- fsync(Dir)
- end,
- [Path, Rootdir | Dirs]); %% XXX check results
- {error, Error} ->
- io:format("Error creating directory: ~w~n", [Error])
- end;
+ check_error(make_dirs([Rootdir, Rootdir ++ "nursery/"] ++ Dirs),
+ "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");
{error, Error} ->
- exit({perm, fileerror, "Error reading file", Error})
+ exit_with_error(Error, "Error reading file")
end.