aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/doc/src/Makefile1
-rw-r--r--lib/kernel/doc/src/application.xml9
-rw-r--r--lib/kernel/doc/src/error_handler.xml38
-rw-r--r--lib/kernel/doc/src/file.xml12
-rw-r--r--lib/kernel/doc/src/inet.xml5
-rw-r--r--lib/kernel/doc/src/packages.xml208
-rw-r--r--lib/kernel/doc/src/ref_man.xml1
-rw-r--r--lib/kernel/src/Makefile1
-rw-r--r--lib/kernel/src/application.erl16
-rw-r--r--lib/kernel/src/code.erl6
-rw-r--r--lib/kernel/src/code_server.erl9
-rw-r--r--lib/kernel/src/error_handler.erl53
-rw-r--r--lib/kernel/src/file.erl14
-rw-r--r--lib/kernel/src/file_io_server.erl4
-rw-r--r--lib/kernel/src/kernel.app.src1
-rw-r--r--lib/kernel/src/packages.erl158
-rw-r--r--lib/kernel/src/ram_file.erl7
-rw-r--r--lib/kernel/test/Makefile2
-rw-r--r--lib/kernel/test/application_SUITE.erl13
-rw-r--r--lib/kernel/test/error_handler_SUITE.erl68
-rw-r--r--lib/kernel/test/error_logger_warn_SUITE.erl4
-rw-r--r--lib/kernel/test/file_SUITE.erl72
-rw-r--r--lib/kernel/test/file_name_SUITE.erl165
-rw-r--r--lib/kernel/test/gen_udp_SUITE.erl5
-rw-r--r--lib/kernel/test/global_SUITE.erl35
-rw-r--r--lib/kernel/test/heart_SUITE.erl27
-rw-r--r--lib/kernel/test/ignore_cores.erl158
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl74
-rw-r--r--lib/kernel/test/ram_file_SUITE.erl17
29 files changed, 631 insertions, 552 deletions
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index 5e04bff0c1..de3ca1e176 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -58,7 +58,6 @@ XML_REF3_FILES = application.xml \
net_adm.xml \
net_kernel.xml \
os.xml \
- packages.xml \
pg2.xml \
rpc.xml \
seq_trace.xml \
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 51a3311ec2..9f19efc793 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -121,6 +121,15 @@
</desc>
</func>
<func>
+ <name name="get_env" arity="3"/>
+ <fsummary>Get the value of a configuration parameter using a default</fsummary>
+ <desc>
+ <p>Works like <seealso marker="#get_env/2">get_env/2</seealso> but returns
+ <c><anno>Def</anno></c> value when configuration parameter
+ <c><anno>Par</anno></c> does not exist.</p>
+ </desc>
+ </func>
+ <func>
<name name="get_key" arity="1"/>
<name name="get_key" arity="2"/>
<fsummary>Get the value of an application specification key</fsummary>
diff --git a/lib/kernel/doc/src/error_handler.xml b/lib/kernel/doc/src/error_handler.xml
index acbf9a2c6e..610b65f0a2 100644
--- a/lib/kernel/doc/src/error_handler.xml
+++ b/lib/kernel/doc/src/error_handler.xml
@@ -43,19 +43,39 @@
A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
</type_desc>
<desc>
- <p>This function is evaluated if a call is made to
+ <p>This function is called by the run-time system if a call is made to
<c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> and
<c><anno>Module</anno>:<anno>Function</anno>/N</c> is undefined. Note that
<c>undefined_function/3</c> is evaluated inside the process
making the original call.</p>
- <p>If <c><anno>Module</anno></c> is interpreted, the interpreter is invoked
- and the return value of the interpreted
- <c><anno>Function</anno>(Arg1,.., ArgN)</c> call is returned.</p>
- <p>Otherwise, it returns, if possible, the value of
- <c>apply(<anno>Module</anno>, <anno>Function</anno>, <anno>Args</anno>)</c> after an attempt has been
- made to autoload <c><anno>Module</anno></c>. If this is not possible, the
- call to <c><anno>Module</anno>:<anno>Function</anno>(Arg1,.., ArgN)</c> fails with
- exit reason <c>undef</c>.</p>
+
+ <p>This function will first attempt to autoload
+ <c><anno>Module</anno></c>. If that is not possible,
+ an <c>undef</c> exception will be raised.</p>
+
+ <p>If it was possible to load <c><anno>Module</anno></c>
+ and the function <c><anno>Function</anno>/N</c> is exported,
+ it will be called.</p>
+
+ <p>Otherwise, if the function <c>'$handle_undefined_function'/2</c>
+ is exported, it will be called as
+ <c>'$handle_undefined_function'(</c><anno>Function</anno>,
+ <anno>Args</anno>).
+ </p>
+ <p>Otherwise an <c>undef</c> exception will be raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name name="raise_undef_exception" arity="3"/>
+ <fsummary>Raise an undef exception</fsummary>
+ <type_desc variable="Args">
+ A (possibly empty) list of arguments <c>Arg1,..,ArgN</c>
+ </type_desc>
+ <desc>
+ <p>Raise an <c>undef</c> exception with a stacktrace indicating
+ that <c><anno>Module</anno>:<anno>Function</anno>/N</c> is
+ undefined.
+ </p>
</desc>
</func>
<func>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 536b98b5f5..e30ade1bd2 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -170,6 +170,18 @@
</desc>
</func>
<func>
+ <name name="allocate" arity="3"/>
+ <fsummary>Allocate file space</fsummary>
+ <desc>
+ <p><c>allocate/3</c> can be used to preallocate space for a file.</p>
+ <p>This function only succeeds in platforms that implement this
+ feature. When it succeeds, space is preallocated for the file but
+ the file size might not be updated. This behaviour depends on the
+ preallocation implementation. To guarantee the file size is updated
+ one must truncate the file to the new size.</p>
+ </desc>
+ </func>
+ <func>
<name name="change_group" arity="2"/>
<fsummary>Change group of a file</fsummary>
<desc>
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index a1590c2dce..3d929a772e 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -323,8 +323,11 @@ fe80::204:acff:fe17:bf38
<type name="stat_option"/>
<desc>
<p>Gets one or more statistic options for a socket.</p>
+
<p><c>getstat(<anno>Socket</anno>)</c> is equivalent to
- <c>getstat(<anno>Socket</anno>,&nbsp;[recv_avg,&nbsp;recv_cnt,&nbsp;recv_dvi,&nbsp;recv_max,&nbsp;recv_oct,&nbsp;send_avg,&nbsp;send_cnt,&nbsp;send_dvi,&nbsp;send_max,&nbsp;send_oct])</c></p>
+ <c>getstat(<anno>Socket</anno>, [recv_avg, recv_cnt, recv_dvi,
+ recv_max, recv_oct, send_avg, send_cnt, send_dvi, send_max,
+ send_oct])</c>.</p>
<p>The following options are available:</p>
<taglist>
<tag><c>recv_avg</c></tag>
diff --git a/lib/kernel/doc/src/packages.xml b/lib/kernel/doc/src/packages.xml
deleted file mode 100644
index 8a82b91a90..0000000000
--- a/lib/kernel/doc/src/packages.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE erlref SYSTEM "erlref.dtd">
-
-<erlref>
- <header>
- <copyright>
- <year>2004</year><year>2012</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- 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
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>packages</title>
- <prepared>Kenneth Lundin</prepared>
- <responsible>Kenneth Lundin</responsible>
- <docno>1</docno>
- <approved>Kenneth Lundin</approved>
- <checked></checked>
- <date>2004-09-07</date>
- <rev>A</rev>
- <file>packages.sgml</file>
- </header>
- <module>packages</module>
- <modulesummary>Packages in Erlang</modulesummary>
- <description>
- <warning><p>
- Packages has since it was introduced more than 5 years ago been an
- experimental feature. Use it at your own risk, we do not
- actively maintain and develop this feature. It might however be
- supported some
- day.
- </p>
- <p>
- In spite of this packages work quite well, but there are some
- known issues in tools and other parts where packages don't work well.
- </p>
- </warning>
- <p><em>Introduction</em></p>
- <p>Packages are simply namespaces for modules.
- All old Erlang modules automatically belong to the top level
- ("empty-string") namespace, and do not need any changes.</p>
- <p>The full name of a packaged module is written as e.g.
- "<c>fee.fie.foe.foo</c>",
- i.e., as atoms separated by periods,
- where the package name is the part up to
- but not including the last period;
- in this case "<c>fee.fie.foe</c>".
- A more concrete example is the module <c>erl.lang.term</c>,
- which is in the
- package <c>erl.lang</c>.
- Package names can have any number of segments, as in
- <c>erl.lang.list.sort</c>.
- The atoms in the name can be quoted, as in <c>foo.'Bar'.baz</c>,
- or even the
- whole name, as in <c>'foo.bar.baz'</c> but the concatenation of
- atoms and
- periods must not contain two consecutive period characters or
- end with a period,
- as in <c>'foo..bar'</c>, <c>foo.'.bar'</c>, or <c>foo.'bar.'</c>.
- The periods must not be followed by whitespace.</p>
- <p>The code loader maps module names onto the file system directory
- structure.
- E.g., the module <c>erl.lang.term</c> corresponds to a file
- <c>.../erl/lang/term.beam</c>
- in the search path.
- Note that the name of the actual object file corresponds to
- the last part only of the full module name.
- (Thus, old existing modules such as <c>lists</c>
- simply map to <c>.../lists.beam</c>, exactly as before.)</p>
- <p>A packaged module in a file "<c>foo/bar/fred.erl</c>" is declared
- as:</p>
- <code type="none">
--module(foo.bar.fred).</code>
- <p>This can be compiled and loaded from the Erlang shell using
- <c>c(fred)</c>, if
- your current directory is the same as that of the file.
- The object file will be named <c>fred.beam</c>.</p>
- <p>The Erlang search path works exactly as before,
- except that the package segments will be appended to each
- directory in the path in order to find the
- file. E.g., assume the path is <c>["/usr/lib/erl", "/usr/local/lib/otp/legacy/ebin", "/home/barney/erl"]</c>.
- Then, the code for a module named <c>foo.bar.fred</c> will be
- searched for
- first as <c>"/usr/lib/erl/foo/bar/fred.beam"</c>, then
- <c>"/usr/local/lib/otp/legacy/ebin/foo/bar/fred.beam"</c>
- and lastly <c>"/home/barney/erl/foo/bar/fred.beam"</c>.
- A module
- like <c>lists</c>, which is in the top-level package,
- will be looked for as <c>"/usr/lib/erl/lists.beam"</c>,
- <c>"/usr/local/lib/otp/legacy/ebin/lists.beam"</c> and
- <c>"/home/barney/erl/lists.beam"</c>.</p>
- <p><em>Programming</em></p>
- <p>Normally, if a call is made from one module to another,
- it is assumed that the
- called module belongs to the same package as the source module.
- The compiler
- automatically expands such calls. E.g., in:</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1]).
-
-f(X) -> m2:g(X).</code>
- <p><c>m2:g(X)</c> becomes a call to <c>foo.bar.m2</c>
- If this is not what was intended, the call can be written
- explicitly, as in</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1]).
-
-f(X) -> fee.fie.foe.m2:g(X).</code>
- <p>Because the called module is given with an explicit package name,
- no expansion is done in this case.</p>
- <p>If a module from another package is used repeatedly in a module,
- an import declaration can make life easier:</p>
- <code type="none">
--module(foo.bar.m1).
--export([f/1, g/1]).
--import(fee.fie.foe.m2).
-
-f(X) -> m2:g(X).
-g(X) -> m2:h(X).</code>
- <p>will make the calls to <c>m2</c> refer to <c>fee.fie.foe.m2</c>.
- More generally, a declaration <c>-import(Package.Module).</c>
- will cause calls to <c>Module</c>
- to be expanded to <c>Package.Module</c>.</p>
- <p>Old-style function imports work as normal (but full module
- names must be
- used); e.g.:</p>
- <code type="none">
--import(fee.fie.foe.m2, [g/1, h/1]).</code>
- <p>however, it is probably better to avoid this form of import
- altogether in new
- code, since it makes it hard to see what calls are really "remote".</p>
- <p>If it is necessary to call a module in the top-level package
- from within a
- named package, the module name can be written either with an
- initial period as
- in e.g. "<c>.lists</c>", or with an empty initial atom, as in
- "<c>''.lists</c>".
- However, the best way is to use an import declaration -
- this is most obvious to
- the eye, and makes sure we don't forget adding a period somewhere:</p>
- <code type="none">
--module(foo.bar.fred).
--export([f/1]).
--import(lists).
-
-f(X) -> lists:reverse(X).</code>
- <p>The dot-syntax for module names can be used in any expression.
- All segments must
- be constant atoms, and the result must be a well-formed
- package/module name.
- E.g.:</p>
- <code type="none">
-spawn(foo.bar.fred, f, [X])</code>
- <p>is equivalent to <c>spawn('foo.bar.fred', f, [X])</c>.</p>
- <p><em>The Erlang Shell</em></p>
- <p>The shell also automatically expands remote calls,
- however currently no
- expansions are made by default.
- The user can change the behaviour by using the <c>import/1</c>
- shell command (or its abbreviation <c>use/1</c>). E.g.:</p>
- <pre>
-1> <input>import(foo.bar.m).</input>
-ok
-2> <input>m:f().</input></pre>
- <p>will evaluate <c>foo.bar.m:f()</c>.
- If a new import is made of the same name,
- this overrides any previous import.
- (It is likely that in the future, some
- system packages will be pre-imported.)</p>
- <p>In addition, the shell command <c>import_all/1</c>
- (and its alias <c>use_all/1</c>)
- imports all modules currently found in the path for a given
- package name. E.g.,
- assuming the files "<c>.../foo/bar/fred.beam</c>",
- "<c>.../foo/bar/barney.beam</c>"
- and "<c>.../foo/bar/bambam.beam</c>" can be found from our current
- path,</p>
- <pre>
-1> <input>import_all(foo.bar).</input></pre>
- <p>will make <c>fred</c>, <c>barney</c> and <c>bambam</c>
- expand to <c>foo.bar.fred</c>,
- <c>foo.bar.barney</c> and <c>foo.bar.bambam</c>, respectively.</p>
- <p>Note: The compiler does not have an "import all" directive, for the
- reason that Erlang has no compile time type checking.
- E.g. if the wrong search
- path is used at compile time, a call <c>m:f(...)</c>
- could be expanded to <c>foo.bar.m:f(...)</c>
- without any warning, instead of the intended
- <c>frob.ozz.m:f(...)</c>, if
- package <c>foo.bar</c> happens to be found first in the path.
- Explicitly
- declaring each use of a module makes for safe code.</p>
- </description>
-</erlref>
-
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
index 9ef0959271..67d91ba585 100644
--- a/lib/kernel/doc/src/ref_man.xml
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -64,6 +64,5 @@
<xi:include href="zlib_stub.xml"/>
<xi:include href="app.xml"/>
<xi:include href="config.xml"/>
- <xi:include href="packages.xml"/>
</application>
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 46e7cc4ed8..eaced4861a 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -107,7 +107,6 @@ MODULES = \
net_adm \
net_kernel \
os \
- packages \
pg2 \
ram_file \
rpc \
diff --git a/lib/kernel/src/application.erl b/lib/kernel/src/application.erl
index 9b7c4aa7b8..4e65883be7 100644
--- a/lib/kernel/src/application.erl
+++ b/lib/kernel/src/application.erl
@@ -23,7 +23,7 @@
which_applications/0, which_applications/1,
loaded_applications/0, permit/2]).
-export([set_env/3, set_env/4, unset_env/2, unset_env/3]).
--export([get_env/1, get_env/2, get_all_env/0, get_all_env/1]).
+-export([get_env/1, get_env/2, get_env/3, get_all_env/0, get_all_env/1]).
-export([get_key/1, get_key/2, get_all_key/0, get_all_key/1]).
-export([get_application/0, get_application/1, info/0]).
-export([start_type/0]).
@@ -264,6 +264,20 @@ get_env(Key) ->
get_env(Application, Key) ->
application_controller:get_env(Application, Key).
+-spec get_env(Application, Par, Def) -> Val when
+ Application :: atom(),
+ Par :: atom(),
+ Def :: term(),
+ Val :: term().
+
+get_env(Application, Key, Def) ->
+ case get_env(Application, Key) of
+ {ok, Val} ->
+ Val;
+ undefined ->
+ Def
+ end.
+
-spec get_all_env() -> Env when
Env :: [{Par :: atom(), Val :: term()}].
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index c808ac7cb7..361f2bdf8a 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -359,7 +359,6 @@ load_code_server_prerequisites() ->
hipe_unified_loader,
lists,
os,
- packages,
unicode],
[M = M:module_info(module) || M <- Needed],
ok.
@@ -413,7 +412,7 @@ which(Module) when is_atom(Module) ->
end.
which2(Module) ->
- Base = to_path(Module),
+ Base = atom_to_list(Module),
File = filename:basename(Base) ++ objfile_extension(),
Path = get_path(),
which(File, filename:dirname(Base), Path).
@@ -547,9 +546,6 @@ has_ext(Ext, Extlen, File) ->
_ -> false
end.
-to_path(X) ->
- filename:join(packages:split(X)).
-
-spec load_native_code_for_all_loaded() -> ok.
load_native_code_for_all_loaded() ->
Architecture = erlang:system_info(hipe_architecture),
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 00ad923466..b2d2c19f78 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1229,7 +1229,7 @@ load_abs(File, Mod0, Caller, St) ->
end.
try_load_module(Mod, Dir, Caller, St) ->
- File = filename:append(Dir, to_path(Mod) ++
+ File = filename:append(Dir, to_list(Mod) ++
objfile_extension()),
case erl_prim_loader:get_file(File) of
error ->
@@ -1347,7 +1347,7 @@ load_file_1(Mod, Caller, #state{cache=Cache}=St0) ->
end.
mod_to_bin([Dir|Tail], Mod) ->
- File = filename:append(Dir, to_path(Mod) ++ objfile_extension()),
+ File = filename:append(Dir, to_list(Mod) ++ objfile_extension()),
case erl_prim_loader:get_file(File) of
error ->
mod_to_bin(Tail, Mod);
@@ -1356,7 +1356,7 @@ mod_to_bin([Dir|Tail], Mod) ->
end;
mod_to_bin([], Mod) ->
%% At last, try also erl_prim_loader's own method
- File = to_path(Mod) ++ objfile_extension(),
+ File = to_list(Mod) ++ objfile_extension(),
case erl_prim_loader:get_file(File) of
error ->
error; % No more alternatives !
@@ -1570,6 +1570,3 @@ to_list(X) when is_atom(X) -> atom_to_list(X).
to_atom(X) when is_atom(X) -> X;
to_atom(X) when is_list(X) -> list_to_atom(X).
-
-to_path(X) ->
- filename:join(packages:split(X)).
diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl
index f8bc5f499c..a3aa1f1dcf 100644
--- a/lib/kernel/src/error_handler.erl
+++ b/lib/kernel/src/error_handler.erl
@@ -23,10 +23,12 @@
%% "error_handler: add no_native compiler directive"
-compile(no_native).
-%% A simple error handler.
+%% Callbacks called from the run-time system.
+-export([undefined_function/3,undefined_lambda/3,breakpoint/3]).
--export([undefined_function/3, undefined_lambda/3, stub_function/3,
- breakpoint/3]).
+%% Exported utility functions.
+-export([raise_undef_exception/3]).
+-export([stub_function/3]).
-spec undefined_function(Module, Function, Args) ->
any() when
@@ -41,12 +43,7 @@ undefined_function(Module, Func, Args) ->
true ->
apply(Module, Func, Args);
false ->
- case check_inheritance(Module, Args) of
- {value, Base, Args1} ->
- apply(Base, Func, Args1);
- none ->
- crash(Module, Func, Args)
- end
+ call_undefined_function_handler(Module, Func, Args)
end;
{module, _} ->
crash(Module, Func, Args);
@@ -77,6 +74,14 @@ undefined_lambda(Module, Fun, Args) ->
breakpoint(Module, Func, Args) ->
(int()):eval(Module, Func, Args).
+-spec raise_undef_exception(Module, Function, Args) -> no_return() when
+ Module :: atom(),
+ Function :: atom(),
+ Args :: list().
+
+raise_undef_exception(Module, Func, Args) ->
+ crash({Module,Func,Args,[]}).
+
%% Used to make the call to the 'int' module a "weak" one, to avoid
%% building strong components in xref or dialyzer.
@@ -130,27 +135,11 @@ ensure_loaded(Module) ->
stub_function(Mod, Func, Args) ->
exit({undef,[{Mod,Func,Args,[]}]}).
-check_inheritance(Module, Args) ->
- Attrs = erlang:get_module_info(Module, attributes),
- case lists:keyfind(extends, 1, Attrs) of
- {extends, [Base]} when is_atom(Base), Base =/= Module ->
- %% This is just a heuristic for detecting abstract modules
- %% with inheritance so they can be handled; it would be
- %% much better to do it in the emulator runtime
- case lists:keyfind(abstract, 1, Attrs) of
- {abstract, [true]} ->
- case lists:reverse(Args) of
- [M|Rs] when tuple_size(M) > 1,
- element(1,M) =:= Module,
- tuple_size(element(2,M)) > 0,
- is_atom(element(1,element(2,M))) ->
- {value, Base, lists:reverse(Rs, [element(2,M)])};
- _ ->
- {value, Base, Args}
- end;
- _ ->
- {value, Base, Args}
- end;
- _ ->
- none
+call_undefined_function_handler(Module, Func, Args) ->
+ Handler = '$handle_undefined_function',
+ case erlang:function_exported(Module, Handler, 2) of
+ false ->
+ crash(Module, Func, Args);
+ true ->
+ Module:Handler(Func, Args)
end.
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index de3eaad5a1..16f2dde464 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -38,7 +38,7 @@
%% Specialized
-export([ipread_s32bu_p32bu/3]).
%% Generic file contents.
--export([open/2, close/1, advise/4,
+-export([open/2, close/1, advise/4, allocate/3,
read/2, write/2,
pread/2, pread/3, pwrite/2, pwrite/3,
read_line/1,
@@ -490,6 +490,18 @@ advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) ->
advise(_, _, _, _) ->
{error, badarg}.
+-spec allocate(File, Offset, Length) ->
+ 'ok' | {'error', posix()} when
+ File :: io_device(),
+ Offset :: non_neg_integer(),
+ Length :: non_neg_integer().
+
+allocate(File, Offset, Length) when is_pid(File) ->
+ R = file_request(File, {allocate, Offset, Length}),
+ wait_file_reply(File, R);
+allocate(#file_descriptor{module = Module} = Handle, Offset, Length) ->
+ Module:allocate(Handle, Offset, Length).
+
-spec read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason} when
IoDevice :: io_device() | atom(),
Number :: non_neg_integer(),
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index acaffe1e41..fad2ed7fb3 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -211,6 +211,10 @@ file_request({advise,Offset,Length,Advise},
Reply ->
{reply,Reply,State}
end;
+file_request({allocate, Offset, Length},
+ #state{handle = Handle} = State) ->
+ Reply = ?PRIM_FILE:allocate(Handle, Offset, Length),
+ {reply, Reply, State};
file_request({pread,At,Sz},
#state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
case position(Handle, At, Buf) of
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 17ab84c177..9a20baf8d0 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -28,7 +28,6 @@
application_starter,
auth,
code,
- packages,
code_server,
dist_util,
erl_boot_server,
diff --git a/lib/kernel/src/packages.erl b/lib/kernel/src/packages.erl
deleted file mode 100644
index e0b1f36b85..0000000000
--- a/lib/kernel/src/packages.erl
+++ /dev/null
@@ -1,158 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. 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
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(packages).
-
--export([to_string/1, concat/1, concat/2, is_valid/1, is_segmented/1,
- split/1, last/1, first/1, strip_last/1, find_modules/1,
- find_modules/2]).
-
-%% A package name (or a package-qualified module name) may be an atom or
-%% a string (list of nonnegative integers) - not a deep list, and not a
-%% list containing atoms. A name may be empty, but may not contain two
-%% consecutive period (`.') characters or end with a period character.
-
--type package_name() :: atom() | string().
-
--spec to_string(package_name()) -> string().
-to_string(Name) when is_atom(Name) ->
- atom_to_list(Name);
-to_string(Name) ->
- Name.
-
-%% `concat' does not insert a leading period if the first segment is
-%% empty. However, the result may contain leading, consecutive or
-%% dangling period characters, if any of the segments after the first
-%% are empty. Use 'is_valid' to check the result if necessary.
-
--spec concat(package_name(), package_name()) -> string().
-concat(A, B) ->
- concat([A, B]).
-
--spec concat([package_name()]) -> string().
-concat([H | T]) when is_atom(H) ->
- concat([atom_to_list(H) | T]);
-concat(["" | T]) ->
- concat_1(T);
-concat(L) ->
- concat_1(L).
-
-concat_1([H | T]) when is_atom(H) ->
- concat_1([atom_to_list(H) | T]);
-concat_1([H]) ->
- H;
-concat_1([H | T]) ->
- H ++ "." ++ concat_1(T);
-concat_1([]) ->
- "";
-concat_1(Name) ->
- erlang:error({badarg, Name}).
-
--spec is_valid(package_name()) -> boolean().
-is_valid(Name) when is_atom(Name) ->
- is_valid_1(atom_to_list(Name));
-is_valid([$. | _]) ->
- false;
-is_valid(Name) ->
- is_valid_1(Name).
-
-is_valid_1([$.]) -> false;
-is_valid_1([$., $. | _]) -> false;
-is_valid_1([H | T]) when is_integer(H), H >= 0 ->
- is_valid_1(T);
-is_valid_1([]) -> true;
-is_valid_1(_) -> false.
-
--spec split(package_name()) -> [string()].
-split(Name) when is_atom(Name) ->
- split_1(atom_to_list(Name), []);
-split(Name) ->
- split_1(Name, []).
-
-split_1([$. | T], Cs) ->
- [lists:reverse(Cs) | split_1(T, [])];
-split_1([H | T], Cs) when is_integer(H), H >= 0 ->
- split_1(T, [H | Cs]);
-split_1([], Cs) ->
- [lists:reverse(Cs)];
-split_1(_, _) ->
- erlang:error(badarg).
-
-%% This is equivalent to testing if `split(Name)' yields a list of
-%% length larger than one (i.e., if the name can be split into two or
-%% more segments), but is cheaper.
-
--spec is_segmented(package_name()) -> boolean().
-is_segmented(Name) when is_atom(Name) ->
- is_segmented_1(atom_to_list(Name));
-is_segmented(Name) ->
- is_segmented_1(Name).
-
-is_segmented_1([$. | _]) -> true;
-is_segmented_1([H | T]) when is_integer(H), H >= 0 ->
- is_segmented_1(T);
-is_segmented_1([]) -> false;
-is_segmented_1(_) ->
- erlang:error(badarg).
-
--spec last(package_name()) -> string().
-last(Name) ->
- last_1(split(Name)).
-
-last_1([H]) -> H;
-last_1([_ | T]) -> last_1(T).
-
--spec first(package_name()) -> [string()].
-first(Name) ->
- first_1(split(Name)).
-
-first_1([H | T]) when T =/= [] -> [H | first_1(T)];
-first_1(_) -> [].
-
--spec strip_last(package_name()) -> string().
-strip_last(Name) ->
- concat(first(Name)).
-
-%% This finds all modules available for a given package, using the
-%% current code server search path. (There is no guarantee that the
-%% modules are loadable; only that the object files exist.)
-
--spec find_modules(package_name()) -> [string()].
-find_modules(P) ->
- find_modules(P, code:get_path()).
-
--spec find_modules(package_name(), [string()]) -> [string()].
-find_modules(P, Paths) ->
- P1 = filename:join(packages:split(P)),
- find_modules(P1, Paths, code:objfile_extension(), sets:new()).
-
-find_modules(P, [Path | Paths], Ext, S0) ->
- case file:list_dir(filename:join(Path, P)) of
- {ok, Fs} ->
- Fs1 = [F || F <- Fs, filename:extension(F) =:= Ext],
- S1 = lists:foldl(fun (F, S) ->
- F1 = filename:rootname(F, Ext),
- sets:add_element(F1, S)
- end,
- S0, Fs1),
- find_modules(P, Paths, Ext, S1);
- _ ->
- find_modules(P, Paths, Ext, S0)
- end;
-find_modules(_P, [], _Ext, S) ->
- sets:to_list(S).
diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl
index 48ea871433..ca881ff8a4 100644
--- a/lib/kernel/src/ram_file.erl
+++ b/lib/kernel/src/ram_file.erl
@@ -29,6 +29,7 @@
%% Specialized file operations
-export([get_size/1, get_file/1, set_file/2, get_file_close/1]).
-export([compress/1, uncompress/1, uuencode/1, uudecode/1, advise/4]).
+-export([allocate/3]).
-export([open_mode/1]). %% used by ftp-file
@@ -72,6 +73,7 @@
-define(RAM_FILE_UUDECODE, 36).
-define(RAM_FILE_SIZE, 37).
-define(RAM_FILE_ADVISE, 38).
+-define(RAM_FILE_ALLOCATE, 39).
%% Open modes for RAM_FILE_OPEN
-define(RAM_FILE_MODE_READ, 1).
@@ -383,6 +385,11 @@ advise(#file_descriptor{module = ?MODULE, data = Port}, Offset,
advise(#file_descriptor{}, _Offset, _Length, _Advise) ->
{error, enotsup}.
+allocate(#file_descriptor{module = ?MODULE, data = Port}, Offset, Length) ->
+ call_port(Port, <<?RAM_FILE_ALLOCATE, Offset:64/signed, Length:64/signed>>);
+allocate(#file_descriptor{}, _Offset, _Length) ->
+ {error, enotsup}.
+
%%%-----------------------------------------------------------------
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 8eca37029d..8d2d55777b 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -48,6 +48,7 @@ MODULES= \
erl_distribution_SUITE \
erl_distribution_wb_SUITE \
erl_prim_loader_SUITE \
+ error_handler_SUITE \
error_logger_SUITE \
error_logger_warn_SUITE \
file_SUITE \
@@ -73,6 +74,7 @@ MODULES= \
seq_trace_SUITE \
wrap_log_reader_SUITE \
cleanup \
+ ignore_cores \
zlib_SUITE \
loose_node \
sendfile_SUITE
diff --git a/lib/kernel/test/application_SUITE.erl b/lib/kernel/test/application_SUITE.erl
index f469a0af98..2ca8840e1f 100644
--- a/lib/kernel/test/application_SUITE.erl
+++ b/lib/kernel/test/application_SUITE.erl
@@ -27,7 +27,7 @@
otp_1586/1, otp_2078/1, otp_2012/1, otp_2718/1, otp_2973/1,
otp_3002/1, otp_3184/1, otp_4066/1, otp_4227/1, otp_5363/1,
otp_5606/1,
- start_phases/1, get_key/1,
+ start_phases/1, get_key/1, get_env/1,
permit_false_start_local/1, permit_false_start_dist/1, script_start/1,
nodedown_start/1, init2973/0, loop2973/0, loop5606/1]).
@@ -49,7 +49,7 @@ all() ->
[failover, failover_comp, permissions, load,
load_use_cache, {group, reported_bugs}, start_phases,
script_start, nodedown_start, permit_false_start_local,
- permit_false_start_dist, get_key,
+ permit_false_start_dist, get_key, get_env,
{group, distr_changed}, config_change, shutdown_func, shutdown_timeout].
groups() ->
@@ -1503,6 +1503,15 @@ loop5606(Pid) ->
Pid ! {self(), Res}
end.
+get_env(suite) -> [];
+get_env(doc) ->
+ ["Tests get_env/* functions"];
+get_env(Conf) when is_list(Conf) ->
+ {ok, _} = application:get_env(kernel, error_logger),
+ undefined = application:get_env(undefined_app, a),
+ undefined = application:get_env(kernel, error_logger_xyz),
+ default = application:get_env(kernel, error_logger_xyz, default),
+ ok.
%%-----------------------------------------------------------------
%% Should be started in a CC view with:
diff --git a/lib/kernel/test/error_handler_SUITE.erl b/lib/kernel/test/error_handler_SUITE.erl
new file mode 100644
index 0000000000..2a86d39b74
--- /dev/null
+++ b/lib/kernel/test/error_handler_SUITE.erl
@@ -0,0 +1,68 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013. 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
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(error_handler_SUITE).
+
+-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
+ init_per_group/2,end_per_group/2,
+ undefined_function_handler/1]).
+
+%% Callback from error_handler.
+-export(['$handle_undefined_function'/2]).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [undefined_function_handler].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+
+%%-----------------------------------------------------------------
+
+undefined_function_handler(_) ->
+ 42 = ?MODULE:forty_two(),
+ 42 = (id(?MODULE)):forty_two(),
+ {ok,{a,b,c}} = ?MODULE:one_arg({a,b,c}),
+ {ok,{a,b,c}} = (id(?MODULE)):one_arg({a,b,c}),
+ {'EXIT',{undef,[{?MODULE,undef_and_not_handled,[[1,2,3]],[]}|_]}} =
+ (catch ?MODULE:undef_and_not_handled([1,2,3])),
+ ok.
+
+'$handle_undefined_function'(forty_two, []) ->
+ 42;
+'$handle_undefined_function'(one_arg, [Arg]) ->
+ {ok,Arg};
+'$handle_undefined_function'(Func, Args) ->
+ error_handler:raise_undef_exception(?MODULE, Func, Args).
+
+id(I) ->
+ I.
diff --git a/lib/kernel/test/error_logger_warn_SUITE.erl b/lib/kernel/test/error_logger_warn_SUITE.erl
index 265e1ae4c8..2bf467610e 100644
--- a/lib/kernel/test/error_logger_warn_SUITE.erl
+++ b/lib/kernel/test/error_logger_warn_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2012. 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
@@ -310,7 +310,7 @@ nice_stop_node(Name) ->
{nodedown,Name} -> ok
end.
-%rensa rd() f�re varje rapport-test s� man bara f�r en fil...
+%clean out rd() before each report test in order to get only one file...
clean_rd() ->
{ok,L} = file:list_dir(rd()),
lists:foreach(fun(F) ->
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 9c507fd437..914f0d6127 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -84,6 +84,8 @@
-export([advise/1]).
+-export([allocate/1]).
+
-export([standard_io/1,mini_server/1]).
%% Debug exports
@@ -116,7 +118,7 @@ groups() ->
{files, [],
[{group, open}, {group, pos}, {group, file_info},
{group, consult}, {group, eval}, {group, script},
- truncate, sync, datasync, advise]},
+ truncate, sync, datasync, advise, allocate]},
{open, [],
[open1, old_modes, new_modes, path_open, close, access,
read_write, pread_write, append, open_errors,
@@ -1617,6 +1619,74 @@ advise(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+allocate(suite) -> [];
+allocate(doc) -> "Tests that ?FILE_MODULE:allocate/3 at least doesn't crash.";
+allocate(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Allocate = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_allocate.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd, 1, iolist_size([Line1, Line2])),
+ ?line ok = io:format(Fd, "~s", [Line1]),
+ ?line ok = io:format(Fd, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ ?line {ok, Fd2} = ?FILE_MODULE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd2, 1, iolist_size(Line1)),
+ ?line ok = io:format(Fd2, "~s", [Line1]),
+ ?line ok = io:format(Fd2, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd2),
+
+ ?line {ok, Fd3} = ?FILE_MODULE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd3, 1, iolist_size(Line1) + 1),
+ ?line ok = io:format(Fd3, "~s", [Line1]),
+ ?line ok = io:format(Fd3, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd3),
+
+ ?line {ok, Fd4} = ?FILE_MODULE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd4, 1, 4 * iolist_size([Line1, Line2])),
+ ?line ok = io:format(Fd4, "~s", [Line1]),
+ ?line ok = io:format(Fd4, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd4),
+
+ ?line [] = flush(),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+allocate_and_assert(Fd, Offset, Length) ->
+ % Just verify that calls to ?PRIM_FILE:allocate/3 don't crash or have
+ % any other negative side effect. We can't really asssert against a
+ % specific return value, because support for file space pre-allocation
+ % depends on the OS, OS version and underlying filesystem.
+ %
+ % The Linux kernel added support for fallocate() in version 2.6.23,
+ % which currently works only for the ext4, ocfs2, xfs and btrfs file
+ % systems. posix_fallocate() is available in glibc as of version
+ % 2.1.94, but it was buggy until glibc version 2.7.
+ %
+ % Mac OS X, as of version 10.3, supports the fcntl operation F_PREALLOCATE.
+ %
+ % Solaris supports posix_fallocate() but only for the UFS file system
+ % apparently (not supported for ZFS).
+ %
+ % FreeBSD 9.0 is the first FreeBSD release supporting posix_fallocate().
+ %
+ % For Windows there's apparently no way to pre-allocate file space, at
+ % least with same semantics as posix_fallocate(), fallocate() and
+ % fcntl F_PREALLOCATE.
+ Result = ?FILE_MODULE:allocate(Fd, Offset, Length),
+ case os:type() of
+ {win32, _} ->
+ ?line {error, enotsup} = Result;
+ _ ->
+ ?line _ = Result
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl
index 3aa010a708..40bde8a736 100644
--- a/lib/kernel/test/file_name_SUITE.erl
+++ b/lib/kernel/test/file_name_SUITE.erl
@@ -1,4 +1,5 @@
-module(file_name_SUITE).
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
@@ -336,7 +337,7 @@ check_normal(Mod) ->
check_icky(Mod) ->
{ok,Dir} = Mod:get_cwd(),
try
- ?line true=(length("���") =:= 3),
+ ?line true=(length("åäö") =:= 3),
?line UniMode = file:native_name_encoding() =/= latin1,
?line make_icky_dir(Mod),
?line {ok, L0} = Mod:list_dir("."),
@@ -357,42 +358,42 @@ check_icky(Mod) ->
|| {T,S,Targ} <- icky_dir(), T =:= symlink ],
?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ],
?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ],
- ?line chk_cre_dir(Mod,[{directory,"���_dir",icky_dir()}]),
+ ?line chk_cre_dir(Mod,[{directory,"åäö_dir",icky_dir()}]),
?line {ok,BeginAt} = Mod:get_cwd(),
?line true = is_list(BeginAt),
- ?line {error,enoent} = Mod:set_cwd("��_dir"),
- ?line ok = Mod:set_cwd("���_dir"),
+ ?line {error,enoent} = Mod:set_cwd("åä_dir"),
+ ?line ok = Mod:set_cwd("åäö_dir"),
?line {ok, NowAt} = Mod:get_cwd(),
?line true = is_list(NowAt),
?line true = BeginAt =/= NowAt,
?line ok = Mod:set_cwd(".."),
?line {ok,BeginAt} = Mod:get_cwd(),
- ?line rm_r2(Mod,"���_dir"),
+ ?line rm_r2(Mod,"åäö_dir"),
{OS,TYPE} = os:type(),
% Check that treat_icky really converts to the same as the OS
case UniMode of
true ->
- ?line chk_cre_dir(Mod,[{directory,"���_dir",[]}]),
- ?line ok = Mod:set_cwd("���_dir"),
- ?line ok = Mod:write_file(<<"���">>,<<"hello">>),
- ?line Treated = treat_icky(<<"���">>),
+ ?line chk_cre_dir(Mod,[{directory,"åäö_dir",[]}]),
+ ?line ok = Mod:set_cwd("åäö_dir"),
+ ?line ok = Mod:write_file(<<"ååå">>,<<"hello">>),
+ ?line Treated = treat_icky(<<"ååå">>),
?line {ok,[Treated]} = Mod:list_dir("."),
- ?line ok = Mod:delete(<<"���">>),
+ ?line ok = Mod:delete(<<"ååå">>),
?line {ok,[]} = Mod:list_dir("."),
?line ok = Mod:set_cwd(".."),
- ?line rm_r2(Mod,"���_dir");
+ ?line rm_r2(Mod,"åäö_dir");
false ->
ok
end,
- ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"���_dir">>),icky_dir()}]),
+ ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"åäö_dir">>),icky_dir()}]),
if
UniMode and (OS =/= win32) ->
- ?line {error,enoent} = Mod:set_cwd("���_dir");
+ ?line {error,enoent} = Mod:set_cwd("åäö_dir");
true ->
ok
end,
- ?line ok = Mod:set_cwd(treat_icky(<<"���_dir">>)),
+ ?line ok = Mod:set_cwd(treat_icky(<<"åäö_dir">>)),
?line {ok, NowAt2} = Mod:get_cwd(),
io:format("~p~n",[NowAt2]),
% Cannot create raw unicode-breaking filenames on windows or macos
@@ -400,22 +401,22 @@ check_icky(Mod) ->
?line true = BeginAt =/= NowAt2,
?line ok = Mod:set_cwd(".."),
?line {ok,BeginAt} = Mod:get_cwd(),
- ?line rm_r2(Mod,conv(treat_icky(<<"���_dir">>))),
+ ?line rm_r2(Mod,conv(treat_icky(<<"åäö_dir">>))),
case has_links() of
true ->
- ?line ok = Mod:make_link("fil1","nisse�"),
- ?line {ok, <<"fil1">>} = Mod:read_file("nisse�"),
- ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse�"),
- ?line ok = Mod:delete("nisse�"),
- ?line ok = Mod:make_link("fil1",treat_icky(<<"nisse�">>)),
- ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisse�">>)),
- ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisse�">>)),
- ?line ok = Mod:delete(treat_icky(<<"nisse�">>)),
+ ?line ok = Mod:make_link("fil1","nisseö"),
+ ?line {ok, <<"fil1">>} = Mod:read_file("nisseö"),
+ ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisseö"),
+ ?line ok = Mod:delete("nisseö"),
+ ?line ok = Mod:make_link("fil1",treat_icky(<<"nisseö">>)),
+ ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisseö">>)),
+ ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisseö">>)),
+ ?line ok = Mod:delete(treat_icky(<<"nisseö">>)),
?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
- ?line {error,enoent} = Mod:read_file("nisse�"),
- ?line {error,enoent} = Mod:read_link_info("nisse�"),
- ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisse�">>)),
- ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisse�">>));
+ ?line {error,enoent} = Mod:read_file("nisseö"),
+ ?line {error,enoent} = Mod:read_link_info("nisseö"),
+ ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisseö">>)),
+ ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisseö">>));
false ->
ok
end,
@@ -430,42 +431,42 @@ check_icky(Mod) ->
?line {ok, BC} = Mod:read(FD,1024),
?line ok = file:close(FD)
end || {regular,Name,Content} <- icky_dir() ],
- ?line Mod:rename("���2","���_fil1"),
- ?line {ok, <<"���2">>} = Mod:read_file("���_fil1"),
- ?line {error,enoent} = Mod:read_file("���2"),
- ?line Mod:rename("���_fil1","���2"),
- ?line {ok, <<"���2">>} = Mod:read_file("���2"),
- ?line {error,enoent} = Mod:read_file("���_fil1"),
+ ?line Mod:rename("åäö2","åäö_fil1"),
+ ?line {ok, <<"åäö2">>} = Mod:read_file("åäö_fil1"),
+ ?line {error,enoent} = Mod:read_file("åäö2"),
+ ?line Mod:rename("åäö_fil1","åäö2"),
+ ?line {ok, <<"åäö2">>} = Mod:read_file("åäö2"),
+ ?line {error,enoent} = Mod:read_file("åäö_fil1"),
- ?line Mod:rename("���2",treat_icky(<<"���_fil1">>)),
- ?line {ok, <<"���2">>} = Mod:read_file(treat_icky(<<"���_fil1">>)),
+ ?line Mod:rename("åäö2",treat_icky(<<"åäö_fil1">>)),
+ ?line {ok, <<"åäö2">>} = Mod:read_file(treat_icky(<<"åäö_fil1">>)),
if
UniMode and (OS =/= win32) ->
- {error,enoent} = Mod:read_file("���_fil1");
+ {error,enoent} = Mod:read_file("åäö_fil1");
true ->
ok
end,
- ?line {error,enoent} = Mod:read_file("���2"),
- ?line Mod:rename(treat_icky(<<"���_fil1">>),"���2"),
- ?line {ok, <<"���2">>} = Mod:read_file("���2"),
- ?line {error,enoent} = Mod:read_file("���_fil1"),
- ?line {error,enoent} = Mod:read_file(treat_icky(<<"���_fil1">>)),
+ ?line {error,enoent} = Mod:read_file("åäö2"),
+ ?line Mod:rename(treat_icky(<<"åäö_fil1">>),"åäö2"),
+ ?line {ok, <<"åäö2">>} = Mod:read_file("åäö2"),
+ ?line {error,enoent} = Mod:read_file("åäö_fil1"),
+ ?line {error,enoent} = Mod:read_file(treat_icky(<<"åäö_fil1">>)),
- ?line {ok,FI} = Mod:read_file_info("���2"),
+ ?line {ok,FI} = Mod:read_file_info("åäö2"),
?line NewMode = FI#file_info.mode band (bnot 8#333),
?line NewMode2 = NewMode bor 8#222,
?line true = NewMode2 =/= NewMode,
- ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode}),
- ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("���2"),
- ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode2}),
- ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("���2"),
+ ?line ok = Mod:write_file_info("åäö2",FI#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("åäö2"),
+ ?line ok = Mod:write_file_info("åäö2",FI#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("åäö2"),
- ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"���5">>)),
+ ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"åäö5">>)),
?line true = NewMode2 =/= NewMode,
- ?line ok = Mod:write_file_info(treat_icky(<<"���5">>),FII#file_info{mode = NewMode}),
- ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"���5">>)),
- ?line ok = Mod:write_file_info(<<"���5">>,FII#file_info{mode = NewMode2}),
- ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"���5">>)),
+ ?line ok = Mod:write_file_info(treat_icky(<<"åäö5">>),FII#file_info{mode = NewMode}),
+ ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"åäö5">>)),
+ ?line ok = Mod:write_file_info(<<"åäö5">>,FII#file_info{mode = NewMode2}),
+ ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"åäö5">>)),
ok
after
Mod:set_cwd(Dir),
@@ -475,7 +476,7 @@ check_icky(Mod) ->
check_very_icky(Mod) ->
{ok,Dir} = Mod:get_cwd(),
try
- ?line true=(length("���") =:= 3),
+ ?line true=(length("åäö") =:= 3),
?line UniMode = file:native_name_encoding() =/= latin1,
if
not UniMode ->
@@ -497,7 +498,7 @@ check_very_icky(Mod) ->
?line chk_cre_dir(Mod,[{directory,[1088,1079,1091]++"_dir",very_icky_dir()}]),
?line {ok,BeginAt} = Mod:get_cwd(),
?line true = is_list(BeginAt),
- ?line {error,enoent} = Mod:set_cwd("��_dir"),
+ ?line {error,enoent} = Mod:set_cwd("åä_dir"),
?line ok = Mod:set_cwd([1088,1079,1091]++"_dir"),
?line {ok, NowAt} = Mod:get_cwd(),
?line true = is_list(NowAt),
@@ -514,16 +515,16 @@ check_very_icky(Mod) ->
?line {ok, #file_info{type = regular}} =
Mod:read_link_info("nisse"++[1088,1079,1091]),
?line ok = Mod:delete("nisse"++[1088,1079,1091]),
- ?line ok = Mod:make_link("fil1",<<"nisse�">>),
- ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisse�">>),
+ ?line ok = Mod:make_link("fil1",<<"nisseö">>),
+ ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisseö">>),
?line {ok, #file_info{type = regular}} =
- Mod:read_link_info(<<"nisse�">>),
- ?line ok = Mod:delete(<<"nisse�">>),
+ Mod:read_link_info(<<"nisseö">>),
+ ?line ok = Mod:delete(<<"nisseö">>),
?line {ok, <<"fil1">>} = Mod:read_file("fil1"),
?line {error,enoent} = Mod:read_file("nisse"++[1088,1079,1091]),
?line {error,enoent} = Mod:read_link_info("nisse"++[1088,1079,1091]),
- ?line {error,enoent} = Mod:read_file(<<"nisse�">>),
- ?line {error,enoent} = Mod:read_link_info(<<"nisse�">>);
+ ?line {error,enoent} = Mod:read_file(<<"nisseö">>),
+ ?line {error,enoent} = Mod:read_link_info(<<"nisseö">>);
false ->
ok
end,
@@ -540,10 +541,10 @@ check_very_icky(Mod) ->
end || {regular,Name,Content} <- very_icky_dir() ],
?line Mod:rename([956,965,963,954,959,49],
[956,965,963,954,959]++"_fil1"),
- ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"),
+ ?line {ok, <<"åäö2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"),
?line {error,enoent} = Mod:read_file([956,965,963,954,959,49]),
?line Mod:rename([956,965,963,954,959]++"_fil1",[956,965,963,954,959,49]),
- ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959,49]),
+ ?line {ok, <<"åäö2">>} = Mod:read_file([956,965,963,954,959,49]),
?line {error,enoent} = Mod:read_file([956,965,963,954,959]++"_fil1"),
?line {ok,FI} = Mod:read_file_info([956,965,963,954,959,49]),
@@ -574,9 +575,9 @@ 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",
+ ?line SF3 = unicode:characters_to_binary("åäösubfil3",
file:native_name_encoding()),
- ?line SF2 = case treat_icky(<<"���subfil2">>) of
+ ?line SF2 = case treat_icky(<<"åäösubfil2">>) of
LF2 when is_list(LF2) ->
unicode:characters_to_binary(LF2,
file:native_name_encoding());
@@ -584,7 +585,7 @@ check_very_icky(Mod) ->
BF2
end,
?line Sorted = lists:sort([SF3,SF2]),
- ?line Sorted = lists:sort(filelib:wildcard("*",<<"���subdir2">>)),
+ ?line Sorted = lists:sort(filelib:wildcard("*",<<"åäösubdir2">>)),
ok
catch
throw:need_unicode_mode ->
@@ -744,26 +745,26 @@ hopeless_darwin() ->
icky_dir() ->
[{regular,"fil1","fil1"},
- {regular,"���2","���2"}] ++
+ {regular,"åäö2","åäö2"}] ++
case has_links() of
true ->
- [{regular,"���3","���2"},
- {symlink,"���4","���2"}];
+ [{regular,"åäö3","åäö2"},
+ {symlink,"åäö4","åäö2"}];
false ->
[]
end ++
- [{regular,treat_icky(<<"���5">>),"���5"}] ++
+ [{regular,treat_icky(<<"åäö5">>),"åäö5"}] ++
case has_links() of
true ->
- [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}];
+ [{symlink,treat_icky(<<"åäö6">>),treat_icky(<<"åäö5">>)}];
false ->
[]
end ++
- [{directory,treat_icky(<<"���subdir2">>),
- [{regular,treat_icky(<<"���subfil2">>),"���subfil12"},
- {regular,"���subfil3","���subfil13"}]},
- {directory,"���subdir",
- [{regular,"���subfil1","���subfil1"}]}].
+ [{directory,treat_icky(<<"åäösubdir2">>),
+ [{regular,treat_icky(<<"åäösubfil2">>),"åäösubfil12"},
+ {regular,"åäösubfil3","åäösubfil13"}]},
+ {directory,"åäösubdir",
+ [{regular,"åäösubfil1","åäösubfil1"}]}].
make_very_icky_dir(Mod) ->
rm_rf(Mod,"very_icky_dir"),
@@ -774,26 +775,26 @@ make_very_icky_dir(Mod) ->
very_icky_dir() ->
[{regular,"fil1","fil1"},
- {regular,[956,965,963,954,959,49],"���2"}] ++
+ {regular,[956,965,963,954,959,49],"åäö2"}] ++
case has_links() of
true ->
- [{regular,[956,965,963,954,959,50],"���2"},
+ [{regular,[956,965,963,954,959,50],"åäö2"},
{symlink,[956,965,963,954,959,51],[956,965,963,954,959,49]}];
false ->
[]
end ++
- [{regular,treat_icky(<<"���5">>),"���5"}] ++
+ [{regular,treat_icky(<<"åäö5">>),"åäö5"}] ++
case has_links() of
true ->
- [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}];
+ [{symlink,treat_icky(<<"åäö6">>),treat_icky(<<"åäö5">>)}];
false ->
[]
end ++
- [{directory,treat_icky(<<"���subdir2">>),
- [{regular,treat_icky(<<"���subfil2">>),"���subfil12"},
- {regular,"���subfil3","���subfil13"}]},
+ [{directory,treat_icky(<<"åäösubdir2">>),
+ [{regular,treat_icky(<<"åäösubfil2">>),"åäösubfil12"},
+ {regular,"åäösubfil3","åäösubfil13"}]},
{directory,[956,965,963,954,959]++"subdir1",
- [{regular,[956,965,963,954,959]++"subfil1","���subfil1"}]}].
+ [{regular,[956,965,963,954,959]++"subfil1","åäösubfil1"}]}].
%% Some OS'es simply do not allow non UTF8 filenames
treat_icky(Bin) ->
diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl
index 2354f8accd..cd768813cf 100644
--- a/lib/kernel/test/gen_udp_SUITE.erl
+++ b/lib/kernel/test/gen_udp_SUITE.erl
@@ -1,7 +1,8 @@
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2012. 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
@@ -442,7 +443,7 @@ open_fd(suite) ->
open_fd(doc) ->
["Test that the 'fd' option works"];
open_fd(Config) when is_list(Config) ->
- Msg = "Det g�r ont n�r knoppar brista. Varf�r skulle annars v�ren tveka?",
+ Msg = "Det gör ont när knoppar brista. Varför skulle annars våren tveka?",
Addr = {127,0,0,1},
{ok,S1} = gen_udp:open(0),
{ok,P2} = inet:port(S1),
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index b40c50f79f..9428a38660 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -91,27 +91,9 @@ end_per_group(_GroupName, Config) ->
Config.
init_per_suite(Config) ->
-
- %% Copied from test_server_ctrl ln 647, we have to do this here as
- %% the test_server only does this when run without common_test
- global:sync(),
- case global:whereis_name(test_server) of
- undefined ->
- io:format(user, "Registering test_server globally!~n",[]),
- global:register_name(test_server, whereis(test_server_ctrl));
- Pid ->
- case node() of
- N when N == node(Pid) ->
- io:format(user, "Warning: test_server already running!\n", []),
- global:re_register_name(test_server,self());
- _ ->
- ok
- end
- end,
Config.
end_per_suite(_Config) ->
- global:unregister_name(test_server),
ok.
@@ -135,8 +117,7 @@ end_per_testcase(_Case, Config) ->
?line write_high_level_trace(Config),
?line _ =
gen_server:call(global_name_server, high_level_trace_stop, infinity),
- ?line[global:unregister_name(N) || N <- global:registered_names(),
- N =/= test_server],
+ [global:unregister_name(N) || N <- global:registered_names()],
?line InitRegistered = ?registered,
?line Registered = registered(),
?line [io:format("~s local names: ~p~n", [What, N]) ||
@@ -1840,16 +1821,16 @@ do_otp_3162(StartFun, Config) ->
?line ?UNTIL
([Cp3] =:= lists:sort(rpc:call(Cp1, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, test_server, vera] =:=
+ ?UNTIL([kalle, vera] =:=
lists:sort(rpc:call(Cp1, global, registered_names, []))),
?line ?UNTIL
([Cp3] =:= lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([stina, test_server, vera] =:=
+ ?UNTIL([stina, vera] =:=
lists:sort(rpc:call(Cp2, global, registered_names, []))),
?line ?UNTIL
([Cp1, Cp2] =:=
lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp3, global, registered_names, []))),
?line pong = rpc:call(Cp2, net_adm, ping, [Cp1]),
@@ -1860,17 +1841,17 @@ do_otp_3162(StartFun, Config) ->
?line
?UNTIL(begin
NN = lists:sort(rpc:call(Cp1, global, registered_names, [])),
- [kalle, stina, test_server, vera] =:= NN
+ [kalle, stina, vera] =:= NN
end),
?line ?UNTIL
([Cp1, Cp3] =:=
lists:sort(rpc:call(Cp2, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp2, global, registered_names, []))),
?line ?UNTIL
([Cp1, Cp2] =:=
lists:sort(rpc:call(Cp3, erlang, nodes, [])) -- [node()]),
- ?line ?UNTIL([kalle, stina, test_server, vera] =:=
+ ?UNTIL([kalle, stina, vera] =:=
lists:sort(rpc:call(Cp3, global, registered_names, []))),
write_high_level_trace(Config),
@@ -4154,7 +4135,7 @@ init_condition(Config) ->
{"Global Locks (ETS)", global_locks},
{"Global Pid Names (ETS)", global_pid_names},
{"Global Pid Ids (ETS)", global_pid_ids}]],
- ?UNTIL([test_server] =:= global:registered_names()),
+ ?UNTIL([] =:= global:registered_names()),
?UNTIL([] =:= nodes()),
?UNTIL([node()] =:= get_known(node())),
ok.
diff --git a/lib/kernel/test/heart_SUITE.erl b/lib/kernel/test/heart_SUITE.erl
index 2ec3b7c297..320b23bea1 100644
--- a/lib/kernel/test/heart_SUITE.erl
+++ b/lib/kernel/test/heart_SUITE.erl
@@ -83,10 +83,10 @@ init_per_suite(Config) when is_list(Config) ->
{win32, windows} ->
{skipped, "No use to run on Windows 95/98"};
_ ->
- Config
+ ignore_cores:init(Config)
end.
end_per_suite(Config) when is_list(Config) ->
- Config.
+ ignore_cores:fini(Config).
start_check(Type, Name) ->
@@ -188,8 +188,20 @@ reboot(Config) when is_list(Config) ->
%% Check that a node is up and running after a crash.
%% This test exhausts the atom table on the remote node.
%% ERL_CRASH_DUMP_SECONDS=0 will force beam not to dump an erl_crash.dump.
+%% May currently dump core in beam debug build due to lock-order violation
+%% This should be removed when a non-lockad information retriever is implemented
+%% for crash dumps
node_start_immediately_after_crash(suite) -> {req, [{time, 10}]};
node_start_immediately_after_crash(Config) when is_list(Config) ->
+ Config2 = ignore_cores:setup(?MODULE, node_start_immediately_after_crash, Config, true),
+ try
+ node_start_immediately_after_crash_test(Config2)
+ after
+ ignore_cores:restore(Config2)
+ end.
+
+
+node_start_immediately_after_crash_test(Config) when is_list(Config) ->
{ok, Node} = start_check(loose, heart_test_imm, [{"ERL_CRASH_DUMP_SECONDS", "0"}]),
ok = rpc:call(Node, heart, set_cmd,
@@ -228,8 +240,19 @@ node_start_immediately_after_crash(Config) when is_list(Config) ->
%% This test exhausts the atom table on the remote node.
%% ERL_CRASH_DUMP_SECONDS=10 will force beam
%% to only dump an erl_crash.dump for 10 seconds.
+%% May currently dump core in beam debug build due to lock-order violation
+%% This should be removed when a non-lockad information retriever is implemented
+%% for crash dumps
node_start_soon_after_crash(suite) -> {req, [{time, 10}]};
node_start_soon_after_crash(Config) when is_list(Config) ->
+ Config2 = ignore_cores:setup(?MODULE, node_start_soon_after_crash, Config, true),
+ try
+ node_start_soon_after_crash_test(Config2)
+ after
+ ignore_cores:restore(Config2)
+ end.
+
+node_start_soon_after_crash_test(Config) when is_list(Config) ->
{ok, Node} = start_check(loose, heart_test_soon, [{"ERL_CRASH_DUMP_SECONDS", "10"}]),
ok = rpc:call(Node, heart, set_cmd,
diff --git a/lib/kernel/test/ignore_cores.erl b/lib/kernel/test/ignore_cores.erl
new file mode 100644
index 0000000000..8b1ac0fe6c
--- /dev/null
+++ b/lib/kernel/test/ignore_cores.erl
@@ -0,0 +1,158 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2010. 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
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : ignore_cores.erl
+%%% Author : Rickard Green <[email protected]>
+%%% Description :
+%%%
+%%% Created : 11 Feb 2008 by Rickard Green <[email protected]>
+%%%-------------------------------------------------------------------
+
+-module(ignore_cores).
+
+-include_lib("test_server/include/test_server.hrl").
+
+-export([init/1, fini/1, setup/3, setup/4, restore/1, dir/1]).
+
+-record(ignore_cores, {org_cwd,
+ org_path,
+ org_pwd_env,
+ ign_dir = false,
+ cores_dir = false}).
+
+%%
+%% Takes a testcase config
+%%
+
+init(Config) ->
+ {ok, OrgCWD} = file:get_cwd(),
+ [{ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = code:get_path(),
+ org_pwd_env = os:getenv("PWD")}}
+ | lists:keydelete(ignore_cores, 1, Config)].
+
+fini(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ ok = file:set_cwd(OrgCWD),
+ true = code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> true = os:putenv("PWD", OrgPWD)
+ end,
+ lists:keydelete(ignore_cores, 1, Config).
+
+setup(Suite, Testcase, Config) ->
+ setup(Suite, Testcase, Config, false).
+
+setup(Suite, Testcase, Config, SetCwd) when is_atom(Suite),
+ is_atom(Testcase),
+ is_list(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD} = ?config(ignore_cores, Config),
+ Path = lists:map(fun (".") -> OrgCWD; (Dir) -> Dir end, OrgPath),
+ true = code:set_path(Path),
+ PrivDir = ?config(priv_dir, Config),
+ IgnDir = filename:join([PrivDir,
+ atom_to_list(Suite)
+ ++ "_"
+ ++ atom_to_list(Testcase)
+ ++ "_wd"]),
+ ok = file:make_dir(IgnDir),
+ case SetCwd of
+ false ->
+ ok;
+ _ ->
+ ok = file:set_cwd(IgnDir),
+ OrgPWD = case os:getenv("PWD") of
+ false -> false;
+ PWD ->
+ os:putenv("PWD", IgnDir),
+ PWD
+ end
+ end,
+ ok = file:write_file(filename:join([IgnDir, "ignore_core_files"]), <<>>),
+ %% cores are dumped in /cores on MacOS X
+ CoresDir = case {?t:os_type(), filelib:is_dir("/cores")} of
+ {{unix,darwin}, true} ->
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []);
+ _ ->
+ false
+ end,
+ lists:keyreplace(ignore_cores,
+ 1,
+ Config,
+ {ignore_cores,
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir}}).
+
+restore(Config) ->
+ #ignore_cores{org_cwd = OrgCWD,
+ org_path = OrgPath,
+ org_pwd_env = OrgPWD,
+ ign_dir = IgnDir,
+ cores_dir = CoresDir} = ?config(ignore_cores, Config),
+ try
+ case CoresDir of
+ false ->
+ ok;
+ _ ->
+ %% Move cores dumped by these testcases in /cores
+ %% to cwd.
+ lists:foreach(fun (C) ->
+ case lists:member(C, CoresDir) of
+ true -> ok;
+ _ ->
+ Dst = filename:join(
+ [IgnDir,
+ filename:basename(C)]),
+ {ok, _} = file:copy(C, Dst),
+ file:delete(C)
+ end
+ end,
+ filelib:fold_files("/cores",
+ "^core.*$",
+ false,
+ fun (C,Cs) -> [C|Cs] end,
+ []))
+ end
+ after
+ catch file:set_cwd(OrgCWD),
+ catch code:set_path(OrgPath),
+ case OrgPWD of
+ false -> ok;
+ _ -> catch os:putenv("PWD", OrgPWD)
+ end
+ end.
+
+
+dir(Config) ->
+ #ignore_cores{ign_dir = Dir} = ?config(ignore_cores, Config),
+ Dir.
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index a56746bbc4..4e93a593b3 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -57,6 +57,8 @@
%% System probe functions that might be handy to check from the shell
-export([unix_free/1]).
+-export([allocate/1]).
+
-include_lib("test_server/include/test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -87,7 +89,7 @@ groups() ->
cur_dir_1a, cur_dir_1b]},
{files, [],
[{group, open}, {group, pos}, {group, file_info},
- truncate, sync, datasync, advise, large_write]},
+ truncate, sync, datasync, advise, large_write, allocate]},
{open, [],
[open1, modes, close, access, read_write, pread_write,
append, exclusive]},
@@ -1359,6 +1361,76 @@ check_large_write(Dog, Fd, _, _, []) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+allocate(suite) -> [];
+allocate(doc) -> "Tests that ?PRIM_FILE:allocate/3 at least doesn't crash.";
+allocate(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Allocate = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_allocate.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?PRIM_FILE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd, 1, iolist_size([Line1, Line2])),
+ ?line ok = ?PRIM_FILE:write(Fd, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd),
+
+ ?line {ok, Fd2} = ?PRIM_FILE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd2, 1, iolist_size(Line1)),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd2),
+
+ ?line {ok, Fd3} = ?PRIM_FILE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd3, 1, iolist_size(Line1) + 1),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd3),
+
+ ?line {ok, Fd4} = ?PRIM_FILE:open(Allocate, [write, binary]),
+ allocate_and_assert(Fd4, 1, 4 * iolist_size([Line1, Line2])),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd4),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+allocate_and_assert(Fd, Offset, Length) ->
+ % Just verify that calls to ?PRIM_FILE:allocate/3 don't crash or have
+ % any other negative side effect. We can't really asssert against a
+ % specific return value, because support for file space pre-allocation
+ % depends on the OS, OS version and underlying filesystem.
+ %
+ % The Linux kernel added support for fallocate() in version 2.6.23,
+ % which currently works only for the ext4, ocfs2, xfs and btrfs file
+ % systems. posix_fallocate() is available in glibc as of version
+ % 2.1.94, but it was buggy until glibc version 2.7.
+ %
+ % Mac OS X, as of version 10.3, supports the fcntl operation F_PREALLOCATE.
+ %
+ % Solaris supports posix_fallocate() but only for the UFS file system
+ % apparently (not supported for ZFS).
+ %
+ % FreeBSD 9.0 is the first FreeBSD release supporting posix_fallocate().
+ %
+ % For Windows there's apparently no way to pre-allocate file space, at
+ % least with similar API/semantics as posix_fallocate(), fallocate() or
+ % fcntl F_PREALLOCATE.
+ Result = ?PRIM_FILE:allocate(Fd, Offset, Length),
+ case os:type() of
+ {win32, _} ->
+ ?line {error, enotsup} = Result;
+ _ ->
+ ?line _ = Result
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
delete_a(suite) -> [];
delete_a(doc) -> [];
delete_a(Config) when is_list(Config) ->
diff --git a/lib/kernel/test/ram_file_SUITE.erl b/lib/kernel/test/ram_file_SUITE.erl
index ab95a3ff5f..5c4437d4d3 100644
--- a/lib/kernel/test/ram_file_SUITE.erl
+++ b/lib/kernel/test/ram_file_SUITE.erl
@@ -1,7 +1,8 @@
+%% -*- coding: utf-8 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2012. 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
@@ -167,7 +168,7 @@ pread_pwrite(suite) ->
pread_pwrite(doc) ->
["Test that pread/2,3 and pwrite/2,3 works."];
pread_pwrite(Config) when is_list(Config) ->
- ?line Str = "Flygande b�ckaziner s�ka hwila p� mjuqa tuvor x",
+ ?line Str = "Flygande bäckaziner söka hwila på mjuqa tuvor x",
?line Bin = list_to_binary(Str),
%%
pread_pwrite_test(?FILE_MODULE, Str, [ram, read, write]),
@@ -206,7 +207,7 @@ position(suite) ->
position(doc) ->
["Test that position/2 works."];
position(Config) when is_list(Config) ->
- ?line Str = "Att vara eller icke vara, det �r fr�gan. ",
+ ?line Str = "Att vara eller icke vara, det är frågan. ",
?line Bin = list_to_binary(Str),
%%
position_test(?FILE_MODULE, Str, [ram, read]),
@@ -287,8 +288,8 @@ truncate(suite) ->
truncate(doc) ->
["Test that truncate/1 works."];
truncate(Config) when is_list(Config) ->
- ?line Str = "M�n �dlare att lida och f�rdraga "
- ++ "ett bittert �des stygn av pilar, ",
+ ?line Str = "Mån ädlare att lida och fördraga "
+ ++ "ett bittert ödes stygn av pilar, ",
?line Bin = list_to_binary(Str),
%%
ok = truncate_test(?FILE_MODULE, Str, [ram, read, write]),
@@ -331,7 +332,7 @@ sync(suite) ->
sync(doc) ->
["Test that sync/1 at least does not crash."];
sync(Config) when is_list(Config) ->
- ?line Str = "�n att ta till vapen mot ett hav av kval. ",
+ ?line Str = "än att ta till vapen mot ett hav av kval. ",
?line Bin = list_to_binary(Str),
%%
sync_test(?FILE_MODULE, Str, [ram, read, write]),
@@ -365,8 +366,8 @@ get_set_file(doc) ->
["Tests get_file/1, set_file/2, get_file_close/1 and get_size/1."];
get_set_file(Config) when is_list(Config) ->
%% These two strings should not be of equal length.
- ?line Str = "N�r h�gan nord blir sn�bet�ckt, ",
- ?line Str2 = "f�r alla harar byta dr�kt. ",
+ ?line Str = "När högan nord blir snöbetäckt, ",
+ ?line Str2 = "får alla harar byta dräkt. ",
?line Bin = list_to_binary(Str),
?line Bin2 = list_to_binary(Str2),
%%