]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Restore original umask after finalize_at_exit
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 28 Oct 2020 20:26:42 +0000 (21:26 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 28 Oct 2020 21:15:53 +0000 (22:15 +0100)
If umask (CCACHE_UMASK) has been configured, ccache restores the
original umask before executing external programs so that the configured
umask is only used for files created by ccache itself. After a
refactoring of how flushing of statistics is done
(dd8f65aa5589709ca55bbb782050424a0010e8b8), the original umask is
restored before calling finalize_at_exit. If ccache hasn’t created a
result file (i.e., the result is not a cache miss, for example when
called for linking), finalize_stats_and_trigger_cleanup (called by
finalize_at_exit) chooses a random stats file and implicitly also
creates any missing cache directories. Such cache directories will
therefore be created without applying the configured umask.

Fix this by restoring the original mask after calling finalize_at_exit.

Fixes #710.

src/ccache.cpp
test/suites/base.bash

index b59fd8ca482c605397afcc90508291da90bb180c..e56be0ae3c958708efbf1a37a30680cd941b6826 100644 (file)
@@ -2229,6 +2229,7 @@ cache_compilation(int argc, const char* const* argv)
 
   bool fall_back_to_original_compiler = false;
   Args saved_orig_args;
+  nonstd::optional<mode_t> original_umask;
 
   {
     Context ctx;
@@ -2255,9 +2256,7 @@ cache_compilation(int argc, const char* const* argv)
       // Else: Fall back to running the real compiler.
       fall_back_to_original_compiler = true;
 
-      if (ctx.original_umask) {
-        umask(*ctx.original_umask);
-      }
+      original_umask = ctx.original_umask;
 
       ASSERT(!ctx.orig_args.empty());
 
@@ -2274,6 +2273,9 @@ cache_compilation(int argc, const char* const* argv)
   }
 
   if (fall_back_to_original_compiler) {
+    if (original_umask) {
+      umask(*original_umask);
+    }
     auto execv_argv = saved_orig_args.to_argv();
     execv(execv_argv[0], const_cast<char* const*>(execv_argv.data()));
     throw Fatal("execv of {} failed: {}", execv_argv[0], strerror(errno));
index 8f2ef9706ba349b670a50ee570b3540c5a74f431..34ab75d2a85366395c23f8b02bceaef96670bf46 100644 (file)
@@ -952,22 +952,26 @@ EOF
     saved_umask=$(umask)
     umask 022
     export CCACHE_UMASK=002
+    export CCACHE_TEMPDIR=$CCACHE_DIR/tmp
 
     cat <<EOF >test.c
 int main() {}
 EOF
 
+    # A cache-miss case which affects the stats file on level 1:
+
     $CCACHE -M 5 >/dev/null
     $CCACHE_COMPILE -MMD -c test.c
     expect_stat 'cache hit (preprocessed)' 0
     expect_stat 'cache miss' 1
-    result_file=$(find $CCACHE_DIR -name '*R')
-    level_2_dir=$(dirname $result_file)
-    level_1_dir=$(dirname $(dirname $result_file))
+    result_file=$(find "$CCACHE_DIR" -name '*R')
+    level_2_dir=$(dirname "$result_file")
+    level_1_dir=$(dirname $(dirname "$result_file"))
     expect_perm test.o -rw-r--r--
     expect_perm test.d -rw-r--r--
     expect_perm "$CCACHE_CONFIGPATH" -rw-rw-r--
     expect_perm "$CCACHE_DIR" drwxrwxr-x
+    expect_perm "$CCACHE_DIR/tmp" drwxrwxr-x
     expect_perm "$level_1_dir" drwxrwxr-x
     expect_perm "$level_1_dir/stats" -rw-rw-r--
     expect_perm "$level_2_dir" drwxrwxr-x
@@ -986,6 +990,20 @@ EOF
     expect_stat 'called for link' 1
     expect_perm test -rwxr-xr-x
 
+    # A non-cache-miss case which affects the stats file on level 2:
+
+    rm -rf "$CCACHE_DIR"
+
+    $CCACHE_COMPILE --version >/dev/null
+    expect_stat 'no input file' 1
+    stats_file=$(find "$CCACHE_DIR" -name stats)
+    level_2_dir=$(dirname "$stats_file")
+    level_1_dir=$(dirname $(dirname "$stats_file"))
+    expect_perm "$CCACHE_DIR" drwxrwxr-x
+    expect_perm "$level_1_dir" drwxrwxr-x
+    expect_perm "$level_2_dir" drwxrwxr-x
+    expect_perm "$stats_file" -rw-rw-r--
+
     umask $saved_umask
 
     # -------------------------------------------------------------------------