]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Merge branch 'maint'
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 14 May 2014 20:03:53 +0000 (22:03 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 15 May 2014 20:19:33 +0000 (22:19 +0200)
* maint:
  Fix clang build warning "shift count >= width of type"
  Clean up stale files in internal tempdir once an hour
  Add signal handler to clean up temporary files at unexpected program exit
  Don't needlessly allocate empty counter_updates data in stats_flush()

Conflicts:
ccache.c
manifest.c
stats.c

1  2 
ccache.c
manifest.c
stats.c

diff --cc ccache.c
index c395fadfdede09d331efd43e6135cefdb676f2b9,a6bca4a34ede7e28014a0191cb073a69190e969d..7f72e5320f9cc859825fb6039da1325b8faabd53
+++ b/ccache.c
@@@ -253,41 -235,75 +261,87 @@@ failed(void
        cc_log_argv("Executing ", orig_args->argv);
        exitfn_call();
        execv(orig_args->argv[0], orig_args->argv);
 -      fatal("%s: execv returned (%s)", orig_args->argv[0], strerror(errno));
 +      fatal("execv of %s failed: %s", orig_args->argv[0], strerror(errno));
 +}
 +
- static void
- clean_up_tmp_files()
- {
-       /* delete intermediate pre-processor file if needed */
-       if (i_tmpfile) {
-               if (!direct_i_file) {
-                       tmp_unlink(i_tmpfile);
-               }
-               free(i_tmpfile);
-               i_tmpfile = NULL;
-       }
-       /* delete the cpp stderr file if necessary */
-       if (cpp_stderr) {
-               tmp_unlink(cpp_stderr);
-               free(cpp_stderr);
-               cpp_stderr = NULL;
-       }
- }
 +static const char *
 +temp_dir()
 +{
 +      static char *path = NULL;
 +      if (path) return path;  /* Memoize */
 +      path = conf->temporary_dir;
 +      if (str_eq(path, "")) {
 +              path = format("%s/tmp", conf->cache_dir);
 +      }
 +      return path;
  }
  
 -      stat(cache_dir, &st);
+ static void
+ add_pending_tmp_file(const char *path)
+ {
+       struct pending_tmp_file *e = x_malloc(sizeof(*e));
+       e->path = x_strdup(path);
+       e->next = pending_tmp_files;
+       pending_tmp_files = e;
+ }
+ static void
+ clean_up_pending_tmp_files(void)
+ {
+       struct pending_tmp_file *p = pending_tmp_files;
+       while (p) {
+               tmp_unlink(p->path);
+               p = p->next;
+               /* Leak p->path and p here because clean_up_pending_tmp_files needs to be signal
+                * safe. */
+       }
+ }
+ static void
+ signal_handler(int signo)
+ {
+       (void)signo;
+       clean_up_pending_tmp_files();
+ }
+ static void
+ clean_up_internal_tempdir(void)
+ {
+       DIR *dir;
+       struct dirent *entry;
+       struct stat st;
+       time_t now = time(NULL);
 -      update_mtime(cache_dir);
++      stat(conf->cache_dir, &st);
+       if (st.st_mtime + 3600 >= now) {
+               /* No cleanup needed. */
+               return;
+       }
 -      dir = opendir(temp_dir);
++      update_mtime(conf->cache_dir);
 -              path = format("%s/%s", temp_dir, entry->d_name);
++      dir = opendir(temp_dir());
+       if (!dir) {
+               return;
+       }
+       while ((entry = readdir(dir))) {
+               char *path;
+               if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
+                       continue;
+               }
++              path = format("%s/%s", temp_dir(), entry->d_name);
+               if (lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
+                       tmp_unlink(path);
+               }
+               free(path);
+       }
+       closedir(dir);
+ }
  /*
   * Transform a name to a full path into the cache directory, creating needed
   * sublevels if needed. Caller frees.
@@@ -933,17 -803,9 +987,19 @@@ get_object_name_from_cpp(struct args *a
                input_base[10] = 0;
        }
  
-       /* now the run */
 -      path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
 +      path_stdout = format(
 +              "%s/%s.tmp.%s.%s",
 +              temp_dir(), input_base, tmp_string(), conf->cpp_extension);
 +      path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir(), tmp_string());
 +
 +      if (create_parent_dirs(path_stdout) != 0) {
 +              fatal("Failed to create parent directory for %s: %s\n",
 +                    path_stdout, strerror(errno));
 +      }
 +
++      add_pending_tmp_file(path_stdout);
+       add_pending_tmp_file(path_stderr);
        time_of_compilation = time(NULL);
  
        if (!direct_i_file) {
  
        i_tmpfile = path_stdout;
  
 -      if (compile_preprocessed_source_code) {
 +      if (conf->run_second_cpp) {
-               tmp_unlink(path_stderr);
 +              free(path_stderr);
 +      } else {
                /*
                 * If we are using the CPP trick, we need to remember this
                 * stderr data and output it just before the main stderr from
        return result;
  }
  
-       exitfn_add_nullary(clean_up_tmp_files);
 +static void
 +create_initial_config_file(struct conf *conf, const char *path)
 +{
 +      unsigned max_files;
 +      uint64_t max_size;
 +      char *stats_dir;
 +      FILE *f;
 +      struct stat st;
 +
 +      if (create_parent_dirs(path) != 0) {
 +              return;
 +      }
 +
 +      stats_dir = format("%s/0", conf->cache_dir);
 +      if (stat(stats_dir, &st) == 0) {
 +              stats_get_obsolete_limits(stats_dir, &max_files, &max_size);
 +              /* STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory. */
 +              max_files *= 16;
 +              max_size *= 16;
 +      } else {
 +              max_files = 0;
 +              max_size = conf->max_size;
 +      }
 +      free(stats_dir);
 +
 +      f = fopen(path, "w");
 +      if (!f) {
 +              return;
 +      }
 +      if (max_files != 0) {
 +              fprintf(f, "max_files = %u\n", max_files);
 +              conf->max_files = max_files;
 +      }
 +      if (max_size != 0) {
 +              char *size = format_parsable_size_with_suffix(max_size);
 +              fprintf(f, "max_size = %s\n", size);
 +              free(size);
 +              conf->max_size = max_size;
 +      }
 +      fclose(f);
 +}
 +
 +/*
 + * Read config file(s), populate variables, create configuration file in cache
 + * directory if missing, etc.
 + */
 +static void
 +initialize(void)
 +{
 +      char *errmsg;
 +      char *p;
 +      struct stat st;
 +      bool should_create_initial_config = false;
 +
 +      conf_free(conf);
 +      conf = conf_create();
 +
 +      p = getenv("CCACHE_CONFIGPATH");
 +      if (p) {
 +              primary_config_path = x_strdup(p);
 +      } else {
 +              secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
 +              if (!conf_read(conf, secondary_config_path, &errmsg)) {
 +                      if (stat(secondary_config_path, &st) == 0) {
 +                              fatal("%s", errmsg);
 +                      }
 +                      /* Missing config file in SYSCONFDIR is OK. */
 +                      free(errmsg);
 +              }
 +
 +              if ((p = getenv("CCACHE_DIR"))) {
 +                      free(conf->cache_dir);
 +                      conf->cache_dir = strdup(p);
 +              }
 +
 +              primary_config_path = format("%s/ccache.conf", conf->cache_dir);
 +      }
 +
 +      if (!conf_read(conf, primary_config_path, &errmsg)) {
 +              if (stat(primary_config_path, &st) == 0) {
 +                      fatal("%s", errmsg);
 +              }
 +              should_create_initial_config = true;
 +      }
 +
 +      if (!conf_update_from_environment(conf, &errmsg)) {
 +              fatal("%s", errmsg);
 +      }
 +
 +      if (conf->disable) {
 +              should_create_initial_config = false;
 +      }
 +
 +      if (should_create_initial_config) {
 +              create_initial_config_file(conf, primary_config_path);
 +      }
 +
 +      exitfn_init();
 +      exitfn_add_nullary(stats_flush);
++      exitfn_add_nullary(clean_up_pending_tmp_files);
 +
 +      cc_log("=== CCACHE %s STARTED =========================================",
 +             CCACHE_VERSION);
 +
 +      if (conf->umask != UINT_MAX) {
 +              umask(conf->umask);
 +      }
 +}
 +
  /* Reset the global state. Used by the test suite. */
  void
  cc_reset(void)
@@@ -2556,29 -2041,45 +2605,37 @@@ ccache(int argc, char *argv[]
        /* Arguments to send to the real compiler. */
        struct args *compiler_args;
  
 -      setup_uncached_err();
 -
 -      if (!getenv("CCACHE_READONLY")) {
 -              if (create_cachedirtag(cache_dir) != 0) {
 -                      cc_log("failed to create %s/CACHEDIR.TAG (%s)\n",
 -                              cache_dir, strerror(errno));
 -                      failed();
 -              }
 -      }
 +      orig_args = args_init(argc, argv);
  
 -      sloppiness = parse_sloppiness(getenv("CCACHE_SLOPPINESS"));
 +      initialize();
 +      find_compiler(argv);
  
 -      cc_log_argv("Command line: ", argv);
 -      cc_log("Hostname: %s", get_hostname());
 -      cc_log("Working directory: %s", current_working_dir);
++      signal(SIGHUP, signal_handler);
++      signal(SIGINT, signal_handler);
++      signal(SIGTERM, signal_handler);
 -      if (base_dir) {
 -              cc_log("Base directory: %s", base_dir);
++      if (str_eq(conf->temporary_dir, "")) {
++              clean_up_internal_tempdir();
+       }
 -      if (getenv("CCACHE_UNIFY")) {
 -              cc_log("Unify mode enabled");
 -              enable_unify = true;
 +      if (!str_eq(conf->log_file, "")) {
 +              conf_print_items(conf, configuration_logger, NULL);
        }
  
 -      if (getenv("CCACHE_NODIRECT") || enable_unify) {
 -              cc_log("Direct mode disabled");
 -              enable_direct = false;
 +      if (conf->disable) {
 +              cc_log("ccache is disabled");
 +              failed();
        }
  
 -      if (getenv("CCACHE_COMPRESS")) {
 -              cc_log("Compression enabled");
 -              enable_compression = true;
 -      }
 +      setup_uncached_err();
  
 -      if ((env = getenv("CCACHE_NLEVELS"))) {
 -              nlevels = atoi(env);
 -              if (nlevels < 1) nlevels = 1;
 -              if (nlevels > 8) nlevels = 8;
 +      cc_log_argv("Command line: ", argv);
 +      cc_log("Hostname: %s", get_hostname());
 +      cc_log("Working directory: %s", current_working_dir);
 +
 +      if (conf->unify) {
 +              cc_log("Direct mode disabled because unify mode is enabled");
 +              conf->direct_mode = false;
        }
  
        if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
diff --cc manifest.c
Simple merge
diff --cc stats.c
Simple merge