From: Joel Rosdahl Date: Sat, 14 Aug 2010 15:55:14 +0000 (+0200) Subject: Don't use /bin/sh when executing compiler check command X-Git-Tag: v3.1~77 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=80342192220d92805a16cf94bee5d471804984a0;p=thirdparty%2Fccache.git Don't use /bin/sh when executing compiler check command Using /bin/sh gives too much overhead for the benefit of being able to specify more complex commands directly. --- diff --git a/MANUAL.txt b/MANUAL.txt index d780fa41a..366816722 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -213,13 +213,15 @@ cases you won't need any of these as the defaults will be fine. you know what you are doing. _a command string_:: Hash the standard output and standard error output of the specified - command. The command is passed to +/bin/sh+ for execution. You can use - ``$compiler'' in the command string to refer to the compiler. Example - commands: + command. The string will be split on whitespace to find out the command and + arguments to run. No other interpretation of the command string will be + done, except that the special word ``%compiler%'' will be replaced with the + path to the compiler. Several commands can be specified with semicolon as + separator. Examples: + -- -* +$compiler -v+ -* +$compiler -dumpmachine && $compiler -dumpversion+ +* +%compiler% -v+ +* +%compiler% -dumpmachine; %compiler% -dumpversion+ You should make sure that the specified command is as fast as possible since it will be run once for each ccache invocation. diff --git a/ccache.c b/ccache.c index 02614ebbb..b27127fa7 100644 --- a/ccache.c +++ b/ccache.c @@ -920,41 +920,8 @@ calculate_common_hash(struct args *args, struct mdfour *hash) hash_int(hash, st.st_size); hash_int(hash, st.st_mtime); } else { /* command string */ - char buf[8192]; - static char compiler_env[1024]; - size_t n; - char *command; - FILE *f; - int status; - - cc_log("Running compiler check command: %s", compilercheck); - snprintf(compiler_env, sizeof(compiler_env), - "compiler=%s", orig_args->argv[0]); - putenv(compiler_env); - command = format("{ %s ; } &1", compilercheck); - f = popen(command, "r"); - free(command); - if (!f) { - stats_update(STATS_COMPCHECK); - fatal("Compiler check popen failed"); - } - hash_delimiter(hash, "cc_command"); - while (1) { - n = fread(buf, 1, sizeof(buf), f); - hash_buffer(hash, buf, n); - if (n < sizeof(buf)) { - if (feof(f)) { - break; - } else { - stats_update(STATS_COMPCHECK); - fatal("Failed reading from compiler check command"); - } - } - } - status = pclose(f); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - stats_update(STATS_COMPCHECK); - fatal("Compiler check command returned %d", WEXITSTATUS(status)); + if (!hash_multicommand_output(hash, compilercheck, orig_args->argv[0])) { + fatal("Failure running compiler check command: %s", compilercheck); } } diff --git a/test.sh b/test.sh index f2f155bad..da521d692 100755 --- a/test.sh +++ b/test.sh @@ -391,17 +391,17 @@ EOF testname="compilercheck=command" $CCACHE -z >/dev/null backdate compiler.sh - CCACHE_COMPILERCHECK='echo $compiler' $CCACHE ./compiler.sh -c test1.c + CCACHE_COMPILERCHECK='echo %compiler%' $CCACHE ./compiler.sh -c test1.c checkstat 'cache hit (preprocessed)' 0 checkstat 'cache miss' 1 echo "# Compiler upgrade" >>compiler.sh CCACHE_COMPILERCHECK="echo ./compiler.sh" $CCACHE ./compiler.sh -c test1.c checkstat 'cache hit (preprocessed)' 1 checkstat 'cache miss' 1 - CCACHE_COMPILERCHECK='echo bar >&2' $CCACHE ./compiler.sh -c test1.c + CCACHE_COMPILERCHECK='echo bar' $CCACHE ./compiler.sh -c test1.c checkstat 'cache hit (preprocessed)' 1 checkstat 'cache miss' 2 - CCACHE_COMPILERCHECK='read x; echo -n b >&2; echo ar >&2' $CCACHE ./compiler.sh -c test1.c + CCACHE_COMPILERCHECK='echo -n b; echo ar' $CCACHE ./compiler.sh -c test1.c checkstat 'cache hit (preprocessed)' 2 checkstat 'cache miss' 2