summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-01-30 22:39:36 +0800
committerruki <[email protected]>2026-01-30 22:39:36 +0800
commit9b87a6b6885d004d445f021b9536d08a18225351 (patch)
tree6c2a84c75566e37157b91363ece45dd5f5ca9faa
parentc50a3cb891f78c187c8bd862a7e0c3ee9b65d1c4 (diff)
detect shebang format
-rw-r--r--core/src/xmake/binutils/format.c18
-rw-r--r--core/src/xmake/binutils/prefix.h1
-rw-r--r--tests/modules/binutils/test.lua4
-rw-r--r--xmake/core/base/os.lua13
4 files changed, 24 insertions, 12 deletions
diff --git a/core/src/xmake/binutils/format.c b/core/src/xmake/binutils/format.c
index 4decff29f..670dec46b 100644
--- a/core/src/xmake/binutils/format.c
+++ b/core/src/xmake/binutils/format.c
@@ -84,6 +84,10 @@ static __tb_inline__ tb_bool_t xm_binutils_format_is_ar(tb_byte_t const* first8)
(first8[7] == '\n' || first8[7] == '\r');
}
+static __tb_inline__ tb_bool_t xm_binutils_format_is_shebang(tb_byte_t const* first2) {
+ return first2[0] == '#' && first2[1] == '!';
+}
+
static __tb_inline__ tb_bool_t xm_binutils_format_is_elf(tb_byte_t const* first8) {
return first8[0] == 0x7f && first8[1] == 'E' && first8[2] == 'L' && first8[3] == 'F';
}
@@ -125,6 +129,19 @@ tb_int_t xm_binutils_format_detect(tb_stream_ref_t istream) {
tb_int_t format = -1;
do {
+ tb_byte_t* p2 = tb_null;
+ if (!tb_stream_peek(istream, &p2, 2)) {
+ tb_hong_t size = tb_stream_size(istream);
+ if (size > 0 && size < 2) {
+ format = XM_BINUTILS_FORMAT_UNKNOWN;
+ }
+ break;
+ }
+ if (xm_binutils_format_is_shebang(p2)) {
+ format = XM_BINUTILS_FORMAT_SHEBANG;
+ break;
+ }
+
tb_byte_t* p = tb_null;
if (!tb_stream_peek(istream, &p, 8)) {
tb_hong_t size = tb_stream_size(istream);
@@ -210,6 +227,7 @@ tb_int_t xm_binutils_format(lua_State *lua) {
case XM_BINUTILS_FORMAT_MACHO: lua_pushliteral(lua, "macho"); break;
case XM_BINUTILS_FORMAT_AR: lua_pushliteral(lua, "ar"); break;
case XM_BINUTILS_FORMAT_PE: lua_pushliteral(lua, "pe"); break;
+ case XM_BINUTILS_FORMAT_SHEBANG: lua_pushliteral(lua, "shebang"); break;
default: lua_pushliteral(lua, "unknown"); break;
}
diff --git a/core/src/xmake/binutils/prefix.h b/core/src/xmake/binutils/prefix.h
index a38eef658..482895c22 100644
--- a/core/src/xmake/binutils/prefix.h
+++ b/core/src/xmake/binutils/prefix.h
@@ -34,6 +34,7 @@
#define XM_BINUTILS_FORMAT_MACHO 3
#define XM_BINUTILS_FORMAT_AR 4
#define XM_BINUTILS_FORMAT_PE 5
+#define XM_BINUTILS_FORMAT_SHEBANG 6
#define XM_BINUTILS_FORMAT_UNKNOWN 0
// COFF machine types (for format detection)
diff --git a/tests/modules/binutils/test.lua b/tests/modules/binutils/test.lua
index 78acb044c..363bf073b 100644
--- a/tests/modules/binutils/test.lua
+++ b/tests/modules/binutils/test.lua
@@ -10,6 +10,10 @@ function test_format(t)
local format = binutils.format(unknown)
t:are_equal(format, "unknown")
+ local scriptfile = path.join(tempdir, "a.sh")
+ io.writefile(scriptfile, "#!/bin/sh\nexit 0\n")
+ t:are_equal(binutils.format(scriptfile), "shebang")
+
local programfile = os.programfile()
if programfile then
local expected = "elf"
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index cbd4cefeb..6ffa08f74 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -1162,24 +1162,13 @@ function os.isexec(filepath)
end
end
- -- detect file header
local format = nil
if binutils and binutils.format then
format = binutils.format(filepath)
end
- if format == "pe" then
+ if format == "pe" or format == "shebang" then
return true
end
-
- -- detect shebang scripts
- local file = io.open(filepath, "rb")
- if file then
- local header = file:read(2)
- file:close()
- if header == "#!" then
- return true
- end
- end
end
for _, suffix in ipairs(exts) do
if os.isfile(filepath .. suffix) then