diff options
| author | ruki <[email protected]> | 2026-01-30 22:39:36 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-01-30 22:39:36 +0800 |
| commit | 9b87a6b6885d004d445f021b9536d08a18225351 (patch) | |
| tree | 6c2a84c75566e37157b91363ece45dd5f5ca9faa | |
| parent | c50a3cb891f78c187c8bd862a7e0c3ee9b65d1c4 (diff) | |
detect shebang format
| -rw-r--r-- | core/src/xmake/binutils/format.c | 18 | ||||
| -rw-r--r-- | core/src/xmake/binutils/prefix.h | 1 | ||||
| -rw-r--r-- | tests/modules/binutils/test.lua | 4 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 13 |
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 |
