aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/doc/src/code.xml13
-rw-r--r--lib/kernel/doc/src/file.xml7
-rw-r--r--lib/kernel/src/application_controller.erl6
-rw-r--r--lib/kernel/src/code.erl6
-rw-r--r--lib/kernel/src/code_server.erl3
-rw-r--r--lib/kernel/src/file.erl33
-rw-r--r--lib/kernel/src/file_server.erl4
-rw-r--r--lib/kernel/test/code_SUITE.erl9
-rw-r--r--lib/kernel/test/file_SUITE.erl42
-rw-r--r--lib/kernel/test/file_name_SUITE.erl11
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl45
11 files changed, 148 insertions, 31 deletions
diff --git a/lib/kernel/doc/src/code.xml b/lib/kernel/doc/src/code.xml
index 279c7558bc..dbcf376487 100644
--- a/lib/kernel/doc/src/code.xml
+++ b/lib/kernel/doc/src/code.xml
@@ -738,6 +738,19 @@ rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
<c>undefined</c>.</p>
</desc>
</func>
+
+ <func>
+ <name name="get_mode" arity="0"/>
+ <fsummary>The code_server's mode.</fsummary>
+ <desc>
+ <p>This function returns an atom describing the code_server's mode:
+ <c>interactive</c> or <c>embedded</c>. </p>
+ <p>This information is useful when an external entity (for example,
+ an IDE) provides additional code for a running node. If in interactive
+ mode, it only needs to add to the code path. If in embedded mode,
+ the code has to be loaded with <c>load_binary/3</c></p>
+ </desc>
+ </func>
</funcs>
</erlref>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 4a9b7d2ceb..069b13eacf 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -110,6 +110,9 @@
<name name="filename"/>
</datatype>
<datatype>
+ <name name="filename_all"/>
+ </datatype>
+ <datatype>
<name name="io_device"/>
<desc>
<p>As returned by
@@ -156,9 +159,6 @@
<datatype>
<name name="file_info_option"/>
</datatype>
- <datatype>
- <name name="sendfile_option"/>
- </datatype>
</datatypes>
<funcs>
@@ -1648,6 +1648,7 @@
<func>
<name name="sendfile" arity="5"/>
<fsummary>send a file to a socket</fsummary>
+ <type name="sendfile_option"/>
<desc>
<p>Sends <c>Bytes</c> from the file
referenced by <c>RawFile</c> beginning at <c>Offset</c> to
diff --git a/lib/kernel/src/application_controller.erl b/lib/kernel/src/application_controller.erl
index 3c860af48e..9ed2c7a7d9 100644
--- a/lib/kernel/src/application_controller.erl
+++ b/lib/kernel/src/application_controller.erl
@@ -495,6 +495,8 @@ init(Init, Kernel) ->
{'EXIT', LoadError} ->
Reason = {'load error', LoadError},
Init ! {ack, self(), {error, to_string(Reason)}};
+ {error, Error} ->
+ Init ! {ack, self(), {error, to_string(Error)}};
{ok, NewS} ->
Init ! {ack, self(), ok},
gen_server:enter_loop(?MODULE, [], NewS,
@@ -1447,7 +1449,7 @@ prim_consult(FullName) ->
{ok, Bin, _} ->
case file_binary_to_list(Bin) of
{ok, String} ->
- case erl_scan:string(String, 1, [unicode]) of
+ case erl_scan:string(String) of
{ok, Tokens, _EndLine} ->
prim_parse(Tokens, []);
{error, Reason, _EndLine} ->
@@ -1600,7 +1602,7 @@ conv(_) -> [].
%%% Fix some day: eliminate the duplicated code here
make_term(Str) ->
- case erl_scan:string(Str, 1, [unicode]) of
+ case erl_scan:string(Str) of
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens ++ [{dot, 1}]) of
{ok, Term} ->
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 8a543abd6f..03fba96d4b 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -64,7 +64,8 @@
where_is_file/1,
where_is_file/2,
set_primary_archive/4,
- clash/0]).
+ clash/0,
+ get_mode/0]).
-export_type([load_error_rsn/0, load_ret/0]).
@@ -293,6 +294,9 @@ replace_path(Name, Dir) when (is_atom(Name) orelse is_list(Name)),
-spec rehash() -> 'ok'.
rehash() -> call(rehash).
+-spec get_mode() -> 'embedded' | 'interactive'.
+get_mode() -> call(get_mode).
+
%%-----------------------------------------------------------------
call(Req) ->
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index b770fce887..5d74e8620b 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -422,6 +422,9 @@ handle_call({is_cached,File}, {_From,_Tag}, S=#state{cache=Cache}) ->
end
end;
+handle_call(get_mode, {_From,_Tag}, S=#state{mode=Mode}) ->
+ {reply, Mode, S};
+
handle_call(Other,{_From,_Tag}, S) ->
error_msg(" ** Codeserver*** ignoring ~w~n ",[Other]),
{noreply,S}.
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 70c4583ad2..5f52f94270 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -27,12 +27,12 @@
-export([format_error/1]).
%% File system and metadata.
-export([get_cwd/0, get_cwd/1, set_cwd/1, delete/1, rename/2,
- make_dir/1, del_dir/1, list_dir/1,
+ make_dir/1, del_dir/1, list_dir/1, list_dir_all/1,
read_file_info/1, read_file_info/2,
write_file_info/2, write_file_info/3,
altname/1,
read_link_info/1, read_link_info/2,
- read_link/1,
+ read_link/1, read_link_all/1,
make_link/2, make_symlink/2,
read_file/1, write_file/2, write_file/3]).
%% Specialized
@@ -67,8 +67,8 @@
-export([ipread_s32bu_p32bu_int/3]).
%% Types that can be used from other modules -- alphabetically ordered.
--export_type([date_time/0, fd/0, file_info/0, filename/0, io_device/0,
- name/0, posix/0]).
+-export_type([date_time/0, fd/0, file_info/0, filename/0, filename_all/0,
+ io_device/0, name/0, posix/0]).
%%% Includes and defines
-include("file.hrl").
@@ -80,7 +80,8 @@
-define(RAM_FILE, ram_file). % Module
%% data types
--type filename() :: string() | binary().
+-type filename() :: string().
+-type filename_all() :: string() | binary().
-type file_info() :: #file_info{}.
-type fd() :: #file_descriptor{}.
-type io_device() :: pid() | fd().
@@ -278,6 +279,14 @@ read_link_info(Name, Opts) when is_list(Opts) ->
read_link(Name) ->
check_and_call(read_link, [file_name(Name)]).
+-spec read_link_all(Name) -> {ok, Filename} | {error, Reason} when
+ Name :: name(),
+ Filename :: filename_all(),
+ Reason :: posix() | badarg.
+
+read_link_all(Name) ->
+ check_and_call(read_link_all, [file_name(Name)]).
+
-spec write_file_info(Filename, FileInfo) -> ok | {error, Reason} when
Filename :: name(),
FileInfo :: file_info(),
@@ -303,6 +312,14 @@ write_file_info(Name, Info = #file_info{}, Opts) when is_list(Opts) ->
list_dir(Name) ->
check_and_call(list_dir, [file_name(Name)]).
+-spec list_dir_all(Dir) -> {ok, Filenames} | {error, Reason} when
+ Dir :: name(),
+ Filenames :: [filename_all()],
+ Reason :: posix() | badarg.
+
+list_dir_all(Name) ->
+ check_and_call(list_dir_all, [file_name(Name)]).
+
-spec read_file(Filename) -> {ok, Binary} | {error, Reason} when
Filename :: name(),
Binary :: binary(),
@@ -1196,7 +1213,7 @@ change_time(Name, {{AY, AM, AD}, {AH, AMin, ASec}}=Atime,
-spec sendfile(RawFile, Socket, Offset, Bytes, Opts) ->
{'ok', non_neg_integer()} | {'error', inet:posix() |
closed | badarg | not_owner} when
- RawFile :: file:fd(),
+ RawFile :: fd(),
Socket :: inet:socket(),
Offset :: non_neg_integer(),
Bytes :: non_neg_integer(),
@@ -1222,7 +1239,7 @@ sendfile(File, Sock, Offset, Bytes, Opts) ->
-spec sendfile(Filename, Socket) ->
{'ok', non_neg_integer()} | {'error', inet:posix() |
closed | badarg | not_owner}
- when Filename :: file:name(),
+ when Filename :: name(),
Socket :: inet:socket().
sendfile(Filename, Sock) ->
case file:open(Filename, [read, raw, binary]) of
@@ -1345,7 +1362,7 @@ eval_stream(Fd, Handling, Bs) ->
eval_stream(Fd, Handling, 1, undefined, [], Bs).
eval_stream(Fd, H, Line, Last, E, Bs) ->
- eval_stream2(io:parse_erl_exprs(Fd, '', Line, [unicode]), Fd, H, Last, E, Bs).
+ eval_stream2(io:parse_erl_exprs(Fd, '', Line), Fd, H, Last, E, Bs).
eval_stream2({ok,Form,EndLine}, Fd, H, Last, E, Bs0) ->
try erl_eval:exprs(Form, Bs0) of
diff --git a/lib/kernel/src/file_server.erl b/lib/kernel/src/file_server.erl
index fc6cd823c9..73202319b9 100644
--- a/lib/kernel/src/file_server.erl
+++ b/lib/kernel/src/file_server.erl
@@ -136,6 +136,8 @@ handle_call({del_dir, Name}, _From, Handle) ->
handle_call({list_dir, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:list_dir(Handle, Name), Handle};
+handle_call({list_dir_all, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:list_dir_all(Handle, Name), Handle};
handle_call(get_cwd, _From, Handle) ->
{reply, ?PRIM_FILE:get_cwd(Handle), Handle};
@@ -167,6 +169,8 @@ handle_call({read_link_info, Name, Opts}, _From, Handle) ->
handle_call({read_link, Name}, _From, Handle) ->
{reply, ?PRIM_FILE:read_link(Handle, Name), Handle};
+handle_call({read_link_all, Name}, _From, Handle) ->
+ {reply, ?PRIM_FILE:read_link(Handle, Name), Handle};
handle_call({make_link, Old, New}, _From, Handle) ->
{reply, ?PRIM_FILE:make_link(Handle, Old, New), Handle};
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index d7424c0c9a..4c040f0a0e 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -33,7 +33,7 @@
purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1,
code_archive/1, code_archive2/1, on_load/1, on_load_binary/1,
on_load_embedded/1, on_load_errors/1, big_boot_embedded/1,
- native_early_modules/1]).
+ native_early_modules/1, get_mode/1]).
-export([init_per_testcase/2, end_per_testcase/2,
init_per_suite/1, end_per_suite/1,
@@ -60,7 +60,7 @@ all() ->
where_is_file_cached, purge_stacktrace, mult_lib_roots,
bad_erl_libs, code_archive, code_archive2, on_load,
on_load_binary, on_load_embedded, on_load_errors,
- big_boot_embedded, native_early_modules].
+ big_boot_embedded, native_early_modules, get_mode].
groups() ->
[].
@@ -1594,6 +1594,11 @@ native_early_modules_1(Architecture) ->
ok
end.
+get_mode(suite) -> [];
+get_mode(doc) -> ["Test that the mode of the code server is properly retrieved"];
+get_mode(Config) when is_list(Config) ->
+ interactive = code:get_mode().
+
%%-----------------------------------------------------------------
%% error_logger handler.
%% (Copied from stdlib/test/proc_lib_SUITE.erl.)
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index ac991b1111..fd4d5bd24e 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -45,6 +45,7 @@
init_per_testcase/2, end_per_testcase/2,
read_write_file/1, names/1]).
-export([cur_dir_0/1, cur_dir_1/1, make_del_dir/1,
+ list_dir/1,list_dir_error/1,
pos1/1, pos2/1]).
-export([close/1, consult1/1, path_consult/1, delete/1]).
-export([ eval1/1, path_eval/1, script1/1, path_script/1,
@@ -115,7 +116,8 @@ all() ->
read_line_4, standard_io].
groups() ->
- [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1]},
+ [{dirs, [], [make_del_dir, cur_dir_0, cur_dir_1,
+ list_dir, list_dir_error]},
{files, [],
[{group, open}, {group, pos}, {group, file_info},
{group, consult}, {group, eval}, {group, script},
@@ -519,6 +521,42 @@ win_cur_dir_1(_Config) ->
ok.
+
+%%%
+%%% Test list_dir() on a non-existing pathname.
+%%%
+
+list_dir_error(Config) ->
+ Priv = ?config(priv_dir, Config),
+ NonExisting = filename:join(Priv, "non-existing-dir"),
+ {error,enoent} = ?FILE_MODULE:list_dir(NonExisting),
+ ok.
+
+%%%
+%%% Test list_dir() and list_dir_all().
+%%%
+
+list_dir(Config) ->
+ RootDir = ?config(priv_dir, Config),
+ TestDir = filename:join(RootDir, ?MODULE_STRING++"_list_dir"),
+ ?FILE_MODULE:make_dir(TestDir),
+ list_dir_1(TestDir, 42, []).
+
+list_dir_1(TestDir, 0, Sorted) ->
+ [ok = ?FILE_MODULE:delete(filename:join(TestDir, F)) ||
+ F <- Sorted],
+ ok = ?FILE_MODULE:del_dir(TestDir);
+list_dir_1(TestDir, Cnt, Sorted0) ->
+ Base = "file" ++ integer_to_list(Cnt),
+ Name = filename:join(TestDir, Base),
+ ok = ?FILE_MODULE:write_file(Name, Base),
+ Sorted = lists:merge([Base], Sorted0),
+ {ok,DirList0} = ?FILE_MODULE:list_dir(TestDir),
+ {ok,DirList1} = ?FILE_MODULE:list_dir_all(TestDir),
+ Sorted = lists:sort(DirList0),
+ Sorted = lists:sort(DirList1),
+ list_dir_1(TestDir, Cnt-1, Sorted).
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2453,6 +2491,7 @@ symlinks(suite) -> [];
symlinks(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(10)),
?line {error, _} = ?FILE_MODULE:read_link(lists:duplicate(10000,$a)),
+ {error, _} = ?FILE_MODULE:read_link_all(lists:duplicate(10000,$a)),
?line RootDir = ?config(priv_dir, Config),
?line NewDir = filename:join(RootDir,
atom_to_list(?MODULE)
@@ -2476,6 +2515,7 @@ symlinks(Config) when is_list(Config) ->
?line {ok, Info2} = ?FILE_MODULE:read_link_info(Alias),
?line #file_info{links=1, type=symlink} = Info2,
?line {ok, Name} = ?FILE_MODULE:read_link(Alias),
+ {ok, Name} = ?FILE_MODULE:read_link_all(Alias),
ok
end,
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 40bde8a736..e8529db1dc 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -575,17 +575,6 @@ check_very_icky(Mod) ->
end,
?line {NumOK,NumNOK} = filelib:fold_files(".",".*",true,fun(_F,{N,M}) when is_list(_F) -> io:format("~ts~n",[_F]),{N+1,M}; (_F,{N,M}) -> io:format("~p~n",[_F]),{N,M+1} end,{0,0}),
?line ok = filelib:fold_files(".",[1076,1089,1072,124,46,42],true,fun(_F,_) -> ok end,false),
- ?line SF3 = unicode:characters_to_binary("åäösubfil3",
- file:native_name_encoding()),
- ?line SF2 = case treat_icky(<<"åäösubfil2">>) of
- LF2 when is_list(LF2) ->
- unicode:characters_to_binary(LF2,
- file:native_name_encoding());
- BF2 ->
- BF2
- end,
- ?line Sorted = lists:sort([SF3,SF2]),
- ?line Sorted = lists:sort(filelib:wildcard("*",<<"åäösubdir2">>)),
ok
catch
throw:need_unicode_mode ->
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 4e93a593b3..4550cb1770 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -49,7 +49,9 @@
make_link_a/1, make_link_b/1,
read_link_info_for_non_link/1,
symlinks_a/1, symlinks_b/1,
- list_dir_limit/1]).
+ list_dir_limit/1,
+ list_dir_error/1,
+ list_dir/1]).
-export([advise/1]).
-export([large_write/1]).
@@ -81,7 +83,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[read_write_file, {group, dirs}, {group, files},
delete_a, delete_b, rename_a, rename_b, {group, errors},
- {group, compression}, {group, links}, list_dir_limit].
+ {group, compression}, {group, links}, list_dir_limit, list_dir].
groups() ->
[{dirs, [],
@@ -110,7 +112,7 @@ groups() ->
write_compressed, compress_errors]},
{links, [],
[make_link_a, make_link_b, read_link_info_for_non_link,
- symlinks_a, symlinks_b]}].
+ symlinks_a, symlinks_b, list_dir_error]}].
init_per_group(_GroupName, Config) ->
Config.
@@ -2035,6 +2037,8 @@ symlinks(Config, Handle, Suffix) ->
?line #file_info{links=1, type=symlink} = Info2,
?line {ok, Name} =
?PRIM_FILE_call(read_link, Handle, [Alias]),
+ {ok, Name} =
+ ?PRIM_FILE_call(read_link_all, Handle, [Alias]),
ok
end,
@@ -2140,6 +2144,41 @@ list_dir_limit_cleanup(Dir, Handle, N, Cnt) ->
list_dir_limit_cleanup(Dir, Handle, N, Cnt+1).
%%%
+%%% Test list_dir() on a non-existing pathname.
+%%%
+
+list_dir_error(Config) ->
+ Priv = ?config(priv_dir, Config),
+ NonExisting = filename:join(Priv, "non-existing-dir"),
+ {error,enoent} = prim_file:list_dir(NonExisting),
+ ok.
+
+%%%
+%%% Test list_dir() and list_dir_all().
+%%%
+
+list_dir(Config) ->
+ RootDir = ?config(priv_dir, Config),
+ TestDir = filename:join(RootDir, ?MODULE_STRING++"_list_dir"),
+ ?PRIM_FILE:make_dir(TestDir),
+ list_dir_1(TestDir, 42, []).
+
+list_dir_1(TestDir, 0, Sorted) ->
+ [ok = ?PRIM_FILE:delete(filename:join(TestDir, F)) ||
+ F <- Sorted],
+ ok = ?PRIM_FILE:del_dir(TestDir);
+list_dir_1(TestDir, Cnt, Sorted0) ->
+ Base = "file" ++ integer_to_list(Cnt),
+ Name = filename:join(TestDir, Base),
+ ok = ?PRIM_FILE:write_file(Name, Base),
+ Sorted = lists:merge([Base], Sorted0),
+ {ok,DirList0} = ?PRIM_FILE:list_dir(TestDir),
+ {ok,DirList1} = ?PRIM_FILE:list_dir_all(TestDir),
+ Sorted = lists:sort(DirList0),
+ Sorted = lists:sort(DirList1),
+ list_dir_1(TestDir, Cnt-1, Sorted).
+
+%%%
%%% Support for testing large files.
%%%