File 0174-Correct-code-module_status-1-for-BEAM-files-in-archi.patch of Package erlang
From 0fe4106fbcc924f245ac8afb69db1625ebbb6ebe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 22 Mar 2022 06:46:17 +0100
Subject: [PATCH] Correct `code:module_status/1` for BEAM files in archives
`code:module_status/1` would always return `modified` for BEAM
file loaded from an archive file.
Closes #5801
---
lib/kernel/src/code.erl | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index 71a570fa7b..b45b55768a 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -1048,20 +1048,20 @@ module_status(Module) ->
%% Note that we don't want to go via which/1, since it doesn't look at the
%% disk contents at all if the module is already loaded.
module_status(Module, PathFiles) ->
- case code:is_loaded(Module) of
+ case is_loaded(Module) of
false -> not_loaded;
{file, preloaded} -> loaded;
{file, cover_compiled} ->
- %% cover compilation loads directly to memory and does not
- %% create a beam file, so report 'modified' if a file exists
+ %% Cover compilation loads directly to memory and does not
+ %% create a beam file, so report 'modified' if a file exists.
case which(Module, PathFiles) of
non_existing -> removed;
_File -> modified
end;
{file, []} -> loaded; % no beam file - generated code
- {file, OldFile} when is_list(OldFile) ->
- %% we don't care whether or not the file is in the same location
- %% as when last loaded, as long as it can be found in the path
+ {file, [_|_]} ->
+ %% We don't care whether or not the file is in the same location
+ %% as when last loaded, as long as it can be found in the path.
case which(Module, PathFiles) of
non_existing -> removed;
Path ->
@@ -1076,10 +1076,24 @@ module_status(Module, PathFiles) ->
%% be reloaded; does not care about file timestamps or compilation time
module_changed_on_disk(Module, Path) ->
MD5 = erlang:get_module_info(Module, md5),
- MD5 =/= beam_file_md5(Path).
+ MD5 =/= beam_file_md5(Module, Path).
+
+beam_file_md5(Module, Path) ->
+ case do_beam_file_md5(Path) of
+ MD5 when is_binary(MD5) ->
+ MD5;
+ undefined ->
+ %% This module is probably embedded in an archive.
+ case get_object_code(Module) of
+ {Module, Code, _Path} ->
+ do_beam_file_md5(Code);
+ error ->
+ undefined
+ end
+ end.
-beam_file_md5(Path) ->
- case beam_lib:md5(Path) of
+do_beam_file_md5(PathOrCode) ->
+ case beam_lib:md5(PathOrCode) of
{ok,{_Mod,MD5}} -> MD5;
_ -> undefined
end.
--
2.34.1