diff --git a/.github/dockerfiles/Dockerfile.ubuntu-base b/.github/dockerfiles/Dockerfile.ubuntu-base
index dc8b28e1c8a5..76952b39a596 100644
--- a/.github/dockerfiles/Dockerfile.ubuntu-base
+++ b/.github/dockerfiles/Dockerfile.ubuntu-base
@@ -48,6 +48,13 @@ RUN apt-get install -y git && \
done && \
rm -rf ~/.kerl
+## We use tmux to test terminals
+RUN apt-get install -y libevent-dev libutf8proc-dev && \
+ cd /tmp && wget https://github.com/tmux/tmux/releases/download/3.2a/tmux-3.2a.tar.gz && \
+ tar xvzf tmux-3.2a.tar.gz && cd tmux-3.2a && \
+ ./configure --enable-static --enable-utf8proc && \
+ make && make install
+
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
ARG USER=gitpod
diff --git a/.github/scripts/build-macos.sh b/.github/scripts/build-macos.sh
index 82b07bac7b7c..73c35a6a22d3 100755
--- a/.github/scripts/build-macos.sh
+++ b/.github/scripts/build-macos.sh
@@ -1,12 +1,19 @@
#!/bin/sh
-export MAKEFLAGS=-j$(getconf _NPROCESSORS_ONLN)
-export ERL_TOP=`pwd`
-export RELEASE_ROOT=$ERL_TOP/release
+export MAKEFLAGS="-j$(getconf _NPROCESSORS_ONLN)"
+export ERL_TOP="$(pwd)"
export ERLC_USE_SERVER=true
+export RELEASE_ROOT="$ERL_TOP/release"
+BUILD_DOCS=false
-./otp_build configure \
- --disable-dynamic-ssl-lib
+if [ "$1" = "build_docs" ]; then
+ BUILD_DOCS=true
+ shift
+fi
+
+./otp_build configure $*
./otp_build boot -a
-./otp_build release -a $RELEASE_ROOT
-make release_docs DOC_TARGETS=chunks
+./otp_build release -a "$RELEASE_ROOT"
+if $BUILD_DOCS; then
+ make release_docs DOC_TARGETS=chunks
+fi
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index 7bdda4c618e6..e24f94eec5de 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -127,7 +127,7 @@ jobs:
tar -xzf ./otp_src.tar.gz
export PATH=$PWD/wxWidgets/release/bin:$PATH
cd otp
- $GITHUB_WORKSPACE/.github/scripts/build-macos.sh
+ $GITHUB_WORKSPACE/.github/scripts/build-macos.sh build_docs --disable-dynamic-ssl-lib
tar -czf otp_macos_$(cat OTP_VERSION)_x86-64.tar.gz -C release .
- name: Test Erlang
@@ -152,6 +152,7 @@ jobs:
runs-on: macos-12
needs: pack
steps:
+ - uses: actions/checkout@v2
- name: Download source archive
uses: actions/download-artifact@v2
with:
@@ -161,12 +162,7 @@ jobs:
run: |
tar -xzf ./otp_src.tar.gz
cd otp
- export ERL_TOP=`pwd`
- export MAKEFLAGS="-j$(($(nproc) + 2)) -O"
- export ERLC_USE_SERVER=true
- ./otp_build configure --xcomp-conf=./xcomp/erl-xcomp-arm64-ios.conf --without-ssl
- ./otp_build boot -a
- ./otp_build release -a
+ $GITHUB_WORKSPACE/.github/scripts/build-macos.sh --xcomp-conf=./xcomp/erl-xcomp-arm64-ios.conf --without-ssl
- name: Package .xcframework
run: |
diff --git a/HOWTO/INSTALL-WIN32.md b/HOWTO/INSTALL-WIN32.md
index 4ad0159bcd25..bd8387aaae65 100644
--- a/HOWTO/INSTALL-WIN32.md
+++ b/HOWTO/INSTALL-WIN32.md
@@ -68,7 +68,7 @@ This is the short story though, for the experienced and impatient:
Ensures that the Erlang runtime system never tries to read
any input. Implies
Starts an Erlang runtime system with no shell. This flag
makes it possible to have the Erlang runtime system as a
diff --git a/erts/doc/src/erlsrv_cmd.xml b/erts/doc/src/erlsrv_cmd.xml
index e8f066b21b5d..fe952f690e66 100644
--- a/erts/doc/src/erlsrv_cmd.xml
+++ b/erts/doc/src/erlsrv_cmd.xml
@@ -112,8 +112,7 @@
The location of the Erlang emulator.
The default is the
If the system uses release handling, this is to be set to a
program similar to
This example is, as can be seen, run in an environment where the terminal supports Unicode input and output.
+The
Starts the interactive shell if it has not already been started. + It can be used to programatically start the shell from an escript + or when erl is started with the -noinput or -noshell flags.
+Starts the interactive shell if it has not already been started.
+ It can be used to programatically start the shell from an
+
Starts the interactive shell as if
Starts the interactive shell using
+
Starts the interactive shell using
+
Starts the interactive shell using as if
+
Can be used to determine how many results are saved by the Erlang shell.
+The slogan printed when starting an Erlang shell. Example:
+
+$ erl -stdlib shell_session_slogan '"Test slogan"'
+Erlang/OTP 26 [DEVELOPMENT] [erts-13.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]
+
+Test slogan
+1>
+
+ The slogan printed when starting the Erlang shell subsystem. Example:
+
+$ erl -stdlib shell_slogan '"Test slogan"'
+Test slogan
+Eshell V13.0.2 (abort with ^G)
+1>
+
+ The default is the return value of
Can be used to determine how the Erlang shell outputs lists of diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl index 6078c5e67bd1..97088dd36147 100644 --- a/lib/stdlib/src/edlin.erl +++ b/lib/stdlib/src/edlin.erl @@ -191,9 +191,9 @@ key_map($\^E, none) -> end_of_line; key_map($\^F, none) -> forward_char; key_map($\^H, none) -> backward_delete_char; key_map($\t, none) -> tab_expand; +key_map($\^K, none) -> kill_line; key_map($\^L, none) -> redraw_line; key_map($\n, none) -> new_line; -key_map($\^K, none) -> kill_line; key_map($\r, none) -> new_line; key_map($\^T, none) -> transpose_char; key_map($\^U, none) -> ctlu; @@ -320,9 +320,9 @@ do_op({search, backward_delete_char}, [_|Bef], Aft, Rs) -> {{Bef,NAft}, [{insert_chars, unicode, NAft}, {delete_chars,-Offset}|Rs], search}; -do_op({search, backward_delete_char}, [], _Aft, Rs) -> - Aft="': ", - {{[],Aft}, Rs, search}; +do_op({search, backward_delete_char}, [], Aft, Rs) -> + NAft="': ", + {{[],NAft}, [{insert_chars, unicode, NAft}, {delete_chars,-cp_len(Aft)}|Rs], search}; do_op({search, skip_up}, Bef, Aft, Rs) -> Offset= cp_len(Aft), NAft = "': ", @@ -621,148 +621,3 @@ cp_len(Str) -> cp_len([GC|R], Len) -> cp_len(R, Len + gc_len(GC)); cp_len([], Len) -> Len. - -%% %% expand(CurrentBefore) -> -%% %% {yes,Expansion} | no -%% %% Try to expand the word before as either a module name or a function -%% %% name. We can handle white space around the seperating ':' but the -%% %% function name must be on the same line. CurrentBefore is reversed -%% %% and over_word/3 reverses the characters it finds. In certain cases -%% %% possible expansions are printed. - -%% expand(Bef0) -> -%% {Bef1,Word,_} = over_word(Bef0, [], 0), -%% case over_white(Bef1, [], 0) of -%% {[$:|Bef2],_White,_Nwh} -> -%% {Bef3,_White1,_Nwh1} = over_white(Bef2, [], 0), -%% {_,Mod,_Nm} = over_word(Bef3, [], 0), -%% expand_function_name(Mod, Word); -%% {_,_,_} -> -%% expand_module_name(Word) -%% end. - -%% expand_module_name(Prefix) -> -%% match(Prefix, code:all_loaded(), ":"). - -%% expand_function_name(ModStr, FuncPrefix) -> -%% Mod = list_to_atom(ModStr), -%% case erlang:module_loaded(Mod) of -%% true -> -%% L = apply(Mod, module_info, []), -%% case lists:keyfind(exports, 1, L) of -%% {_, Exports} -> -%% match(FuncPrefix, Exports, "("); -%% _ -> -%% no -%% end; -%% false -> -%% no -%% end. - -%% match(Prefix, Alts, Extra) -> -%% Matches = match1(Prefix, Alts), -%% case longest_common_head([N || {N,_} <- Matches]) of -%% {partial, []} -> -%% print_matches(Matches), -%% no; -%% {partial, Str} -> -%% case lists:nthtail(length(Prefix), Str) of -%% [] -> -%% print_matches(Matches), -%% {yes, []}; -%% Remain -> -%% {yes, Remain} -%% end; -%% {complete, Str} -> -%% {yes, lists:nthtail(length(Prefix), Str) ++ Extra}; -%% no -> -%% no -%% end. - -%% %% Print the list of names L in multiple columns. -%% print_matches(L) -> -%% io:nl(), -%% col_print(lists:sort(L)), -%% ok. - -%% col_print([]) -> ok; -%% col_print(L) -> col_print(L, field_width(L), 0). - -%% col_print(X, Width, Len) when Width + Len > 79 -> -%% io:nl(), -%% col_print(X, Width, 0); -%% col_print([{H0,A}|T], Width, Len) -> -%% H = if -%% %% If the second element is an integer, we assume it's an -%% %% arity, and meant to be printed. -%% integer(A) -> -%% H0 ++ "/" ++ integer_to_list(A); -%% true -> -%% H0 -%% end, -%% io:format("~-*s",[Width,H]), -%% col_print(T, Width, Len+Width); -%% col_print([], _, _) -> -%% io:nl(). - -%% field_width([{H,_}|T]) -> field_width(T, length(H)). - -%% field_width([{H,_}|T], W) -> -%% case length(H) of -%% L when L > W -> field_width(T, L); -%% _ -> field_width(T, W) -%% end; -%% field_width([], W) when W < 40 -> -%% W + 4; -%% field_width([], _) -> -%% 40. - -%% match1(Prefix, Alts) -> -%% match1(Prefix, Alts, []). - -%% match1(Prefix, [{H,A}|T], L) -> -%% case prefix(Prefix, Str = atom_to_list(H)) of -%% true -> -%% match1(Prefix, T, [{Str,A}|L]); -%% false -> -%% match1(Prefix, T, L) -%% end; -%% match1(_, [], L) -> -%% L. - -%% longest_common_head([]) -> -%% no; -%% longest_common_head(LL) -> -%% longest_common_head(LL, []). - -%% longest_common_head([[]|_], L) -> -%% {partial, reverse(L)}; -%% longest_common_head(LL, L) -> -%% case same_head(LL) of -%% true -> -%% [[H|_]|_] = LL, -%% LL1 = all_tails(LL), -%% case all_nil(LL1) of -%% false -> -%% longest_common_head(LL1, [H|L]); -%% true -> -%% {complete, reverse([H|L])} -%% end; -%% false -> -%% {partial, reverse(L)} -%% end. - -%% same_head([[H|_]|T1]) -> same_head(H, T1). - -%% same_head(H, [[H|_]|T]) -> same_head(H, T); -%% same_head(_, []) -> true; -%% same_head(_, _) -> false. - -%% all_tails(LL) -> all_tails(LL, []). - -%% all_tails([[_|T]|T1], L) -> all_tails(T1, [T|L]); -%% all_tails([], L) -> L. - -%% all_nil([]) -> true; -%% all_nil([[] | Rest]) -> all_nil(Rest); -%% all_nil(_) -> false. diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl index 18f6ef3ddee9..46d5cd4ae82f 100644 --- a/lib/stdlib/src/io.erl +++ b/lib/stdlib/src/io.erl @@ -213,15 +213,18 @@ get_password(Io) -> -type opt_pair() :: {'binary', boolean()} | {'echo', boolean()} | {'expand_fun', expand_fun()} - | {'encoding', encoding()}. + | {'encoding', encoding()} + | {atom(), term()}. +-type get_opt_pair() :: opt_pair() + | {'terminal', boolean()}. --spec getopts() -> [opt_pair()] | {'error', Reason} when +-spec getopts() -> [get_opt_pair()] | {'error', Reason} when Reason :: term(). getopts() -> getopts(default_input()). --spec getopts(IoDevice) -> [opt_pair()] | {'error', Reason} when +-spec getopts(IoDevice) -> [get_opt_pair()] | {'error', Reason} when IoDevice :: device(), Reason :: term(). diff --git a/lib/stdlib/src/shell.erl b/lib/stdlib/src/shell.erl index 7de78758b03b..8d48ff7b2a03 100644 --- a/lib/stdlib/src/shell.erl +++ b/lib/stdlib/src/shell.erl @@ -20,10 +20,10 @@ -module(shell). -export([start/0, start/1, start/2, server/1, server/2, history/1, results/1]). --export([whereis_evaluator/0, whereis_evaluator/1]). -export([start_restricted/1, stop_restricted/0]). -export([local_allowed/3, non_local_allowed/3]). -export([catch_exception/1, prompt_func/1, strings/1]). +-export([start_interactive/0, start_interactive/1]). -define(LINEMAX, 30). -define(CHAR_MAX, 60). @@ -48,6 +48,16 @@ non_local_allowed({init,stop},[],State) -> non_local_allowed(_,_,State) -> {false,State}. +-spec start_interactive() -> ok | {error, already_started | enottty}. +start_interactive() -> + user_drv:start_shell(). +-spec start_interactive(noshell | mfa() | {node(), mfa()} | {remote, string()}) -> + ok | {error, already_started | enottty}. +start_interactive({Node, {M, F, A}}) -> + user_drv:start_shell(#{ initial_shell => {Node, M, F ,A} }); +start_interactive(InitialShell) -> + user_drv:start_shell(#{ initial_shell => InitialShell }). + -spec start() -> pid(). start() -> @@ -60,60 +70,14 @@ start(NoCtrlG) -> start(NoCtrlG, StartSync) -> _ = code:ensure_loaded(user_default), - spawn(fun() -> server(NoCtrlG, StartSync) end). - -%% Find the pid of the current evaluator process. --spec whereis_evaluator() -> 'undefined' | pid(). - -whereis_evaluator() -> - %% locate top group leader, always registered as user - %% can be implemented by group (normally) or user - %% (if oldshell or noshell) - case whereis(user) of - undefined -> - undefined; - User -> - %% get user_drv pid from group, or shell pid from user - case group:interfaces(User) of - [] -> % old- or noshell - case user:interfaces(User) of - [] -> - undefined; - [{shell,Shell}] -> - whereis_evaluator(Shell) - end; - [{user_drv,UserDrv}] -> - %% get current group pid from user_drv - case user_drv:interfaces(UserDrv) of - [] -> - undefined; - [{current_group,Group}] -> - %% get shell pid from group - GrIfs = group:interfaces(Group), - case lists:keyfind(shell, 1, GrIfs) of - {shell, Shell} -> - whereis_evaluator(Shell); - false -> - undefined - end - end - end - end. - --spec whereis_evaluator(pid()) -> 'undefined' | pid(). - -whereis_evaluator(Shell) -> - case process_info(Shell, dictionary) of - {dictionary,Dict} -> - case lists:keyfind(evaluator, 1, Dict) of - {_, Eval} when is_pid(Eval) -> - Eval; - _ -> - undefined - end; - _ -> - undefined - end. + Ancestors = [self() | case get('$ancestors') of + undefined -> []; + Anc -> Anc + end], + spawn(fun() -> + put('$ancestors', Ancestors), + server(NoCtrlG, StartSync) + end). %% Call this function to start a user restricted shell %% from a normal shell session. @@ -201,12 +165,24 @@ server(StartSync) -> undefined end, - case get(no_control_g) of - true -> - io:fwrite(<<"Eshell V~s\n">>, [erlang:system_info(version)]); - _undefined_or_false -> - io:fwrite(<<"Eshell V~s (abort with ^G)\n">>, - [erlang:system_info(version)]) + JCL = + case get(no_control_g) of + true -> " (type help(). for help)"; + _ -> " (press Ctrl+G to abort, type help(). for help)" + end, + DefaultSessionSlogan = + io_lib:format(<<"Eshell V~s">>, [erlang:system_info(version)]), + SessionSlogan = + case application:get_env(stdlib, shell_session_slogan, DefaultSessionSlogan) of + SloganFun when is_function(SloganFun, 0) -> + SloganFun(); + Slogan -> + Slogan + end, + try + io:fwrite("~ts~ts\n",[unicode:characters_to_list(SessionSlogan),JCL]) + catch _:_ -> + io:fwrite("Warning! The slogan \"~p\" could not be printed.\n",[SessionSlogan]) end, erase(no_control_g), diff --git a/lib/stdlib/src/shell_docs.erl b/lib/stdlib/src/shell_docs.erl index e42b5bb5b864..201e842cb1e7 100644 --- a/lib/stdlib/src/shell_docs.erl +++ b/lib/stdlib/src/shell_docs.erl @@ -1005,18 +1005,18 @@ nl(Chars) -> init_ansi(#config{ ansi = undefined, io_opts = Opts }) -> %% We use this as our heuristic to see if we should print ansi or not case {application:get_env(kernel, shell_docs_ansi), + proplists:get_value(tty, Opts, false), proplists:is_defined(echo, Opts) andalso - proplists:is_defined(expand_fun, Opts), - os:type()} of + proplists:is_defined(expand_fun, Opts)} of {{ok,false}, _, _} -> put(ansi, noansi); {{ok,true}, _, _} -> put(ansi, []); - {_, _, {win32,_}} -> - put(ansi, noansi); - {_, true,_} -> + {_, true, _} -> + put(ansi, []); + {_, _, true} -> put(ansi, []); - {_, false,_} -> + {_, _, false} -> put(ansi, noansi) end; init_ansi(#config{ ansi = true }) -> diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src index 90c19b2cade4..653e92812784 100644 --- a/lib/stdlib/src/stdlib.app.src +++ b/lib/stdlib/src/stdlib.app.src @@ -112,6 +112,6 @@ dets]}, {applications, [kernel]}, {env, []}, - {runtime_dependencies, ["sasl-3.0","kernel-8.4","erts-@OTP-17934@","crypto-4.5", + {runtime_dependencies, ["sasl-3.0","kernel-@OTP-17932@","erts-@OTP-17934@","crypto-4.5", "compiler-5.0"]} ]}. diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 0ee9ee6f6d79..0503db2c62ae 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -164,6 +164,7 @@ release_tests_spec: make_emakefile $(ERL_FILES) $(COVERFILE) $(EXTRA_FILES) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" @tar cf - *_SUITE_data property_test | (cd "$(RELSYSDIR)"; tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)/stdlib_SUITE_data" $(INSTALL_DATA) $(ERL_TOP)/make/otp_version_tickets "$(RELSYSDIR)/stdlib_SUITE_data" release_docs_spec: diff --git a/lib/stdlib/test/escript_SUITE_data/arg_overflow b/lib/stdlib/test/escript_SUITE_data/arg_overflow index dd5accc05184..e3138cabbdaf 100755 --- a/lib/stdlib/test/escript_SUITE_data/arg_overflow +++ b/lib/stdlib/test/escript_SUITE_data/arg_overflow @@ -1,5 +1,5 @@ #! /usr/bin/env escript %% -*- erlang -*- -%%!x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x +%%!-x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x -x main(_) -> halt(0). diff --git a/lib/stdlib/test/escript_SUITE_data/linebuf_overflow b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow index 33133c1ce903..018be1f26d0a 100755 --- a/lib/stdlib/test/escript_SUITE_data/linebuf_overflow +++ b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow @@ -1,5 +1,5 @@ #! /usr/bin/env escript %% -*- erlang -*- -%%!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +%%!-v xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx main(_) -> halt(0). diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 482e233493b5..bc96992ce2a3 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -24,7 +24,8 @@ -export([setopts_getopts/1,unicode_options/1,unicode_options_gen/1, binary_options/1, read_modes_gl/1, - read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1,unicode_prompt/1]). + read_modes_ogl/1, broken_unicode/1,eof_on_pipe/1, + unicode_prompt/1, shell_slogan/1]). -export([io_server_proxy/1,start_io_server_proxy/0, proxy_getall/1, @@ -32,7 +33,7 @@ %% For spawn -export([answering_machine1/3, answering_machine2/3]). --export([uprompt/1]). +-export([uprompt/1, slogan/0, session_slogan/0]). %%-define(debug, true). @@ -49,7 +50,8 @@ suite() -> all() -> [setopts_getopts, unicode_options, unicode_options_gen, binary_options, read_modes_gl, read_modes_ogl, - broken_unicode, eof_on_pipe, unicode_prompt]. + broken_unicode, eof_on_pipe, unicode_prompt, + shell_slogan]. groups() -> []. @@ -115,14 +117,42 @@ unicode_prompt(Config) when is_list(Config) -> {putline, "hej"}, {expect, "\\Q\"hej\\n\"\\E"}, {putline, "io:setopts([{binary,true}])."}, - {expect, "[\n ]ok"}, + {expect, "[\n ]\\?*ok"}, {putline, "io:get_line('')."}, {putline, "hej"}, - {expect,"[\n ]hej"}, + {expect,"[\n ]\\?*hej"}, {expect, "\\Q<<\"hej\\n\">>\\E"} ],[],"",["-oldshell","-pa",PA]), ok. +%% Test that an Unicode prompt does not crash the shell. +shell_slogan(Config) when is_list(Config) -> + PA = filename:dirname(code:which(?MODULE)), + case proplists:get_value(default_shell,Config) of + new -> + rtnode:run( + [{expect, "\\Q"++string:trim(erlang:system_info(system_version))++"\\E"}, + {expect, "\\Q"++io_lib:format("Eshell V~s (press Ctrl+G to abort, type help(). for help)",[erlang:system_info(version)])++"\\E"} + ],[],"",[]), + rtnode:run( + [{expect, "\nTest slogan"}, + {expect, "\nTest session slogan \\("} + ],[],"",["-stdlib","shell_slogan","\"Test slogan\"", + "-stdlib","shell_session_slogan","\"Test session slogan\""]), + rtnode:run( + [{expect, "\nTest slogan"}, + {expect, "\\Q\nTest session slogan (\\E"} + ],[],"",["-stdlib","shell_slogan","fun io_proto_SUITE:slogan/0", + "-stdlib","shell_session_slogan","fun io_proto_SUITE:session_slogan/0", + "-pa",PA]); + _ -> + ok + end. + +slogan() -> + "Test slogan". +session_slogan() -> + "Test session slogan". %% Check io:setopts and io:getopts functions. setopts_getopts(Config) when is_list(Config) -> diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl index b38dee47e7e1..6aedfb94a272 100644 --- a/lib/stdlib/test/shell_SUITE.erl +++ b/lib/stdlib/test/shell_SUITE.erl @@ -36,6 +36,8 @@ -export([ start_restricted_from_shell/1, start_restricted_on_command_line/1,restricted_local/1]). +-export([ start_interactive/1 ]). + %% Internal export. -export([otp_5435_2/0, prompt1/1, prompt2/1, prompt3/1, prompt4/1, prompt5/1]). @@ -3014,6 +3016,57 @@ otp_14296(Config) when is_list(Config) -> {error, {_,_,"bad term"}} = TF("1, 2"), ok. +start_interactive(_Config) -> + rtnode:run( + [{expect, "test"}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive() end}, + {expect, "1>"}, + {expect, "2>"} + ],[],"",["-noinput","-eval","io:format(\"test~n\")"]), + + rtnode:run( + [{expect, "test"}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive({shell,start,[]}) end}, + {expect, "1>"}, + {expect, "2>"} + ],[],"",["-noinput","-eval","io:format(\"test~n\")"]), + + rtnode:run( + [{expect, "test"}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive(noshell) end}, + {eval, fun() -> io:format(user,"~ts",[io:get_line(user, "")]) end}, + {expect, "test\\."}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive() end}, + {expect, "1>"}, + {expect, "2>"} + ],[],"",["-noinput","-eval","io:format(\"test~n\")"]), + + {ok, RPeer, RNode} = ?CT_PEER(), + unlink(RPeer), + SRNode = atom_to_list(RNode), + rtnode:run( + [{expect, "test"}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive({remote, SRNode}) end}, + {expect, "\\Q("++SRNode++")\\E2>"} + ],[],"",["-noinput","-eval","io:format(\"test~n\")"]), + + {ok, Peer, Node} = ?CT_PEER(), + unlink(Peer), + SNode = atom_to_list(Node), + rtnode:run( + [{expect, "test"}, + {putline, "test."}, + {eval, fun() -> shell:start_interactive({Node, {shell,start,[]}}) end}, + {expect, "\\Q("++SNode++")\\E2>"} + ],[],"",["-noinput","-eval","io:format(\"test~n\")"]), + + ok. + term_to_string(T) -> lists:flatten(io_lib:format("~w", [T])). diff --git a/lib/stdlib/test/shell_docs_SUITE.erl b/lib/stdlib/test/shell_docs_SUITE.erl index 028e2c0aba64..b7d85204d84b 100644 --- a/lib/stdlib/test/shell_docs_SUITE.erl +++ b/lib/stdlib/test/shell_docs_SUITE.erl @@ -255,14 +255,15 @@ render_non_native(_Config) -> beam_language = not_erlang, format = <<"text/asciidoc">>, module_doc = #{<<"en">> => <<"This is\n\npure text">>}, - docs= [] + docs = [] }, <<"\n\tnot_an_erlang_module\n\n" " This is\n" " \n" " pure text\n">> = - unicode:characters_to_binary(shell_docs:render(not_an_erlang_module, Docs, #{})), + unicode:characters_to_binary( + shell_docs:render(not_an_erlang_module, Docs, #{ ansi => false })), ok. diff --git a/make/configure.ac b/make/configure.ac index e0d4103b6edb..1276caecbcac 100644 --- a/make/configure.ac +++ b/make/configure.ac @@ -212,10 +212,6 @@ AS_HELP_STRING([--disable-parallel-configure], [disable parallel execution of co AC_ARG_ENABLE(dirty-schedulers, AS_HELP_STRING([--enable-dirty-schedulers], [enable dirty scheduler support])) -AC_ARG_ENABLE(plain-emulator, -AS_HELP_STRING([--enable-plain-emulator], [enable threaded non-smp emulator]) -AS_HELP_STRING([--disable-plain-emulator], [disable threaded non-smp emulator])) - AC_ARG_WITH(termcap, AS_HELP_STRING([--with-termcap], [use termcap (default)]) AS_HELP_STRING([--without-termcap], diff --git a/make/test_target_script.sh b/make/test_target_script.sh index a837533c7a86..7fc9d5b89d3d 100755 --- a/make/test_target_script.sh +++ b/make/test_target_script.sh @@ -316,7 +316,7 @@ then -pz "$ERL_TOP/lib/common_test/test_server" \ -pz "." \ -ct_test_vars "{net_dir,\"\"}" \ - -noshell \ + -noinput \ -sname test_server \ -rsh ssh \ ${ERL_ARGS} @@ -337,7 +337,7 @@ else -pz "$WIN_ERL_TOP/lib/common_test/test_server"\ -pz "."\ -ct_test_vars "{net_dir,\"\"}"\ - -noshell\ + -noinput\ -sname test_server\ -rsh ssh\ ${ERL_ARGS} diff --git a/otp_build b/otp_build index 7b35b39fc2c5..284da6389320 100755 --- a/otp_build +++ b/otp_build @@ -1001,8 +1001,7 @@ do_tests () do_debuginfo_win32 () { setup_make - (cd erts/emulator && $MAKE MAKE="$MAKE" TARGET=$TARGET FLAVOR=smp debug &&\ - $MAKE MAKE="$MAKE" TARGET=$TARGET FLAVOR=plain debug) || exit 1 + (cd erts/emulator && $MAKE MAKE="$MAKE" TARGET=$TARGET debug) || exit 1 if [ -z "$1" ]; then RELDIR="$ERL_TOP/release/$TARGET" else @@ -1010,7 +1009,7 @@ do_debuginfo_win32 () fi BINDIR="$ERL_TOP/bin/$TARGET" EVSN=`grep '^VSN' erts/vsn.mk | sed 's,^VSN.*=[^0-9]*\([0-9].*\)$,@\1,g;s,^[^@].*,,g;s,^@,,g'` - for f in beam.debug.smp.dll beam.smp.pdb beam.debug.smp.dll.pdb erl.pdb werl.pdb erlexec.pdb; do + for f in beam.debug.smp.dll beam.smp.pdb beam.debug.smp.dll.pdb erl.pdb erlexec.pdb; do if [ -f $BINDIR/$f ]; then rm -f $RELDIR/erts-$EVSN/bin/$f cp $BINDIR/$f $RELDIR/erts-$EVSN/bin/$f @@ -1218,7 +1217,7 @@ case "$1" in do_configure "$@";; opt) do_boot;; - plain|smp) + smp) if [ $minus_x_flag = false ]; then TYPE=opt fi;