summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Bakken <luke@bakken.io>2022-12-10 14:20:02 -0800
committerLuke Bakken <luke@bakken.io>2022-12-10 14:20:02 -0800
commit10fcc64b7439a536c24d41d43b1e518dfd81c3bd (patch)
tree6ca9dc931bf0d9e897c49046b3068fd73d205f7e
parentf7b65abc1592dde817b1fc263a6ed908f4c34d55 (diff)
downloadrabbitmq-server-git-10fcc64b7439a536c24d41d43b1e518dfd81c3bd.tar.gz
Use win32_cmd/2 to run handle.exe because it is great.
-rw-r--r--deps/rabbit_common/src/rabbit_misc.erl46
-rw-r--r--deps/rabbitmq_management_agent/src/rabbit_mgmt_external_stats.erl11
2 files changed, 30 insertions, 27 deletions
diff --git a/deps/rabbit_common/src/rabbit_misc.erl b/deps/rabbit_common/src/rabbit_misc.erl
index bf43ac59af..aadf485ddf 100644
--- a/deps/rabbit_common/src/rabbit_misc.erl
+++ b/deps/rabbit_common/src/rabbit_misc.erl
@@ -62,7 +62,7 @@
-export([pget/2, pget/3, pupdate/3, pget_or_die/2, pmerge/3, pset/3, plmerge/2]).
-export([format_message_queue/2]).
-export([append_rpc_all_nodes/4, append_rpc_all_nodes/5]).
--export([os_cmd/1, pwsh_cmd/1]).
+-export([os_cmd/1, pwsh_cmd/1, win32_cmd/2]).
-export([is_os_process_alive/1]).
-export([version/0, otp_release/0, platform_and_version/0, otp_system_version/0,
rabbitmq_and_erlang_versions/0, which_applications/0]).
@@ -1173,7 +1173,7 @@ is_os_process_alive(Pid) ->
case os:find_executable("tasklist.exe") of
false ->
Cmd = format("(Get-Process -Id ~ts).ProcessName", [PidS]),
- {ok, Res} = pwsh_cmd(Cmd),
+ {ok, [Res]} = pwsh_cmd(Cmd),
case Res of
"erl" -> true;
"werl" -> true;
@@ -1181,7 +1181,7 @@ is_os_process_alive(Pid) ->
end;
TasklistExe ->
Args = ["/nh", "/fi", "pid eq " ++ PidS],
- {ok, Res} = do_win32_cmd(TasklistExe, Args),
+ {ok, [Res]} = win32_cmd(TasklistExe, Args),
match =:= re:run(Res, "erl\\.exe", [{capture, none}])
end
end}]).
@@ -1472,44 +1472,46 @@ whereis_name(Name) ->
%% End copypasta from gen_server2.erl
%% -------------------------------------------------------------------------
-%% This will execute a Powershell command that is expected to return a
-%% single-line result. Output lines can't exceed 512 bytes. If multiple
-%% lines are returned by the command, these functions will return the
-%% last line.
+%% This will execute a Powershell command without an intervening cmd.exe
+%% process. Output lines can't exceed 512 bytes.
%%
%% Inspired by os:cmd/1 in lib/kernel/src/os.erl
do_pwsh_cmd(Command) ->
Pwsh = find_powershell(),
- A1 = ["-NoLogo",
- "-NonInteractive",
- "-NoProfile",
- "-InputFormat", "Text",
- "-OutputFormat", "Text",
- "-Command", Command],
- do_win32_cmd(Pwsh, A1).
-
-do_win32_cmd(Exe, Args) ->
+ Args = ["-NoLogo",
+ "-NonInteractive",
+ "-NoProfile",
+ "-InputFormat", "Text",
+ "-OutputFormat", "Text",
+ "-Command", Command],
+ win32_cmd(Pwsh, Args).
+
+win32_cmd(Exe, Args) ->
SystemRootDir = os:getenv("SystemRoot", "/"),
% Note: 'hide' must be used or this will not work!
A0 = [exit_status, stderr_to_stdout, in, hide,
{cd, SystemRootDir}, {line, 512}, {arg0, Exe}, {args, Args}],
Port = erlang:open_port({spawn_executable, Exe}, A0),
MonRef = erlang:monitor(port, Port),
- Result = win32_cmd_receive(Port, MonRef, <<>>),
+ Result = win32_cmd_receive(Port, MonRef, []),
true = erlang:demonitor(MonRef, [flush]),
Result.
-win32_cmd_receive(Port, MonRef, Data0) ->
+win32_cmd_receive(Port, MonRef, Acc0) ->
receive
{Port, {exit_status, 0}} ->
win32_cmd_receive_finish(Port, MonRef),
- {ok, Data0};
+ {ok, lists:reverse(Acc0)};
{Port, {exit_status, Status}} ->
win32_cmd_receive_finish(Port, MonRef),
{error, {exit_status, Status}};
- {Port, {data, {eol, Data1}}} ->
- Data2 = string:trim(Data1),
- win32_cmd_receive(Port, MonRef, Data2);
+ {Port, {data, {eol, Data0}}} ->
+ Data1 = string:trim(Data0),
+ Acc1 = case Data1 of
+ [] -> Acc0; % Note: skip empty lines in output
+ Data2 -> [Data2 | Acc0]
+ end,
+ win32_cmd_receive(Port, MonRef, Acc1);
{'DOWN', MonRef, _, _, _} ->
flush_exit(Port),
{error, nodata}
diff --git a/deps/rabbitmq_management_agent/src/rabbit_mgmt_external_stats.erl b/deps/rabbitmq_management_agent/src/rabbit_mgmt_external_stats.erl
index 8a2b765f2b..fe25326272 100644
--- a/deps/rabbitmq_management_agent/src/rabbit_mgmt_external_stats.erl
+++ b/deps/rabbitmq_management_agent/src/rabbit_mgmt_external_stats.erl
@@ -116,19 +116,20 @@ get_used_fd({win32, _}, State0) ->
UsedFd = get_used_fd_via_powershell(Pid),
{State1, UsedFd};
HandleExe ->
- Handle = rabbit_misc:os_cmd("\"" ++ HandleExe ++ "\" /accepteula -s -p " ++ Pid ++ " 2> nul"),
- case Handle of
+ Args = ["/accepteula", "-s", "-p", Pid],
+ HandleExeOutput = rabbit_misc:win32_cmd(HandleExe, Args),
+ case HandleExeOutput of
[] ->
State1 = log_fd_warning_once("Could not execute handle.exe, using powershell to determine handle count", [], State0),
UsedFd = get_used_fd_via_powershell(Pid),
{State1, UsedFd};
_ ->
- case find_files_line(string:tokens(Handle, "\r\n")) of
+ case find_files_line(HandleExeOutput) of
unknown ->
State1 = log_fd_warning_once("handle.exe output did not contain "
"a line beginning with 'File', using "
"powershell to determine used file descriptor "
- "count: ~tp", [Handle], State0),
+ "count: ~tp", [HandleExeOutput], State0),
UsedFd = get_used_fd_via_powershell(Pid),
{State1, UsedFd};
UsedFd ->
@@ -147,7 +148,7 @@ find_files_line([_H | T]) ->
get_used_fd_via_powershell(Pid) ->
Cmd = "Get-Process -Id " ++ Pid ++ " | Select-Object -ExpandProperty HandleCount",
- {ok, Result} = rabbit_misc:pwsh_cmd(Cmd),
+ {ok, [Result]} = rabbit_misc:pwsh_cmd(Cmd),
list_to_integer(Result).
-define(SAFE_CALL(Fun, NoProcFailResult),