diff --git a/src/bvar/default_variables.cpp b/src/bvar/default_variables.cpp index db74db11f5..a32273a5d0 100644 --- a/src/bvar/default_variables.cpp +++ b/src/bvar/default_variables.cpp @@ -20,6 +20,7 @@ #include // getpagesize #include #include // getrusage +#include // uname #include // dirent #include // setw #include @@ -617,11 +618,26 @@ static void get_cmdline(std::ostream& os, void*) { struct ReadVersion { std::string content; ReadVersion() { - std::ostringstream oss; - if (butil::read_command_output(oss, "uname -ap") != 0) { + struct utsname buf; + if (uname(&buf) != 0) { LOG(ERROR) << "Fail to read kernel version"; return; } +#if defined(__APPLE__) && (defined(__aarch64__) || defined(__arm64__)) + const char* processor = "arm"; +#elif defined(__APPLE__) && defined(__x86_64__) + const char* processor = "i386"; +#else + const char* processor = buf.machine; +#endif + std::ostringstream oss; + oss << buf.sysname << ' ' << buf.nodename << ' ' + << buf.release << ' ' << buf.version << ' ' + << buf.machine << ' ' << processor; +#if !defined(__APPLE__) + oss << " GNU/Linux"; +#endif + oss << '\n'; content.append(oss.str()); } }; diff --git a/test/bvar_variable_unittest.cpp b/test/bvar_variable_unittest.cpp index f2a3edb777..d29e50c8c5 100644 --- a/test/bvar_variable_unittest.cpp +++ b/test/bvar_variable_unittest.cpp @@ -19,7 +19,8 @@ #include // pthread_* #include // usleep - +#include // uname +#include // strlen #include #include #include @@ -462,6 +463,48 @@ TEST_F(VariableTest, dtor_waits_for_inflight_describe) { ASSERT_TRUE(destructed.load()); } + +TEST_F(VariableTest, uname_returns_valid_kernel_info) { + struct utsname buf; + ASSERT_EQ(0, uname(&buf)); + + // Each field should be non-empty + ASSERT_GT(strlen(buf.sysname), 0u); + ASSERT_GT(strlen(buf.nodename), 0u); + ASSERT_GT(strlen(buf.release), 0u); + ASSERT_GT(strlen(buf.version), 0u); + ASSERT_GT(strlen(buf.machine), 0u); + + // Build the string the same way ReadVersion does in default_variables.cpp +#if defined(__APPLE__) && (defined(__aarch64__) || defined(__arm64__)) + const char* processor = "arm"; +#elif defined(__APPLE__) && defined(__x86_64__) + const char* processor = "i386"; +#else + const char* processor = buf.machine; +#endif + std::ostringstream oss; + oss << buf.sysname << ' ' << buf.nodename << ' ' + << buf.release << ' ' << buf.version << ' ' + << buf.machine << ' ' << processor; +#if !defined(__APPLE__) + oss << " GNU/Linux"; +#endif + oss << '\n'; + std::string content = oss.str(); + + // The result should contain all key fields + ASSERT_NE(content.find(buf.sysname), std::string::npos); + ASSERT_NE(content.find(buf.release), std::string::npos); + ASSERT_NE(content.find(buf.machine), std::string::npos); + + // On Linux, sysname should be "Linux"; on macOS, "Darwin" +#if defined(__linux__) + ASSERT_STREQ(buf.sysname, "Linux"); +#elif defined(__APPLE__) + ASSERT_STREQ(buf.sysname, "Darwin"); +#endif +} } // namespace int main(int argc, char** argv) {