From 119a7ed05dd444bcc6e4b7e18faf24f11aaaa42a Mon Sep 17 00:00:00 2001 From: Thomas Otto Date: Tue, 3 Mar 2020 23:21:18 +0100 Subject: [PATCH] Adapt find_executable() to use split_into_strings() --- src/ccache.cpp | 18 ++++++++---------- src/execute.cpp | 40 ++++++++++++++++------------------------ src/execute.hpp | 8 ++++---- src/hashutil.cpp | 4 +--- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/ccache.cpp b/src/ccache.cpp index 2887a073d..228b4894a 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -167,13 +167,12 @@ add_prefix(const Context& ctx, Args& args, const std::string& prefix_command) Args prefix; for (const auto& word : Util::split_into_strings(prefix_command, " ")) { - char* path = find_executable(ctx, word.c_str(), MYNAME); - if (!path) { + std::string path = find_executable(ctx, word.c_str(), MYNAME); + if (path.empty()) { fatal("%s: %s", word.c_str(), strerror(errno)); } - args_add(prefix, path); - free(path); + args_add(prefix, path.c_str()); } cc_log("Using command-line prefix %s", prefix_command.c_str()); @@ -1522,11 +1521,10 @@ hash_nvcc_host_compiler(const Context& ctx, } free(path); } else { - char* path = find_executable(ctx, compiler, MYNAME); - if (path) { + std::string path = find_executable(ctx, compiler, MYNAME); + if (!path.empty()) { auto st = Stat::stat(path, Stat::OnError::log); hash_compiler(ctx, hash, st, ccbin, false); - free(path); } } } @@ -2083,11 +2081,11 @@ find_compiler(Context& ctx, const char* const* argv) base = ctx.config.compiler(); } - char* compiler = find_executable(ctx, base.c_str(), MYNAME); - if (!compiler) { + std::string compiler = find_executable(ctx, base.c_str(), MYNAME); + if (compiler.empty()) { fatal("Could not find compiler \"%s\" in PATH", base.c_str()); } - if (str_eq(compiler, argv[0])) { + if (compiler == argv[0]) { fatal("Recursive invocation (the name of the ccache binary must be \"%s\")", MYNAME); } diff --git a/src/execute.cpp b/src/execute.cpp index 91077c4ac..7fa5832c8 100644 --- a/src/execute.cpp +++ b/src/execute.cpp @@ -106,12 +106,12 @@ std::string win32getshell(const char* path) { char* path_env; - char* sh = NULL; + std::string sh; const char* ext = get_extension(path); if (ext && strcasecmp(ext, ".sh") == 0 && (path_env = getenv("PATH"))) { sh = find_executable_in_path("sh.exe", NULL, path_env); } - if (!sh && getenv("CCACHE_DETECT_SHEBANG")) { + if (sh.empty() && getenv("CCACHE_DETECT_SHEBANG")) { // Detect shebang. FILE* fp = fopen(path, "r"); if (fp) { @@ -125,9 +125,7 @@ win32getshell(const char* path) } } - std::string result = sh ? sh : ""; - free(sh); - return result; + return sh; } void @@ -307,11 +305,11 @@ execute(const char* const* argv, int fd_out, int fd_err, pid_t* pid) // Find an executable by name in $PATH. Exclude any that are links to // exclude_name. -char* +std::string find_executable(const Context& ctx, const char* name, const char* exclude_name) { if (Util::is_absolute_path(name)) { - return x_strdup(name); + return name; } const char* path = ctx.config.path().c_str(); @@ -320,13 +318,13 @@ find_executable(const Context& ctx, const char* name, const char* exclude_name) } if (!path) { cc_log("No PATH variable"); - return nullptr; + return ""; } return find_executable_in_path(name, exclude_name, path); } -char* +std::string find_executable_in_path(const char* name, const char* exclude_name, const char* path) @@ -335,33 +333,30 @@ find_executable_in_path(const char* name, return nullptr; } - char* path_buf = x_strdup(path); - // Search the path looking for the first compiler of the right name that // isn't us. - char* saveptr = nullptr; - for (char* tok = strtok_r(path_buf, PATH_DELIM, &saveptr); tok; - tok = strtok_r(nullptr, PATH_DELIM, &saveptr)) { + for (const std::string& dir : Util::split_into_strings(path, PATH_DELIM)) { #ifdef _WIN32 char namebuf[MAX_PATH]; - int ret = SearchPath(tok, name, NULL, sizeof(namebuf), namebuf, NULL); + int ret = + SearchPath(dir.c_str(), name, NULL, sizeof(namebuf), namebuf, NULL); if (!ret) { char* exename = format("%s.exe", name); - ret = SearchPath(tok, exename, NULL, sizeof(namebuf), namebuf, NULL); + ret = + SearchPath(dir.c_str(), exename, NULL, sizeof(namebuf), namebuf, NULL); free(exename); } (void)exclude_name; if (ret) { - free(path_buf); - return x_strdup(namebuf); + return std::string(namebuf); } #else assert(exclude_name); - char* fname = format("%s/%s", tok, name); + std::string fname = fmt::format("{}/{}", dir, name); auto st1 = Stat::lstat(fname); auto st2 = Stat::stat(fname); // Look for a normal executable file. - if (st1 && st2 && st2.is_regular() && access(fname, X_OK) == 0) { + if (st1 && st2 && st2.is_regular() && access(fname.c_str(), X_OK) == 0) { if (st1.is_symlink()) { std::string real_path = Util::real_path(fname, true); if (Util::base_name(real_path) == exclude_name) { @@ -371,15 +366,12 @@ find_executable_in_path(const char* name, } // Found it! - free(path_buf); return fname; } - free(fname); #endif } - free(path_buf); - return nullptr; + return ""; } void diff --git a/src/execute.hpp b/src/execute.hpp index b06cd2522..f1fb7a48b 100644 --- a/src/execute.hpp +++ b/src/execute.hpp @@ -25,11 +25,11 @@ struct Context; int execute(const char* const* argv, int fd_out, int fd_err, pid_t* pid); -char* +std::string find_executable(const Context& ctx, const char* name, const char* exclude_name); -char* find_executable_in_path(const char* name, - const char* exclude_name, - const char* path); +std::string find_executable_in_path(const char* name, + const char* exclude_name, + const char* path); void print_command(FILE* fp, const char* const* argv); char* format_command(const char* const* argv); diff --git a/src/hashutil.cpp b/src/hashutil.cpp index 86560ddc4..0e13b00cc 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -330,10 +330,8 @@ hash_command_output(struct hash* hash, STARTUPINFO si; memset(&si, 0x00, sizeof(si)); - char* exe_path = + std::string path = find_executable_in_path(args[0].c_str(), nullptr, getenv("PATH")); - std::string path = exe_path ? exe_path : ""; - free(exe_path); if (path.empty()) { path = args[0]; } -- 2.47.2