diff options
author | Hans Bolinder <[email protected]> | 2013-04-30 10:19:45 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2013-05-06 12:14:14 +0200 |
commit | 9e75f186c50071557d1846cf7267edfc942acdfb (patch) | |
tree | 320988c91d6600f17628e6c3a073a5387b399fdd /lib/stdlib/test | |
parent | fa6ce2d4653bd7955c8c478a143119dbdd6b9d06 (diff) | |
download | otp-9e75f186c50071557d1846cf7267edfc942acdfb.tar.gz otp-9e75f186c50071557d1846cf7267edfc942acdfb.tar.bz2 otp-9e75f186c50071557d1846cf7267edfc942acdfb.zip |
Fix a minor bug in ets:tabfile_info() and ets:file2tab()
Certain error conditions could leave an open file descriptor.
Diffstat (limited to 'lib/stdlib/test')
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index af5d5a8f21..432ab19423 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -33,7 +33,7 @@ -export([ match1/1, match2/1, match_object/1, match_object2/1]). -export([ dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]). -export([ tab2file/1, tab2file2/1, tabfile_ext1/1, - tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1]). + tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1, badfile/1]). -export([ heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]). -export([ lookup_element_mult/1]). -export([]). @@ -168,7 +168,7 @@ groups() -> [misc1, safe_fixtable, info, dups, tab2list]}, {files, [], [tab2file, tab2file2, tabfile_ext1, - tabfile_ext2, tabfile_ext3, tabfile_ext4]}, + tabfile_ext2, tabfile_ext3, tabfile_ext4, badfile]}, {heavy, [], [heavy_lookup, heavy_lookup_element, heavy_concurrent]}, {fold, [], @@ -4178,7 +4178,56 @@ tabfile_ext4(Config) when is_list(Config) -> file:delete(FName), ok. +badfile(suite) -> + []; +badfile(doc) -> + ["Tests that no disk_log is left open when file has been corrupted"]; +badfile(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir,Config), + File = filename:join(PrivDir, "badfile"), + _ = file:delete(File), + T = ets:new(table, []), + true = ets:insert(T, [{a,1},{b,2}]), + ok = ets:tab2file(T, File, []), + true = ets:delete(T), + [H0 | Ts ] = get_all_terms(l, File), + H1 = tuple_to_list(H0), + H2 = [{K,V} || {K,V} <- H1, K =/= protection], + H = list_to_tuple(H2), + ok = file:delete(File), + write_terms(l, File, [H | Ts]), + %% All mandatory keys are no longer members of the header + {error, badfile} = ets:file2tab(File), + {error, badfile} = ets:tabfile_info(File), + file:delete(File), + {[],[]} = disk_log:accessible_logs(), + ok. + +get_all_terms(Log, File) -> + {ok, Log} = disk_log:open([{name,Log}, + {file, File}, + {mode, read_only}]), + Ts = get_all_terms(Log), + ok = disk_log:close(Log), + Ts. + +get_all_terms(Log) -> + get_all_terms1(Log, start, []). + +get_all_terms1(Log, Cont, Res) -> + case disk_log:chunk(Log, Cont) of + {error, _R} -> + throw(fel); + {Cont2, Terms} -> + get_all_terms1(Log, Cont2, Res ++ Terms); + eof -> + Res + end. +write_terms(Log, File, Terms) -> + {ok, Log} = disk_log:open([{name,Log},{file, File},{mode,read_write}]), + ok = disk_log:log(Log, Terms), + ok = disk_log:close(Log). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |