From be353901879b3cccda7cd01947936cf1550dea04 Mon Sep 17 00:00:00 2001
From: Richard Carlsson <richardc@klarna.com>
Date: Tue, 1 Dec 2015 11:25:12 +0100
Subject: Check exit status in init:stop/1 and simplify documentation

---
 erts/doc/src/init.xml       | 10 ++--------
 erts/preloaded/src/init.erl | 36 ++++++++++++++++++++++++++----------
 2 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml
index 84a5aea335..3546099fad 100644
--- a/erts/doc/src/init.xml
+++ b/erts/doc/src/init.xml
@@ -178,14 +178,8 @@
       <name name="stop" arity="0"/>
       <fsummary>Take down an Erlang node smoothly</fsummary>
       <desc>
-        <p>All applications are taken down smoothly, all code is
-          unloaded, and all ports are closed before the system
-          terminates. If the <c>-heart</c> command line flag was given, 
-          the <c>heart</c> program is terminated before the Erlang node
-          terminates. Refer to <c>heart(3)</c> for more information.</p>
-        <p>To limit the shutdown time, the time <c>init</c> is allowed
-          to spend taking down applications, the <c>-shutdown_time</c>
-          command line flag should be used.</p>
+        <p>The same as
+	<seealso marker="#stop/1"><c>stop(0)</c></seealso>.</p>
       </desc>
     </func>
     <func>
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index 618b53f6bb..04c5210aa3 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -90,6 +90,8 @@
 
 -define(ON_LOAD_HANDLER, init__boot__on_load_handler).
 
+-define(MAX_HALT_STRING_SIZE, 199).
+
 debug(false, _) -> ok;
 debug(_, T)     -> erlang:display(T).
 
@@ -173,7 +175,25 @@ stop() -> init ! {stop,stop}, ok.
 
 -spec stop(Status) -> 'ok' when
       Status :: non_neg_integer() | string().
-stop(Status) -> init ! {stop,{stop,Status}}, ok.
+stop(Status) when is_integer(Status), Status >= 0 ->
+    stop_1(Status);
+stop(Status) when is_list(Status) ->
+    case is_bytelist(Status) of
+        true ->
+            stop_1(limit_halt_string(Status));
+        false ->
+            erlang:error(badarg)
+    end;
+stop(_) ->
+    erlang:error(badarg).
+
+is_bytelist([B|Bs]) when is_integer(B), B >= 0, B < 256 -> is_bytelist(Bs);
+is_bytelist([]) -> true;
+is_bytelist(_) -> false.
+
+%% Note that we check the type of Status beforehand to ensure that
+%% the call to halt(Status) by the init process cannot fail
+stop_1(Status) -> init ! {stop,{stop,Status}}, ok.
 
 -spec boot(BootArgs) -> no_return() when
       BootArgs :: [binary()].
@@ -285,16 +305,12 @@ things_to_string([]) ->
     "".
 
 halt_string(String, List) ->
-    HaltString = String ++ things_to_string(List),
-    if
-	length(HaltString)<199 -> HaltString;
-	true -> first198(HaltString, 198)
-    end.
+    limit_halt_string(String ++ things_to_string(List)).
 
-first198([H|T], N) when N>0 ->
-    [H|first198(T, N-1)];
-first198(_, 0) ->
-    [].
+limit_halt_string(String) when length(String) < ?MAX_HALT_STRING_SIZE ->
+    String;
+limit_halt_string(String) ->
+    lists:sublist(String, ?MAX_HALT_STRING_SIZE-1).
 
 %% String = string()
 %% List = [string() | atom() | pid() | number()]
-- 
cgit v1.2.3