Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ccache for openSUSE:Factory checked 
in at 2022-12-07 17:34:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ccache (Old)
 and      /work/SRC/openSUSE:Factory/.ccache.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ccache"

Wed Dec  7 17:34:27 2022 rev:70 rq:1040613 version:4.7.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/ccache/ccache.changes    2022-11-19 
18:08:54.994301380 +0100
+++ /work/SRC/openSUSE:Factory/.ccache.new.1835/ccache.changes  2022-12-07 
17:35:34.648740346 +0100
@@ -1,0 +2,21 @@
+Mon Dec  5 12:36:18 UTC 2022 - Dirk Müller <dmuel...@suse.com>
+
+- update to 4.7.4:
+  * Fixed an inode cache race condition.
+  * The default temporary directory is now `$XDG_RUNTIME_DIR/ccache-tmp`
+    instead of a hardcoded `/run/user/<UID>/ccache-tmp`. If `XDG_RUNTIME_DIR` 
+    is not set, `<cache_dir>/tmp` is used. This avoids creating 
`/run/user/<UID>`
+    on systems that don't have it if compiling as root.
+  * Added a fallback in case `posix_fallocate` returns `EINVAL` when
+    creating the
+  inode cache file.
+  * Connection timeout for an HTTP connection is now reported as a timeout
+    instead
+  * Temporary files found in the cache are no longer counted in
+  `--show-compression`.
+  * Removed duplicate magic header in output from `--inspect`.
+  * Ccache now properly waits for all recompression jobs to finish when
+    there is no `f` subdirectory in the cache.
+  * Documentation improvements
+
+-------------------------------------------------------------------

Old:
----
  ccache-4.7.3.tar.xz
  ccache-4.7.3.tar.xz.asc

New:
----
  ccache-4.7.4.tar.xz
  ccache-4.7.4.tar.xz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ccache.spec ++++++
--- /var/tmp/diff_new_pack.zrjp3b/_old  2022-12-07 17:35:36.412750005 +0100
+++ /var/tmp/diff_new_pack.zrjp3b/_new  2022-12-07 17:35:36.416750027 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           ccache
-Version:        4.7.3
+Version:        4.7.4
 Release:        0
 Summary:        A Fast C/C++ Compiler Cache
 License:        GPL-3.0-or-later

++++++ ccache-4.7.3.tar.xz -> ccache-4.7.4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/.github/workflows/codeql-analysis.yaml 
new/ccache-4.7.4/.github/workflows/codeql-analysis.yaml
--- old/ccache-4.7.3/.github/workflows/codeql-analysis.yaml     2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/.github/workflows/codeql-analysis.yaml     2022-11-21 
19:53:32.000000000 +0100
@@ -51,6 +51,7 @@
       env:
         RUN_TESTS: none
         CMAKE_GENERATOR: Ninja
+        EXTRA_CMAKE_BUILD_FLAGS: --target ccache
 
     - name: Perform CodeQL Analysis
       uses: github/codeql-action/analyze@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/ci/build new/ccache-4.7.4/ci/build
--- old/ccache-4.7.3/ci/build   2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/ci/build   2022-11-21 19:53:32.000000000 +0100
@@ -4,32 +4,40 @@
 
 set -eu
 
-if [ -n "${VERBOSE:-}" ]; then
+# Set default values.
+: ${BUILDDIR:=build}
+: ${CCACHE_LOC:=..}
+: ${CMAKE_PARAMS:=}
+: ${CMAKE_PREFIX:=}
+: ${EXTRA_CMAKE_BUILD_FLAGS:=}
+: ${JOBS:=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)}
+: ${SPECIAL:=}
+: ${TEST_CC:=${CC:-}}
+: ${VERBOSE:=}
+
+if [ -n "${VERBOSE}" ]; then
     set -x
 fi
 
-if [ -n "${SPECIAL:-}" ]; then
+if [ -n "${SPECIAL}" ]; then
     exec "ci/$SPECIAL"
 else
-    [ -z ${JOBS:+x} ] && JOBS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
-    [ -z ${JOBS:+x} ] && JOBS=2
-
-    mkdir -p ${BUILDDIR:-build}
-    cd ${BUILDDIR:-build}
-    ${CMAKE_PREFIX:-} cmake ${CMAKE_PARAMS:-} ${CCACHE_LOC:-..}
+    mkdir -p "${BUILDDIR}"
+    cd "${BUILDDIR}"
+    ${CMAKE_PREFIX} cmake ${CMAKE_PARAMS} ${CCACHE_LOC}
 
     case "${CMAKE_GENERATOR}" in
         [Vv]isual" "[Ss]tudio*) # MSBuild, use all CPUs.
-            ${CMAKE_PREFIX:-} cmake --build . ${EXTRA_CMAKE_BUILD_FLAGS:-} -- 
-m
+            ${CMAKE_PREFIX} cmake --build . ${EXTRA_CMAKE_BUILD_FLAGS} -- -m
             ;;
         *) # Ninja automatically uses all available CPUs.
-            ${CMAKE_PREFIX:-} cmake --build . ${EXTRA_CMAKE_BUILD_FLAGS:-}
+            ${CMAKE_PREFIX} cmake --build . ${EXTRA_CMAKE_BUILD_FLAGS}
             ;;
     esac
 
     case "${RUN_TESTS:-all}" in
         all)
-            CC=${TEST_CC:-${CC}} ctest --output-on-failure -j$JOBS "$@"
+            CC="${TEST_CC}" ctest --output-on-failure -j"${JOBS}" "$@"
             ;;
         unittest-in-wine)
             wine ccache.exe --version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/cmake/CcacheVersion.cmake 
new/ccache-4.7.4/cmake/CcacheVersion.cmake
--- old/ccache-4.7.3/cmake/CcacheVersion.cmake  2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/cmake/CcacheVersion.cmake  2022-11-21 19:53:32.000000000 
+0100
@@ -22,7 +22,7 @@
 # CCACHE_VERSION_ORIGIN is set to "archive" in scenario 1 and "git" in scenario
 # 3.
 
-set(version_info "0dca9dddef6dc4e780ba0357eea49b62e3815ff6 HEAD, tag: v4.7.3, 
origin/master, origin/HEAD, master")
+set(version_info "1527040bc2a278b9d3d51badb732ecf5841d8bb5 HEAD, tag: v4.7.4, 
origin/master, origin/HEAD, master")
 set(CCACHE_VERSION "unknown")
 
 if(version_info MATCHES 
"^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]* 
(.*)")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/cmake/Findhiredis.cmake 
new/ccache-4.7.4/cmake/Findhiredis.cmake
--- old/ccache-4.7.3/cmake/Findhiredis.cmake    2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/cmake/Findhiredis.cmake    2022-11-21 19:53:32.000000000 
+0100
@@ -33,7 +33,7 @@
 elseif(HIREDIS_FROM_INTERNET)
   message(STATUS "*** WARNING ***: Using hiredis from the internet because it 
was NOT found and HIREDIS_FROM_INTERNET is TRUE")
 
-  set(hiredis_version "1.0.2")
+  set(hiredis_version "1.1.0")
 
   set(hiredis_dir   ${CMAKE_BINARY_DIR}/hiredis-${hiredis_version})
   set(hiredis_build ${CMAKE_BINARY_DIR}/hiredis-build)
@@ -43,7 +43,7 @@
   FetchContent_Declare(
     hiredis
     URL         
https://github.com/redis/hiredis/archive/v${hiredis_version}.tar.gz
-    URL_HASH    
SHA256=e0ab696e2f07deb4252dda45b703d09854e53b9703c7d52182ce5a22616c3819
+    URL_HASH    
SHA256=fe6d21741ec7f3fc9df409d921f47dfc73a4d8ff64f4ac6f1d95f951bf7f53d6
     SOURCE_DIR  ${hiredis_dir}
     BINARY_DIR  ${hiredis_build}
   )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/cmake/GenerateConfigurationFile.cmake 
new/ccache-4.7.4/cmake/GenerateConfigurationFile.cmake
--- old/ccache-4.7.3/cmake/GenerateConfigurationFile.cmake      2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/cmake/GenerateConfigurationFile.cmake      2022-11-21 
19:53:32.000000000 +0100
@@ -26,7 +26,6 @@
 include(CheckFunctionExists)
 set(functions
     asctime_r
-    geteuid
     getopt_long
     getpwuid
     posix_fallocate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/cmake/config.h.in 
new/ccache-4.7.4/cmake/config.h.in
--- old/ccache-4.7.3/cmake/config.h.in  2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/cmake/config.h.in  2022-11-21 19:53:32.000000000 +0100
@@ -76,9 +76,6 @@
 // Define if your compiler supports AVX2.
 #cmakedefine HAVE_AVX2
 
-// Define if you have the "geteuid" function.
-#cmakedefine HAVE_GETEUID
-
 // Define if you have the "getopt_long" function.
 #cmakedefine HAVE_GETOPT_LONG
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/doc/MANUAL.adoc 
new/ccache-4.7.4/doc/MANUAL.adoc
--- old/ccache-4.7.3/doc/MANUAL.adoc    2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/doc/MANUAL.adoc    2022-11-21 19:53:32.000000000 +0100
@@ -139,7 +139,7 @@
 
     Recompress the cache to level _LEVEL_ using the Zstandard algorithm. The
     level can be an integer, with the same semantics as the
-    <<config_compression_level,*compression_level*>> configuration option), or
+    <<config_compression_level,*compression_level*>> configuration option, or
     the special value *uncompressed* for no compression. See
     _<<Cache compression>>_ for more information. This can potentionally take a
     long time since all files in the cache need to be visited. Only files that
@@ -191,17 +191,17 @@
 
 *--trim-dir* _PATH_::
 
-   Remove old files from directory _PATH_ until it is at most the size 
specified
-   by `--trim-max-size`.
+    Remove old files from directory _PATH_ until it is at most the size
+    specified by `--trim-max-size`.
 +
 WARNING: Don't use this option to trim the local cache. To trim the local cache
 directory to a certain size, use `CCACHE_MAXSIZE=_SIZE_ ccache -c`.
 
 *--trim-max-size* _SIZE_::
 
-   Specify the maximum size for `--trim-dir`. _SIZE_ should be a number 
followed
-   by an optional suffix: k, M, G, T (decimal), Ki, Mi, Gi or Ti (binary). The
-   default suffix is G.
+    Specify the maximum size for `--trim-dir`. _SIZE_ should be a number
+    followed by an optional suffix: k, M, G, T (decimal), Ki, Mi, Gi or Ti
+    (binary). The default suffix is G.
 
 *--trim-method* _METHOD_::
 
@@ -553,8 +553,6 @@
     NVCC (CUDA) compiler.
 *other*::
     Any compiler other than the known types.
-*pump*::
-    distcc's "`pump`" script.
 --
 
 [#config_compression]
@@ -1038,7 +1036,8 @@
 *temporary_dir* (*CCACHE_TEMPDIR*)::
 
     This option specifies where ccache will put temporary files. The default is
-    `/run/user/<UID>/ccache-tmp` if `/run/user/<UID>` exists, otherwise
+    `$XDG_RUNTIME_DIR/ccache-tmp` (typically `/run/user/<UID>/ccache-tmp`) if
+    `XDG_RUNTIME_DIR` is set and the directory exists, otherwise
     `<cache_dir>/tmp`.
 +
 NOTE: In previous versions of ccache, *CCACHE_TEMPDIR* had to be on the same
@@ -1591,8 +1590,8 @@
 == Handling of newly created header files
 
 If modification time (mtime) or status change time (ctime) of one of the 
include
-files is the same second as the time compilation is being done, ccache disables
-the direct mode (or, in the case of a <<Precompiled headers,precompiled
+files is equal to (or newer than) the time compilation is being done, ccache
+disables the direct mode (or, in the case of a <<Precompiled 
headers,precompiled
 header>>, disables caching completely). This done as a safety measure to avoid 
a
 race condition (see below).
 
@@ -1710,8 +1709,8 @@
 
 == Precompiled headers
 
-Ccache has support for GCC's precompiled headers. However, you have to do some
-things to make it work properly:
+Ccache has support for precompiled headers with GCC and Clang. However, you 
have
+to do some things to make it work properly:
 
 * You must set <<config_sloppiness,*sloppiness*>> to *pch_defines,time_macros*.
   The reason is that ccache can't tell whether `+__TIME__+`, `+__DATE__+` or
@@ -1734,6 +1733,8 @@
    compiling.
 --
 +
+* If you use Clang, you must compile with `-fno-pch-timestamp`.
+
 If you don't do this, either the non-precompiled version of the header file 
will
 be used (if available) or ccache will fall back to running the real compiler 
and
 increase the statistics counter "`Preprocessing failed`" (if the 
non-precompiled
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/doc/NEWS.adoc 
new/ccache-4.7.4/doc/NEWS.adoc
--- old/ccache-4.7.3/doc/NEWS.adoc      2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/doc/NEWS.adoc      2022-11-21 19:53:32.000000000 +0100
@@ -1,5 +1,64 @@
 = Ccache news
 
+== Ccache 4.7.4
+
+Release date: 2022-11-21
+
+
+=== Bug fixes
+
+- Fixed an inode cache race condition. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- The default temporary directory is now `$XDG_RUNTIME_DIR/ccache-tmp` instead
+  of a hardcoded `/run/user/<UID>/ccache-tmp`. If `XDG_RUNTIME_DIR` is not set,
+  `<cache_dir>/tmp` is used. This avoids creating `/run/user/<UID>` on systems
+  that don't have it if compiling as root. +
+  [small]#_[contributed by Joel Rosdahl and Oleg Sidorkin]_#
+
+- Added a fallback in case `posix_fallocate` returns `EINVAL` when creating the
+  inode cache file. +
+  [small]#_[contributed by Oleg Sidorkin]_#
+
+- Connection timeout for an HTTP connection is now reported as a timeout 
instead
+  of an error. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Temporary files found in the cache are no longer counted in
+  `--show-compression`. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Removed duplicate magic header in output from `--inspect`. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Ccache now properly waits for all recompression jobs to finish when there is
+  no `f` subdirectory in the cache. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+
+=== Other minor improvements
+
+- Improved inode cache logging. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+
+=== Documentation improvements
+
+- Removed stray parenthesis. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Improved description of how header files are handled. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Added a hint about using `-fno-pch-timestamp` for precompiled headers with
+  Clang. +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+- Removed obsolete description of compiler type "`pump`". +
+  [small]#_[contributed by Joel Rosdahl]_#
+
+
+
 == Ccache 4.7.3
 
 Release date: 2022-11-05
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/Config.cpp 
new/ccache-4.7.4/src/Config.cpp
--- old/ccache-4.7.3/src/Config.cpp     2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/Config.cpp     2022-11-21 19:53:32.000000000 +0100
@@ -1114,10 +1114,13 @@
 Config::default_temporary_dir() const
 {
   static const std::string run_user_tmp_dir = [] {
-#ifdef HAVE_GETEUID
-    auto dir = FMT("/run/user/{}/ccache-tmp", geteuid());
-    if (Util::create_dir(dir) && access(dir.c_str(), W_OK) == 0) {
-      return dir;
+#ifndef _WIN32
+    const char* const xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
+    if (xdg_runtime_dir && Stat::stat(xdg_runtime_dir).is_directory()) {
+      auto dir = FMT("{}/ccache-tmp", xdg_runtime_dir);
+      if (Util::create_dir(dir) && access(dir.c_str(), W_OK) == 0) {
+        return dir;
+      }
     }
 #endif
     return std::string();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/InodeCache.cpp 
new/ccache-4.7.4/src/InodeCache.cpp
--- old/ccache-4.7.3/src/InodeCache.cpp 2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/InodeCache.cpp 2022-11-21 19:53:32.000000000 +0100
@@ -29,6 +29,8 @@
 #include "Util.hpp"
 #include "fmtmacros.hpp"
 
+#include <util/TimePoint.hpp>
+
 #include <fcntl.h>
 #include <libgen.h>
 #include <sys/mman.h>
@@ -225,6 +227,13 @@
     return false;
   }
 
+  // See comment for InodeCache::InodeCache why this check is done.
+  auto now = util::TimePoint::now();
+  if (now - stat.ctime() < m_min_age || now - stat.mtime() < m_min_age) {
+    LOG("Too new ctime or mtime of {}, not considering for inode cache", path);
+    return false;
+  }
+
   Key key;
   memset(&key, 0, sizeof(Key));
   key.type = type;
@@ -375,7 +384,12 @@
   return false;
 }
 
-InodeCache::InodeCache(const Config& config) : m_config(config)
+InodeCache::InodeCache(const Config& config, util::Duration min_age)
+  : m_config(config),
+    // CCACHE_DISABLE_INODE_CACHE_MIN_AGE is only for testing purposes; see
+    // test/suites/inode_cache.bash.
+    m_min_age(getenv("CCACHE_DISABLE_INODE_CACHE_MIN_AGE") ? util::Duration(0)
+                                                           : min_age)
 {
 }
 
@@ -474,8 +488,9 @@
     return false;
   }
 
-  LOG("Inode cache insert: {}", path);
-
+  if (m_config.debug()) {
+    LOG("Inode cache insert: {}", path);
+  }
   return true;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/InodeCache.hpp 
new/ccache-4.7.4/src/InodeCache.hpp
--- old/ccache-4.7.3/src/InodeCache.hpp 2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/InodeCache.hpp 2022-11-21 19:53:32.000000000 +0100
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include <util/Duration.hpp>
+
 #include <cstdint>
 #include <functional>
 #include <string>
@@ -41,7 +43,26 @@
     checked_for_temporal_macros = 1,
   };
 
-  InodeCache(const Config& config);
+  // `min_age` specifies how old a file must be to be put in the cache. The
+  // reason for this is that there is a race condition that consists of these
+  // events:
+  //
+  // 1. A file is written with content C1, size S and timestamp (ctime/mtime) 
T.
+  // 2. Ccache hashes the file content and asks the inode cache to store the
+  //    digest with a hash of S and T (and some other data) as the key.
+  // 3. The file is quickly thereafter written with content C2 without changing
+  //    size S and timestamp T. The timestamp is not updated since the file
+  //    writes are made within a time interval smaller than the granularity of
+  //    the clock used for file system timestamps. At the time of writing, a
+  //    common granularity on a Linux system is 0.004 s (250 Hz).
+  // 4. The inode cache is asked for the file digest and the inode cache
+  //    delivers a digest of C1 even though the file's content is C2.
+  //
+  // To avoid the race condition, the inode cache only caches inodes whose
+  // timestamp was updated more than `min_age` ago. The default value is a
+  // conservative 2 seconds since not all file systems have subsecond
+  // resolution.
+  InodeCache(const Config& config, util::Duration min_age = util::Duration(2));
   ~InodeCache();
 
   // Return whether it's possible to use the inode cache on the filesystem
@@ -101,14 +122,14 @@
   using BucketHandler = std::function<void(Bucket* bucket)>;
 
   bool mmap_file(const std::string& inode_cache_file);
-  static bool
-  hash_inode(const std::string& path, ContentType type, Digest& digest);
+  bool hash_inode(const std::string& path, ContentType type, Digest& digest);
   bool with_bucket(const Digest& key_digest,
                    const BucketHandler& bucket_handler);
   static bool create_new_file(const std::string& filename);
   bool initialize();
 
   const Config& m_config;
+  util::Duration m_min_age;
   struct SharedRegion* m_sr = nullptr;
   bool m_failed = false;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/ThreadPool.cpp 
new/ccache-4.7.4/src/ThreadPool.cpp
--- old/ccache-4.7.3/src/ThreadPool.cpp 2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/ThreadPool.cpp 2022-11-21 19:53:32.000000000 +0100
@@ -51,6 +51,10 @@
 {
   {
     std::unique_lock<std::mutex> lock(m_mutex);
+    if (m_shutting_down) {
+      // Already called shut_down.
+      return;
+    }
     m_shutting_down = true;
   }
   m_task_enqueued_or_shutting_down_condition.notify_all();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/Util.cpp 
new/ccache-4.7.4/src/Util.cpp
--- old/ccache-4.7.3/src/Util.cpp       2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/Util.cpp       2022-11-21 19:53:32.000000000 +0100
@@ -438,7 +438,8 @@
 {
   std::string result;
   const char* left = str.c_str();
-  for (const char* right = left; *right; ++right) {
+  const char* right = left;
+  while (*right) {
     if (*right == '$') {
       result.append(left, right - left);
 
@@ -471,6 +472,7 @@
         left = right + 1;
       }
     }
+    ++right;
   }
   result += left;
   return result;
@@ -480,8 +482,13 @@
 fallocate(int fd, long new_size)
 {
 #ifdef HAVE_POSIX_FALLOCATE
-  return posix_fallocate(fd, 0, new_size);
-#else
+  const int posix_fallocate_err = posix_fallocate(fd, 0, new_size);
+  if (posix_fallocate_err == 0 || posix_fallocate_err != EINVAL) {
+    return posix_fallocate_err;
+  }
+  // the underlying filesystem does not support the operation so fallback to
+  // lseeks
+#endif
   off_t saved_pos = lseek(fd, 0, SEEK_END);
   off_t old_size = lseek(fd, 0, SEEK_END);
   if (old_size == -1) {
@@ -508,7 +515,6 @@
   lseek(fd, saved_pos, SEEK_SET);
   free(buf);
   return err;
-#endif
 }
 
 std::string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/ccache.cpp 
new/ccache-4.7.4/src/ccache.cpp
--- old/ccache-4.7.3/src/ccache.cpp     2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/ccache.cpp     2022-11-21 19:53:32.000000000 +0100
@@ -166,10 +166,11 @@
   auto prefix = debug_dir.empty()
                   ? output_obj
                   : debug_dir + util::to_absolute_path_no_drive(output_obj);
-  if (!Util::create_dir(Util::dir_name(prefix))) {
-    // Ignore since we can't handle an error in another way in this context. 
The
-    // caller takes care of logging when trying to open the path for writing.
-  }
+
+  // Ignore any error from create_dir since we can't handle an error in another
+  // way in this context. The caller takes care of logging when trying to open
+  // the path for writing.
+  Util::create_dir(Util::dir_name(prefix));
 
   char timestamp[100];
   const auto tm = Util::localtime(time_of_invocation);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/core/CMakeLists.txt 
new/ccache-4.7.4/src/core/CMakeLists.txt
--- old/ccache-4.7.3/src/core/CMakeLists.txt    2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/src/core/CMakeLists.txt    2022-11-21 19:53:32.000000000 
+0100
@@ -2,11 +2,11 @@
   sources
   CacheEntry.cpp
   Manifest.cpp
+  MsvcShowIncludesOutput.cpp
   Result.cpp
   ResultExtractor.cpp
   ResultInspector.cpp
   ResultRetriever.cpp
-  MsvcShowIncludesOutput.cpp
   Statistics.cpp
   StatisticsCounters.cpp
   StatsLog.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/core/CacheEntry.cpp 
new/ccache-4.7.4/src/core/CacheEntry.cpp
--- old/ccache-4.7.3/src/core/CacheEntry.cpp    2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/src/core/CacheEntry.cpp    2022-11-21 19:53:32.000000000 
+0100
@@ -117,7 +117,7 @@
 CacheEntry::Header::inspect() const
 {
   std::string result;
-  result += result += FMT("Magic: {:04x}\n", magic);
+  result += FMT("Magic: {:04x}\n", magic);
   result += FMT("Entry format version: {}\n", entry_format_version);
   result += FMT("Entry type: {} ({})\n",
                 static_cast<uint8_t>(entry_type),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ccache-4.7.3/src/storage/local/LocalStorage_compress.cpp 
new/ccache-4.7.4/src/storage/local/LocalStorage_compress.cpp
--- old/ccache-4.7.3/src/storage/local/LocalStorage_compress.cpp        
2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/storage/local/LocalStorage_compress.cpp        
2022-11-21 19:53:32.000000000 +0100
@@ -22,6 +22,7 @@
 #include <Context.hpp>
 #include <File.hpp>
 #include <Logging.hpp>
+#include <TemporaryFile.hpp>
 #include <ThreadPool.hpp>
 #include <assertions.hpp>
 #include <core/CacheEntry.hpp>
@@ -219,7 +220,7 @@
               // Ignore for now.
             }
           });
-        } else {
+        } else if (!TemporaryFile::is_tmp_file(file.path())) {
           statistics.update(0, 0, 0, file.lstat().size());
         }
 
@@ -234,6 +235,9 @@
     },
     progress_receiver);
 
+  // In case there was no f subdir, shut down the thread pool now.
+  thread_pool.shut_down();
+
   if (isatty(STDOUT_FILENO)) {
     PRINT_RAW(stdout, "\n\n");
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/storage/remote/HttpStorage.cpp 
new/ccache-4.7.4/src/storage/remote/HttpStorage.cpp
--- old/ccache-4.7.3/src/storage/remote/HttpStorage.cpp 2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/storage/remote/HttpStorage.cpp 2022-11-21 
19:53:32.000000000 +0100
@@ -94,6 +94,14 @@
   return get_partial_url(url).str();
 }
 
+RemoteStorage::Backend::Failure
+failure_from_httplib_error(httplib::Error error)
+{
+  return error == httplib::Error::ConnectionTimeout
+           ? RemoteStorage::Backend::Failure::timeout
+           : RemoteStorage::Backend::Failure::error;
+}
+
 HttpStorageBackend::HttpStorageBackend(const Params& params)
   : m_url_path(get_url_path(params.url)),
     m_http_client(get_url(params.url))
@@ -155,7 +163,7 @@
         url_path,
         to_string(result.error()),
         static_cast<int>(result.error()));
-    return nonstd::make_unexpected(Failure::error);
+    return nonstd::make_unexpected(failure_from_httplib_error(result.error()));
   }
 
   if (result->status < 200 || result->status >= 300) {
@@ -181,7 +189,8 @@
           url_path,
           to_string(result.error()),
           static_cast<int>(result.error()));
-      return nonstd::make_unexpected(Failure::error);
+      return nonstd::make_unexpected(
+        failure_from_httplib_error(result.error()));
     }
 
     if (result->status >= 200 && result->status < 300) {
@@ -204,14 +213,14 @@
         url_path,
         to_string(result.error()),
         static_cast<int>(result.error()));
-    return nonstd::make_unexpected(Failure::error);
+    return nonstd::make_unexpected(failure_from_httplib_error(result.error()));
   }
 
   if (result->status < 200 || result->status >= 300) {
     LOG("Failed to put {} to http storage: status code: {}",
         url_path,
         result->status);
-    return nonstd::make_unexpected(Failure::error);
+    return nonstd::make_unexpected(failure_from_httplib_error(result.error()));
   }
 
   return true;
@@ -228,14 +237,14 @@
         url_path,
         to_string(result.error()),
         static_cast<int>(result.error()));
-    return nonstd::make_unexpected(Failure::error);
+    return nonstd::make_unexpected(failure_from_httplib_error(result.error()));
   }
 
   if (result->status < 200 || result->status >= 300) {
     LOG("Failed to delete {} from http storage: status code: {}",
         url_path,
         result->status);
-    return nonstd::make_unexpected(Failure::error);
+    return nonstd::make_unexpected(failure_from_httplib_error(result.error()));
   }
 
   return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/util/Duration.hpp 
new/ccache-4.7.4/src/util/Duration.hpp
--- old/ccache-4.7.3/src/util/Duration.hpp      2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/src/util/Duration.hpp      2022-11-21 19:53:32.000000000 
+0100
@@ -93,25 +93,25 @@
 inline Duration
 Duration::operator+(const Duration& other) const
 {
-  return Duration(m_ns + other.m_ns);
+  return Duration(0, m_ns + other.m_ns);
 }
 
 inline Duration
 Duration::operator-(const Duration& other) const
 {
-  return Duration(m_ns - other.m_ns);
+  return Duration(0, m_ns - other.m_ns);
 }
 
 inline Duration
 Duration::operator*(double factor) const
 {
-  return Duration(factor * m_ns);
+  return Duration(0, factor * m_ns);
 }
 
 inline Duration
 Duration::operator/(double factor) const
 {
-  return Duration(m_ns / factor);
+  return Duration(0, m_ns / factor);
 }
 
 inline int64_t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/util/file.cpp 
new/ccache-4.7.4/src/util/file.cpp
--- old/ccache-4.7.3/src/util/file.cpp  2022-11-05 16:49:59.000000000 +0100
+++ new/ccache-4.7.4/src/util/file.cpp  2022-11-21 19:53:32.000000000 +0100
@@ -296,7 +296,7 @@
 write_fd(int fd, const void* data, size_t size)
 {
   int64_t written = 0;
-  do {
+  while (static_cast<size_t>(written) < size) {
     const auto count =
       write(fd, static_cast<const uint8_t*>(data) + written, size - written);
     if (count == -1) {
@@ -306,7 +306,7 @@
     } else {
       written += count;
     }
-  } while (static_cast<size_t>(written) < size);
+  }
   return {};
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/src/util/string.cpp 
new/ccache-4.7.4/src/util/string.cpp
--- old/ccache-4.7.3/src/util/string.cpp        2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/src/util/string.cpp        2022-11-21 19:53:32.000000000 
+0100
@@ -134,7 +134,8 @@
 
   std::string result;
   result.reserve(string.size());
-  for (size_t i = 0; i < string.size(); ++i) {
+  size_t i = 0;
+  while (i < string.size()) {
     if (string[i] != '%') {
       result += string[i];
     } else if (i + 2 >= string.size() || !std::isxdigit(string[i + 1])
@@ -147,6 +148,7 @@
       result += ch;
       i += 2;
     }
+    ++i;
   }
 
   return result;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/test/suites/inode_cache.bash 
new/ccache-4.7.4/test/suites/inode_cache.bash
--- old/ccache-4.7.3/test/suites/inode_cache.bash       2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/test/suites/inode_cache.bash       2022-11-21 
19:53:32.000000000 +0100
@@ -19,6 +19,11 @@
     export CCACHE_DEBUG=1
     unset CCACHE_NODIRECT
     export CCACHE_TEMPDIR="${CCACHE_DIR}/tmp"  # isolate inode cache file
+
+    # Disable safety guard against race condition in InodeCache. This is OK
+    # since files used in the tests have different sizes and thus will have
+    # different cache keys even if ctime/mtime are not updated quickly enough.
+    export CCACHE_DISABLE_INODE_CACHE_MIN_AGE=1
 }
 
 SUITE_inode_cache() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/unittest/CMakeLists.txt 
new/ccache-4.7.4/unittest/CMakeLists.txt
--- old/ccache-4.7.3/unittest/CMakeLists.txt    2022-11-05 16:49:59.000000000 
+0100
+++ new/ccache-4.7.4/unittest/CMakeLists.txt    2022-11-21 19:53:32.000000000 
+0100
@@ -21,6 +21,7 @@
   test_storage_local_StatsFile.cpp
   test_storage_local_util.cpp
   test_util_Bytes.cpp
+  test_util_Duration.cpp
   test_util_LockFile.cpp
   test_util_TextTable.cpp
   test_util_TimePoint.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/unittest/test_InodeCache.cpp 
new/ccache-4.7.4/unittest/test_InodeCache.cpp
--- old/ccache-4.7.3/unittest/test_InodeCache.cpp       2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/unittest/test_InodeCache.cpp       2022-11-21 
19:53:32.000000000 +0100
@@ -74,7 +74,7 @@
   Config config;
   init(config);
   config.set_inode_cache(false);
-  InodeCache inode_cache(config);
+  InodeCache inode_cache(config, util::Duration(0));
 
   Digest digest;
   int return_value;
@@ -99,7 +99,7 @@
   Config config;
   init(config);
 
-  InodeCache inode_cache(config);
+  InodeCache inode_cache(config, util::Duration(0));
   util::write_file("a", "");
 
   Digest digest;
@@ -121,7 +121,7 @@
   Config config;
   init(config);
 
-  InodeCache inode_cache(config);
+  InodeCache inode_cache(config, util::Duration(0));
   util::write_file("a", "a text");
 
   CHECK(put(inode_cache, "a", "a text", 1));
@@ -169,7 +169,7 @@
   Config config;
   init(config);
 
-  InodeCache inode_cache(config);
+  InodeCache inode_cache(config, util::Duration(0));
 
   Digest digest;
 
@@ -187,7 +187,7 @@
   Config config;
   init(config);
 
-  InodeCache inode_cache(config);
+  InodeCache inode_cache(config, util::Duration(0));
   util::write_file("a", "a text");
   Digest binary_digest = Hash().hash("binary").digest();
   Digest code_digest = Hash().hash("code").digest();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/unittest/test_util_Duration.cpp 
new/ccache-4.7.4/unittest/test_util_Duration.cpp
--- old/ccache-4.7.3/unittest/test_util_Duration.cpp    1970-01-01 
01:00:00.000000000 +0100
+++ new/ccache-4.7.4/unittest/test_util_Duration.cpp    2022-11-21 
19:53:32.000000000 +0100
@@ -0,0 +1,131 @@
+// Copyright (C) 2022 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include <util/Duration.hpp>
+
+#include <third_party/doctest.h>
+
+TEST_SUITE_BEGIN("util::Duration");
+
+using util::Duration;
+
+TEST_CASE("Basics")
+{
+  Duration d0(4711, 2042);
+
+  CHECK(d0.sec() == 4711);
+  CHECK(d0.nsec() == 4711000002042);
+  CHECK(d0.nsec_decimal_part() == 2042);
+}
+
+TEST_CASE("Comparison operators")
+{
+  Duration d0(1000, 0);
+  Duration d1(1000, 42);
+  Duration d2(1001, 0);
+
+  SUBCASE("operator==")
+  {
+    CHECK(d0 == d0);
+    CHECK(!(d0 == d1));
+    CHECK(!(d1 == d0));
+    CHECK(!(d0 == d2));
+    CHECK(!(d2 == d0));
+  }
+
+  SUBCASE("operator!=")
+  {
+    CHECK(!(d0 != d0));
+    CHECK(d0 != d1);
+    CHECK(d1 != d0);
+  }
+
+  SUBCASE("operator<")
+  {
+    CHECK(d0 < d1);
+    CHECK(d0 < d2);
+    CHECK(d1 < d2);
+    CHECK(!(d1 < d0));
+    CHECK(!(d2 < d0));
+    CHECK(!(d2 < d1));
+  }
+
+  SUBCASE("operator>")
+  {
+    CHECK(d2 > d1);
+    CHECK(d2 > d0);
+    CHECK(d1 > d0);
+    CHECK(!(d1 > d2));
+    CHECK(!(d0 > d2));
+    CHECK(!(d0 > d1));
+  }
+
+  SUBCASE("operator<=")
+  {
+    CHECK(d0 <= d0);
+    CHECK(d0 <= d1);
+    CHECK(d0 <= d2);
+    CHECK(!(d1 <= d0));
+    CHECK(!(d2 <= d0));
+  }
+
+  SUBCASE("operator>=")
+  {
+    CHECK(d2 >= d1);
+    CHECK(d2 >= d0);
+    CHECK(d1 >= d0);
+    CHECK(!(d1 >= d2));
+    CHECK(!(d0 >= d2));
+  }
+}
+
+TEST_CASE("Arithmetic operators")
+{
+  Duration d0(1, 2);
+  Duration d1(3, 9);
+
+  SUBCASE("operator+")
+  {
+    Duration d = d0 + d1;
+    CHECK(d.sec() == 4);
+    CHECK(d.nsec_decimal_part() == 11);
+  }
+
+  SUBCASE("operator-")
+  {
+    Duration d = d0 - d1;
+    CHECK(d.sec() == -2);
+    CHECK(d.nsec_decimal_part() == -7);
+  }
+
+  SUBCASE("operator*")
+  {
+    Duration d = d1 * 4;
+    CHECK(d.sec() == 12);
+    CHECK(d.nsec_decimal_part() == 36);
+  }
+
+  SUBCASE("operator/")
+  {
+    Duration d = d1 / 0.8;
+    CHECK(d.sec() == 3);
+    CHECK(d.nsec_decimal_part() == 750'000'011);
+  }
+}
+
+TEST_SUITE_END();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ccache-4.7.3/unittest/test_util_TimePoint.cpp 
new/ccache-4.7.4/unittest/test_util_TimePoint.cpp
--- old/ccache-4.7.3/unittest/test_util_TimePoint.cpp   2022-11-05 
16:49:59.000000000 +0100
+++ new/ccache-4.7.4/unittest/test_util_TimePoint.cpp   2022-11-21 
19:53:32.000000000 +0100
@@ -30,6 +30,7 @@
 
   CHECK(t0.sec() == 4711);
   CHECK(t0.nsec() == 4711000002042);
+  CHECK(t0.nsec_decimal_part() == 2042);
 }
 
 TEST_CASE("Conversions")

Reply via email to