Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:26
erlang
3001-Add-the-os_cmd_shell-kernel-config-paramet...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3001-Add-the-os_cmd_shell-kernel-config-parameter-to-poin.patch of Package erlang
From 66fac5cbab8a9ff4528e70adff8c6cd0e867624f Mon Sep 17 00:00:00 2001 From: Yaroslav Maslennikov <ymaslenn@cisco.com> Date: Tue, 22 Oct 2024 12:52:48 +0200 Subject: [PATCH 1/3] Add the os_cmd_shell kernel config parameter to point to system shell for os:cmd/2 Initialize the parameter at startup Fix the test - restore the old shell after the test Add initialization to other tests that use os:cmd/2 Update os:cmd/2 description --- lib/kernel/doc/kernel_app.md | 4 ++ lib/kernel/src/kernel.erl | 1 + lib/kernel/src/os.erl | 70 ++++++++++++++-------- lib/kernel/test/os_SUITE.erl | 34 ++++++++++- lib/kernel/test/os_SUITE_data/Makefile.src | 8 ++- lib/kernel/test/os_SUITE_data/sys_shell.c | 6 ++ 6 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 lib/kernel/test/os_SUITE_data/sys_shell.c diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index 4984a350ab..0428b911de 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -643,6 +643,11 @@ MaxT = NetTickTime + NetTickTime / NetTi <p>See <seeguide marker="stdlib:unicode_usage#escripts-and-non-interactive-i-o"> Escripts and non-interactive I/O in Unicode Usage in Erlang</seeguide> for more details.</p> </item> + <tag><marker id="os_cmd_shell"/><c>os_cmd_shell = string()</c></tag> + <item> + <p>Specifies which shell to use when invoking system commands via `os:cmd/2`. + By default the shell is detected automatically.</p> + </item> </taglist> </section> diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl index 021676c33e..f53f3b1071 100644 --- a/lib/kernel/src/kernel.erl +++ b/lib/kernel/src/kernel.erl @@ -33,6 +33,7 @@ start(_, []) -> %% Setup the logger and configure the kernel logger environment ok = logger:internal_init_logger(), + ok = os:internal_init_cmd_shell(), case supervisor:start_link({local, kernel_sup}, kernel, []) of {ok, Pid} -> ok = erl_signal_handler:start(), diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl index adb31bd678..3f0895167a 100644 --- a/lib/kernel/src/os.erl +++ b/lib/kernel/src/os.erl @@ -37,6 +37,8 @@ a program to run on most platforms. -export([type/0, version/0, cmd/1, cmd/2, find_executable/1, find_executable/2]). +-export([internal_init_cmd_shell/0]). + -include("file.hrl"). -export_type([env_var_name/0, env_var_value/0, env_var_name_value/0]). @@ -581,35 +587,14 @@ get_option(Opt, Options, Default) -> _ -> throw(badopt) end. -mk_cmd({win32,Wtype}, Cmd) -> - Command = case {os:getenv("COMSPEC"),Wtype} of - {false,windows} -> lists:concat(["command.com /c", Cmd]); - {false,_} -> lists:concat(["cmd /c", Cmd]); - {Cspec,_} -> lists:concat([Cspec," /c",Cmd]) - end, +mk_cmd({win32,_}, Cmd) -> + {ok, Shell} = application:get_env(kernel, os_cmd_shell), + Command = lists:concat([Shell, " /c", Cmd]), {Command, [], [], <<>>}; mk_cmd(_,Cmd) -> %% Have to send command in like this in order to make sh commands like %% cd and ulimit available. - %% - %% We use an absolute path here because we do not want the path to be - %% searched in case a stale NFS handle is somewhere in the path before - %% the sh command. - %% - %% Check if the default shell is located in /bin/sh as expected usually - %% or in /system/bin/sh as implemented on Android. The raw option is - %% used to bypass the file server and speed up the file access. - Shell = case file:read_file_info("/bin/sh",[raw]) of - {ok,#file_info{type=regular}} -> - "/bin/sh"; - _ -> - case file:read_file_info("/system/bin/sh",[raw]) of - {ok,#file_info{type=regular}} -> - "/system/bin/sh"; - _ -> - "/bin/sh" - end - end, + {ok, Shell} = application:get_env(kernel, os_cmd_shell), {Shell ++ " -s unix:cmd", [out], %% We insert a new line after the command, in case the command %% contains a comment character. @@ -628,6 +613,40 @@ mk_cmd(_,Cmd) -> ["(", unicode:characters_to_binary(Cmd), "\n) </dev/null; echo \"\^D\"\n"], <<$\^D>>}. +internal_init_cmd_shell() -> + case application:get_env(kernel, os_cmd_shell) of + undefined -> + application:set_env(kernel, os_cmd_shell, + internal_init_cmd_shell(os:type())); + _ -> + ok + end. +internal_init_cmd_shell({win32,Wtype}) -> + case {os:getenv("COMSPEC"),Wtype} of + {false,windows} -> "command.com"; + {false,_} -> "cmd"; + {Cspec,_} -> Cspec + end; +internal_init_cmd_shell(_) -> + %% We use an absolute path here because we do not want the path to be + %% searched in case a stale NFS handle is somewhere in the path before + %% the sh command. + %% + %% Check if the default shell is located in /bin/sh as expected usually + %% or in /system/bin/sh as implemented on Android. The raw option is + %% used to bypass the file server. + case file:read_file_info("/bin/sh",[raw]) of + {ok,#file_info{type=regular}} -> + "/bin/sh"; + _ -> + case file:read_file_info("/system/bin/sh",[raw]) of + {ok,#file_info{type=regular}} -> + "/system/bin/sh"; + _ -> + "/bin/sh" + end + end. + validate(Term) -> try validate1(Term) catch error:_ -> throw(badarg) diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index 6d6ed337a0..8a5691bef7 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -28,7 +28,7 @@ find_executable/1, unix_comment_in_command/1, deep_list_command/1, large_output_command/1, background_command/0, background_command/1, message_leak/1, close_stdin/0, close_stdin/1, max_size_command/1, - perf_counter_api/1, error_info/1]). + perf_counter_api/1, error_info/1, os_cmd_shell/1,os_cmd_shell_peer/1]). -include_lib("common_test/include/ct.hrl"). @@ -43,7 +43,7 @@ all() -> find_executable, unix_comment_in_command, deep_list_command, large_output_command, background_command, message_leak, close_stdin, max_size_command, perf_counter_api, - error_info]. + error_info, os_cmd_shell, os_cmd_shell_peer]. groups() -> []. @@ -469,6 +469,36 @@ error_info(Config) -> ], error_info_lib:test_error_info(os, L). +os_cmd_shell(Config) -> + DataDir = proplists:get_value(data_dir, Config), + SysShell = filename:join(DataDir, "sys_shell"), + + {ok, OldShell} = application:get_env(kernel, os_cmd_shell), + try + application:set_env(kernel, os_cmd_shell, SysShell), + + %% os:cmd should not try to detect the shell location rather than use + %% the value from kernel:os_cmd_shell parameter + comp("sys_shell", os:cmd("ls")) + after + application:set_env(kernel, os_cmd_shell, OldShell) + end. + +os_cmd_shell_peer(Config) -> + DataDir = proplists:get_value(data_dir, Config), + SysShell = "\"" ++ filename:join(DataDir, "sys_shell") ++ "\"", + {ok, Peer, Node} = ?CT_PEER(["-kernel","os_cmd_shell", SysShell]), + try erpc:call(Node, os, cmd, ["ls"], rtnode:timeout(normal)) of + "sys_shell" -> ok; + Other -> ct:fail({unexpected, Other}) + catch + C:R:Stk -> + io:format("~p\n~p\n~p\n", [C,R,Stk]), + ct:fail(failed) + after + peer:stop(Peer) + end. + no_limit_for_opened_files() -> case os:type() of {unix, freebsd} -> diff --git a/lib/kernel/test/os_SUITE_data/Makefile.src b/lib/kernel/test/os_SUITE_data/Makefile.src index f83f781411..2141b320bb 100644 --- a/lib/kernel/test/os_SUITE_data/Makefile.src +++ b/lib/kernel/test/os_SUITE_data/Makefile.src @@ -3,7 +3,7 @@ LD = @LD@ CFLAGS = @CFLAGS@ -I@erl_include@ @DEFS@ CROSSLDFLAGS = @CROSSLDFLAGS@ -PROGS = my_echo@exe@ my_fds@exe@ +PROGS = my_echo@exe@ my_fds@exe@ sys_shell@exe@ all: $(PROGS) @@ -18,3 +18,9 @@ my_fds@exe@: my_fds@obj@ my_fds@obj@: my_fds.c $(CC) -c -o my_fds@obj@ $(CFLAGS) my_fds.c + +sys_shell@exe@: sys_shell@obj@ + $(LD) $(CROSSLDFLAGS) -o sys_shell sys_shell@obj@ @LIBS@ + +sys_shell@obj@: sys_shell.c + $(CC) -c -o sys_shell@obj@ $(CFLAGS) sys_shell.c diff --git a/lib/kernel/test/os_SUITE_data/sys_shell.c b/lib/kernel/test/os_SUITE_data/sys_shell.c new file mode 100644 index 0000000000..73a8c03450 --- /dev/null +++ b/lib/kernel/test/os_SUITE_data/sys_shell.c @@ -0,0 +1,6 @@ +#include <stdio.h> +int main(void) +{ + printf("sys_shell"); + return 0; +} -- 2.43.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor