From de2fb97f15ac98aa1d1c5533aacca378334f4778 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 1 Jul 2014 00:58:26 +0200 Subject: Fix handling of broken symlinks in filelib This fixes a bug introduced in f11aabdc9fec593c31e6c4f3fa25c1707e9c35df where filelib:eval_read_file_info/2 was made to use file:read_link_info/1 to never follow symlinks. This fixed wildcard/1 but broke every other function using eval_read_file_info/2. Reported-by: Louis-Philippe Gauthier Reported-by: Danil Zagoskin --- lib/kernel/src/erl_boot_server.erl | 6 +++++- lib/stdlib/src/filelib.erl | 14 ++++++++++++-- lib/stdlib/test/filelib_SUITE.erl | 25 +++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/erl_boot_server.erl b/lib/kernel/src/erl_boot_server.erl index 9a49655a9f..ef09d86ca4 100644 --- a/lib/kernel/src/erl_boot_server.erl +++ b/lib/kernel/src/erl_boot_server.erl @@ -341,9 +341,13 @@ handle_command(S, PS, Msg) -> send_file_result(S, list_dir, Res), PS2; {read_file_info,File} -> - {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File), + {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File, true), send_file_result(S, read_file_info, Res), PS2; + {read_link_info,File} -> + {Res, PS2} = erl_prim_loader:prim_read_file_info(PS, File, false), + send_file_result(S, read_link_info, Res), + PS2; get_cwd -> {Res, PS2} = erl_prim_loader:prim_get_cwd(PS, []), send_file_result(S, get_cwd, Res), diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index c0921e4cf1..9efbe8da20 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -265,7 +265,7 @@ do_wildcard(Pattern, Cwd, Mod) -> lists:sort(Files). do_wildcard_1({exists,File}, Mod) -> - case eval_read_file_info(File, Mod) of + case eval_read_link_info(File, Mod) of {ok,_} -> [File]; _ -> [] end; @@ -488,7 +488,7 @@ badpattern(Reason) -> error({badpattern,Reason}). eval_read_file_info(File, file) -> - file:read_link_info(File); + file:read_file_info(File); eval_read_file_info(File, erl_prim_loader) -> case erl_prim_loader:read_file_info(File) of error -> {error, erl_prim_loader}; @@ -497,6 +497,16 @@ eval_read_file_info(File, erl_prim_loader) -> eval_read_file_info(File, Mod) -> Mod:read_file_info(File). +eval_read_link_info(File, file) -> + file:read_link_info(File); +eval_read_link_info(File, erl_prim_loader) -> + case erl_prim_loader:read_link_info(File) of + error -> {error, erl_prim_loader}; + Res-> Res + end; +eval_read_link_info(File, Mod) -> + Mod:read_link_info(File). + eval_list_dir(Dir, file) -> file:list_dir(Dir); eval_list_dir(Dir, erl_prim_loader) -> diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index 8203a03a7a..f1a072194a 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -23,7 +23,8 @@ init_per_group/2,end_per_group/2, init_per_testcase/2,end_per_testcase/2, wildcard_one/1,wildcard_two/1,wildcard_errors/1, - fold_files/1,otp_5960/1,ensure_dir_eexist/1,symlinks/1]). + fold_files/1,otp_5960/1,ensure_dir_eexist/1,ensure_dir_symlink/1, + symlinks/1]). -import(lists, [foreach/2]). @@ -43,7 +44,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [wildcard_one, wildcard_two, wildcard_errors, - fold_files, otp_5960, ensure_dir_eexist, symlinks]. + fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink, symlinks]. groups() -> []. @@ -367,6 +368,26 @@ ensure_dir_eexist(Config) when is_list(Config) -> ?line {error, eexist} = filelib:ensure_dir(NeedFileB), ok. +ensure_dir_symlink(Config) when is_list(Config) -> + PrivDir = ?config(priv_dir, Config), + Dir = filename:join(PrivDir, "ensure_dir_symlink"), + Name = filename:join(Dir, "same_name_as_file_and_dir"), + ok = filelib:ensure_dir(Name), + ok = file:write_file(Name, <<"some string\n">>), + %% With a symlink to the directory. + Symlink = filename:join(PrivDir, "ensure_dir_symlink_link"), + case file:make_symlink(Dir, Symlink) of + {error,enotsup} -> + {skip,"Symlinks not supported on this platform"}; + {error,eperm} -> + {win32,_} = os:type(), + {skip,"Windows user not privileged to create symlinks"}; + ok -> + SymlinkedName = filename:join(Symlink, "same_name_as_file_and_dir"), + ok = filelib:ensure_dir(SymlinkedName) + end. + + symlinks(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), Dir = filename:join(PrivDir, ?MODULE_STRING++"_symlinks"), -- cgit v1.2.3 From 9dc807376b0dff43a19af5ef4301333f16cc11c1 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Mon, 7 Jul 2014 15:45:36 +0200 Subject: Add tests of filelib and symlinks This commit complements 769996c0cd4cb68c157e39de725642f209ed7423 and adds tests for the following problems introduced by f11aabdc9fec593c31e6c4f3fa25c1707e9c35df: Given the symlink 'dirlink' pointing to an existing dir, then - filelib:is_regular("dirlink") -> false - filelib:is_dir("dirlink") -> false Given the symlink 'filelink' pointing to an existing file, then - filelib:is_regular("filelink") -> false - filelib:is_file("filelink") -> false - filelib:last_modified("filelink") and filelib:filesize("filelink") return the info of the link and not the file Given the symlink "broken_symlink" pointing to a non-existing file, then - filelib:wildcard("broken_symlink",File) -> [] --- lib/kernel/test/erl_prim_loader_SUITE.erl | 26 ++++++++- lib/stdlib/test/filelib_SUITE.erl | 93 +++++++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl index b2ca3bdbc2..658c31c14d 100644 --- a/lib/kernel/test/erl_prim_loader_SUITE.erl +++ b/lib/kernel/test/erl_prim_loader_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -328,6 +328,30 @@ file_requests(Config) when is_list(Config) -> {ok,Info} = file:read_file_info(code:which(test_server)), ?line {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info, [code:which(test_server)]), + + PrivDir = ?config(priv_dir,Config), + Dir = filename:join(PrivDir,?MODULE_STRING++"_file_requests"), + ok = file:make_dir(Dir), + Alias = filename:join(Dir,"symlink"), + case file:make_symlink(code:which(test_server), Alias) of + {error, enotsup} -> + %% Links not supported on this platform + ok; + {error, eperm} -> + {win32,_} = os:type(), + %% Windows user not privileged to create symlinks" + ok; + ok -> + %% Reading file info for link should return file info for + %% link target + {ok,Info} = rpc:call(Node, erl_prim_loader, read_file_info, + [Alias]), + #file_info{type=regular} = Info, + {ok,#file_info{type=symlink}} = + rpc:call(Node, erl_prim_loader, read_link_info, + [Alias]) + end, + {ok,Cwd} = file:get_cwd(), ?line {ok,Cwd} = rpc:call(Node, erl_prim_loader, get_cwd, []), case file:get_cwd("C:") of diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index f1a072194a..040ae1effc 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -24,7 +24,7 @@ init_per_testcase/2,end_per_testcase/2, wildcard_one/1,wildcard_two/1,wildcard_errors/1, fold_files/1,otp_5960/1,ensure_dir_eexist/1,ensure_dir_symlink/1, - symlinks/1]). + wildcard_symlink/1, is_file_symlink/1, file_props_symlink/1]). -import(lists, [foreach/2]). @@ -44,7 +44,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [wildcard_one, wildcard_two, wildcard_errors, - fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink, symlinks]. + fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink, + wildcard_symlink, is_file_symlink, file_props_symlink]. groups() -> []. @@ -387,10 +388,9 @@ ensure_dir_symlink(Config) when is_list(Config) -> ok = filelib:ensure_dir(SymlinkedName) end. - -symlinks(Config) when is_list(Config) -> +wildcard_symlink(Config) when is_list(Config) -> PrivDir = ?config(priv_dir, Config), - Dir = filename:join(PrivDir, ?MODULE_STRING++"_symlinks"), + Dir = filename:join(PrivDir, ?MODULE_STRING++"_wildcard_symlink"), SubDir = filename:join(Dir, "sub"), AFile = filename:join(SubDir, "a_file"), Alias = filename:join(Dir, "symlink"), @@ -408,6 +408,18 @@ symlinks(Config) when is_list(Config) -> basenames(Dir, filelib:wildcard(filename:join(Dir, "*"))), ["symlink"] = basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"))), + ["sub","symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "*"), + erl_prim_loader)), + ["symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"), + erl_prim_loader)), + ["sub","symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "*"), + prim_file)), + ["symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"), + prim_file)), ok = file:delete(AFile), %% The symlink should still be visible even when its target %% has been deleted. @@ -415,6 +427,18 @@ symlinks(Config) when is_list(Config) -> basenames(Dir, filelib:wildcard(filename:join(Dir, "*"))), ["symlink"] = basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"))), + ["sub","symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "*"), + erl_prim_loader)), + ["symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"), + erl_prim_loader)), + ["sub","symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "*"), + prim_file)), + ["symlink"] = + basenames(Dir, filelib:wildcard(filename:join(Dir, "symlink"), + prim_file)), ok end. @@ -423,3 +447,60 @@ basenames(Dir, Files) -> Dir = filename:dirname(F), filename:basename(F) end || F <- Files]. + +is_file_symlink(Config) -> + PrivDir = ?config(priv_dir, Config), + Dir = filename:join(PrivDir, ?MODULE_STRING++"_is_file_symlink"), + SubDir = filename:join(Dir, "sub"), + AFile = filename:join(SubDir, "a_file"), + DirAlias = filename:join(Dir, "dir_symlink"), + FileAlias = filename:join(Dir, "file_symlink"), + ok = file:make_dir(Dir), + ok = file:make_dir(SubDir), + ok = file:write_file(AFile, "not that big\n"), + case file:make_symlink(SubDir, DirAlias) of + {error, enotsup} -> + {skip, "Links not supported on this platform"}; + {error, eperm} -> + {win32,_} = os:type(), + {skip, "Windows user not privileged to create symlinks"}; + ok -> + true = filelib:is_dir(DirAlias), + true = filelib:is_dir(DirAlias, erl_prim_loader), + true = filelib:is_dir(DirAlias, prim_file), + true = filelib:is_file(DirAlias), + true = filelib:is_file(DirAlias, erl_prim_loader), + true = filelib:is_file(DirAlias, prim_file), + ok = file:make_symlink(AFile,FileAlias), + true = filelib:is_file(FileAlias), + true = filelib:is_file(FileAlias, erl_prim_loader), + true = filelib:is_file(FileAlias, prim_file), + true = filelib:is_regular(FileAlias), + true = filelib:is_regular(FileAlias, erl_prim_loader), + true = filelib:is_regular(FileAlias, prim_file), + ok + end. + +file_props_symlink(Config) -> + PrivDir = ?config(priv_dir, Config), + Dir = filename:join(PrivDir, ?MODULE_STRING++"_file_props_symlink"), + AFile = filename:join(Dir, "a_file"), + Alias = filename:join(Dir, "symlink"), + ok = file:make_dir(Dir), + ok = file:write_file(AFile, "not that big\n"), + case file:make_symlink(AFile, Alias) of + {error, enotsup} -> + {skip, "Links not supported on this platform"}; + {error, eperm} -> + {win32,_} = os:type(), + {skip, "Windows user not privileged to create symlinks"}; + ok -> + {_,_} = LastMod = filelib:last_modified(AFile), + LastMod = filelib:last_modified(Alias), + LastMod = filelib:last_modified(Alias, erl_prim_loader), + LastMod = filelib:last_modified(Alias, prim_file), + FileSize = filelib:file_size(AFile), + FileSize = filelib:file_size(Alias), + FileSize = filelib:file_size(Alias, erl_prim_loader), + FileSize = filelib:file_size(Alias, prim_file) + end. -- cgit v1.2.3 From 4182a479c2ae47d097c2b4f18a6a2a47020a5bca Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Wed, 9 Jul 2014 15:15:48 +0200 Subject: Update runtime dependencies --- lib/kernel/src/kernel.app.src | 2 +- lib/stdlib/src/stdlib.app.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src index 5658c6b6cf..9f6c0f4624 100644 --- a/lib/kernel/src/kernel.app.src +++ b/lib/kernel/src/kernel.app.src @@ -115,6 +115,6 @@ {applications, []}, {env, [{error_logger, tty}]}, {mod, {kernel, []}}, - {runtime_dependencies, ["erts-6.0", "stdlib-2.0", "sasl-2.4"]} + {runtime_dependencies, ["erts-6.1.2", "stdlib-2.0", "sasl-2.4"]} ] }. diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index d388410de0..3585eec342 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -103,7 +103,7 @@ dets]}, {applications, [kernel]}, {env, []}, - {runtime_dependencies, ["sasl-2.4","kernel-3.0","erts-6.0","crypto-3.3", + {runtime_dependencies, ["sasl-2.4","kernel-3.0.2","erts-6.1.2","crypto-3.3", "compiler-5.0"]} ]}. -- cgit v1.2.3 From ab5afc3d8cbd0211fef7c9c71edc2708f643f705 Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Thu, 10 Jul 2014 10:43:04 +0200 Subject: Update stdlib appup file Allow upgrade from OTP 17.1 to newer. --- lib/stdlib/src/stdlib.appup.src | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/src/stdlib.appup.src b/lib/stdlib/src/stdlib.appup.src index 22eefb2514..99d9b8b431 100644 --- a/lib/stdlib/src/stdlib.appup.src +++ b/lib/stdlib/src/stdlib.appup.src @@ -17,9 +17,11 @@ %% %CopyrightEnd% {"%VSN%", %% Up from - max one major revision back - [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17 + [{<<"2\\.1(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1 + {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0 {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}],%% R16 %% Down to - max one major revision back - [{<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% R17 + [{<<"2\\.1(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.1 + {<<"2\\.0(\\.[0-9]+)*">>,[restart_new_emulator]}, %% 17.0 {<<"1\\.19(\\.[0-9]+)*">>,[restart_new_emulator]}] %% R16 }. -- cgit v1.2.3 From 41d2dc56d5d2a3be1ba59c6999e1003360b1e308 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 10 Jul 2014 10:45:27 +0200 Subject: Prepare release --- lib/kernel/doc/src/notes.xml | 19 +++++++++++++++++++ lib/kernel/vsn.mk | 2 +- lib/stdlib/doc/src/notes.xml | 19 +++++++++++++++++++ lib/stdlib/vsn.mk | 2 +- 4 files changed, 40 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 3a8de841d0..35889f9d11 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,25 @@

This document describes the changes made to the Kernel application.

+
Kernel 3.0.2 + +
Fixed Bugs and Malfunctions + + +

+ OTP-11850 fixed filelib:wildcard/1 to work with broken + symlinks. This correction, however, introduced problems + since symlinks were no longer followed for functions like + filelib:ensure_dir/1, filelib:is_dir/1, + filelib:file_size/1, etc. This is now corrected.

+

+ Own Id: OTP-12054 Aux Id: seq12660

+
+
+
+ +
+
Kernel 3.0.1
Fixed Bugs and Malfunctions diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index aebe28655e..1ecfde190e 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 3.0.1 +KERNEL_VSN = 3.0.2 diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index 0421d560b6..5e74616099 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -30,6 +30,25 @@

This document describes the changes made to the STDLIB application.

+
STDLIB 2.1.1 + +
Fixed Bugs and Malfunctions + + +

+ OTP-11850 fixed filelib:wildcard/1 to work with broken + symlinks. This correction, however, introduced problems + since symlinks were no longer followed for functions like + filelib:ensure_dir/1, filelib:is_dir/1, + filelib:file_size/1, etc. This is now corrected.

+

+ Own Id: OTP-12054 Aux Id: seq12660

+
+
+
+ +
+
STDLIB 2.1
Fixed Bugs and Malfunctions diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 52ed78c557..9881ab040e 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 2.1 +STDLIB_VSN = 2.1.1 -- cgit v1.2.3