aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-04-09 16:30:49 +0200
committerBjörn Gustavsson <[email protected]>2014-05-08 14:26:27 +0200
commitbb2b84c35e75ae80174ef54dad7babf6c6fa9075 (patch)
tree6d108ff7075cd594b4529a7c0f7c38c2f4833e63
parent61138cb31e1f6ad44d3ca54e668de9d2d4adb2ec (diff)
downloadotp-bb2b84c35e75ae80174ef54dad7babf6c6fa9075.tar.gz
otp-bb2b84c35e75ae80174ef54dad7babf6c6fa9075.tar.bz2
otp-bb2b84c35e75ae80174ef54dad7babf6c6fa9075.zip
Correct end of tape marker
The POSIX standard for tar says that there must be at least two 512-bytes zero blocks at the end of the tar archive file. Our implementation would only emit a single 512-byte zero block if the size of the last file was in the range 18*512 through 19*512-1 (modulo 20*512). GNU tar would correctly unpack such tar archive file, but would emit a warning: tar: A lone zero block at 20
-rw-r--r--lib/stdlib/src/erl_tar.erl14
-rw-r--r--lib/stdlib/test/tar_SUITE.erl1
2 files changed, 12 insertions, 3 deletions
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index 89b4ea6c04..acf7a5cd40 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -397,9 +397,17 @@ to_string(Str0, Count) ->
pad_file(File) ->
{ok,Position} = file:position(File, {cur,0}),
- %% There must be at least one empty record at the end of the file.
- Zeros = zeroes(?block_size - (Position rem ?block_size)),
- file:write(File, Zeros).
+ %% There must be at least two zero records at the end.
+ Fill = case ?block_size - (Position rem ?block_size) of
+ Fill0 when Fill0 < 2*?record_size ->
+ %% We need to another block here to ensure that there
+ %% are at least two zero records at the end.
+ Fill0 + ?block_size;
+ Fill0 ->
+ %% Large enough.
+ Fill0
+ end,
+ file:write(File, zeroes(Fill)).
split_filename(Name) when length(Name) =< ?th_name_len ->
{"", Name};
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 297f5b161a..6349139925 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -73,6 +73,7 @@ borderline(Config) when is_list(Config) ->
?line lists:foreach(fun(Size) -> borderline_test(Size, TempDir) end,
[0, 1, 10, 13, 127, 333, Record-1, Record, Record+1,
+ Block-2*Record-1, Block-2*Record, Block-2*Record+1,
Block-Record-1, Block-Record, Block-Record+1,
Block-1, Block, Block+1,
Block+Record-1, Block+Record, Block+Record+1]),