diff options
author | Hans Bolinder <[email protected]> | 2014-03-05 14:14:00 +0100 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2014-03-05 15:05:58 +0100 |
commit | e936ccec462760c4bb98679f1b88a7a5a3ead65f (patch) | |
tree | b6d42db19f3768b2e1a2c3818bad34c72eacf13b /lib/stdlib | |
parent | f02afa352f14e2dc0f3be4f6854a68b14129c2ba (diff) | |
download | otp-e936ccec462760c4bb98679f1b88a7a5a3ead65f.tar.gz otp-e936ccec462760c4bb98679f1b88a7a5a3ead65f.tar.bz2 otp-e936ccec462760c4bb98679f1b88a7a5a3ead65f.zip |
stdlib: Fix a Dets bug where files were deleted
Instead of deleting the small file when opening it with
dets:open_file/2 an error message is returned, mimicking the behaviour
when the file is bigger.
open_file/1 has been modified to return the same error message when
the file is small as when the file is bigger.
Thanks to Hakan Mattson for reporting this bug.
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/src/dets.erl | 9 | ||||
-rw-r--r-- | lib/stdlib/test/dets_SUITE.erl | 54 |
2 files changed, 37 insertions, 26 deletions
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl index 8c5c86f3b9..c32da1624f 100644 --- a/lib/stdlib/src/dets.erl +++ b/lib/stdlib/src/dets.erl @@ -2114,6 +2114,8 @@ test_bchunk_format(Head, Term) -> do_open_file([Fname, Verbose], Parent, Server, Ref) -> case catch fopen2(Fname, Ref) of + {error, {tooshort, _}} -> + err({error, {not_a_dets_file, Fname}}); {error, _Reason} = Error -> err(Error); {ok, Head} -> @@ -2127,11 +2129,10 @@ do_open_file([Fname, Verbose], Parent, Server, Ref) -> [Bad]), {error, {dets_bug, Fname, Bad}} end; -do_open_file([Tab, OpenArgs, Verb], Parent, Server, Ref) -> +do_open_file([Tab, OpenArgs, Verb], Parent, Server, _Ref) -> case catch fopen3(Tab, OpenArgs) of {error, {tooshort, _}} -> - _ = file:delete(OpenArgs#open_args.file), - do_open_file([Tab, OpenArgs, Verb], Parent, Server, Ref); + err({error, {not_a_dets_file, OpenArgs#open_args.file}}); {error, _Reason} = Error -> err(Error); {ok, Head} -> @@ -2487,7 +2488,6 @@ fopen2(Fname, Tab) -> {ok, _} -> Acc = read_write, Ram = false, - %% Fd is not always closed upon error, but exit is soon called. {ok, Fd, FH} = read_file_header(Fname, Acc, Ram), Mod = FH#fileheader.mod, Do = case Mod:check_file_header(FH, Fd) of @@ -2543,7 +2543,6 @@ fopen_existing_file(Tab, OpenArgs) -> ram_file = Ram, delayed_write = CacheSz, auto_save = Auto, access = Acc, version = Version, debug = Debug} = OpenArgs, - %% Fd is not always closed upon error, but exit is soon called. {ok, Fd, FH} = read_file_header(Fname, Acc, Ram), V9 = (Version =:= 9) or (Version =:= default), MinF = (MinSlots =:= default) or (MinSlots =:= FH#fileheader.min_no_slots), diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl index 0f6b76a629..00a5da42ad 100644 --- a/lib/stdlib/test/dets_SUITE.erl +++ b/lib/stdlib/test/dets_SUITE.erl @@ -772,9 +772,9 @@ open_1(Config, V) -> crash(Fname, TypePos), {error, {invalid_type_code,Fname}} = dets:open_file(Fname), truncate(Fname, HeadSize - 10), - {error, {tooshort,Fname}} = dets:open_file(Fname), - {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]), - ok = dets:close(TabRef), + {error,{not_a_dets_file,Fname}} = dets:open_file(Fname), + {error,{not_a_dets_file,Fname}} = + dets:open_file(TabRef, [{file,Fname},{version,V}]), file:delete(Fname), {error,{file_error,{foo,bar},_}} = dets:is_dets_file({foo,bar}), @@ -967,10 +967,12 @@ fast_init_table(Config) -> {'EXIT', _} = (catch dets:init_table(TabRef, fun(foo) -> bar end, {format,bchunk})), dets:close(TabRef), + file:delete(Fname), {ok, _} = dets:open_file(TabRef, Args), {'EXIT', _} = (catch dets:init_table(TabRef, fun() -> foo end, {format,bchunk})), dets:close(TabRef), + file:delete(Fname), {ok, _} = dets:open_file(TabRef, Args), {'EXIT', {badarg, _}} = (catch dets:init_table(TabRef, nofun, {format,bchunk})), @@ -979,10 +981,12 @@ fast_init_table(Config) -> away = (catch dets:init_table(TabRef, fun(_) -> throw(away) end, {format,bchunk})), dets:close(TabRef), + file:delete(Fname), {ok, _} = dets:open_file(TabRef, Args), {error, {init_fun, fopp}} = dets:init_table(TabRef, fun(read) -> fopp end, {format,bchunk}), dets:close(TabRef), + file:delete(Fname), {ok, _} = dets:open_file(TabRef, Args), dets:safe_fixtable(TabRef, true), {error, {fixed_table, TabRef}} = @@ -1389,23 +1393,6 @@ repair(Config, V) -> {ok, TabRef} = dets:open_file(TabRef, [{file,Fname},{version,V}]), ok = ins(TabRef, 100), ok = dets:close(TabRef), - truncate(Fname, HeadSize - 10), - %% a new file is created ('tooshort') - {ok, TabRef} = dets:open_file(TabRef, - [{file,Fname},{version,V}, - {min_no_slots,1000}, - {max_no_slots,1000000}]), - case dets:info(TabRef, no_slots) of - undefined -> ok; - {Min1,Slot1,Max1} -> - true = Min1 =< Slot1, true = Slot1 =< Max1, - true = 1000 < Min1, true = 1000+256 > Min1, - true = 1000000 < Max1, true = (1 bsl 20)+256 > Max1 - end, - 0 = dets:info(TabRef, size), - no_keys_test(TabRef), - _ = histogram(TabRef, silent), - ok = dets:close(TabRef), file:delete(Fname), %% version bump (v8) @@ -3925,6 +3912,7 @@ otp_11709(doc) -> otp_11709(suite) -> []; otp_11709(Config) when is_list(Config) -> + Short = <<"foo">>, Long = <<"a sufficiently long text">>, %% Bug: leaking file descriptor @@ -3934,7 +3922,31 @@ otp_11709(Config) when is_list(Config) -> false = dets:is_dets_file(File), check_pps(P0), - file:delete(File), + %% Bug: deleting file + Args = [[{access, A}, {repair, R}] || + A <- [read, read_write], + R <- [true, false, force]], + Fun1 = fun(S, As) -> + P1 = pps(), + ok = file:write_file(File, S), + {error,{not_a_dets_file,File}} = dets:open_file(File, As), + {ok, S} = file:read_file(File), + check_pps(P1) + end, + Fun2 = fun(S) -> + _ = [Fun1(S, As) || As <- Args], + ok + end, + ok = Fun2(Long), % no change here + ok = Fun2(Short), % mimic the behaviour for longer files + + %% open_file/1 + ok = file:write_file(File, Long), + {error,{not_a_dets_file,File}} = dets:open_file(File), % no change + ok = file:write_file(File, Short), + {error,{not_a_dets_file,File}} = dets:open_file(File), % mimic + + _ = file:delete(File), ok. %% |