if (!path) {
path = format("%s/tmp", cache_dir);
}
-
- /* make sure the temp dir exists */
- if (create_dir(path) != 0) {
- fprintf(stderr,
- "ccache: failed to create %s (%s)\n",
- path, strerror(errno));
- exit(1);
- }
return path;
}
/*
* Transform a name to a full path into the cache directory, creating needed
* sublevels if needed. Caller frees.
- *
- * stat() calls can be expensive on the cache, so we both avoid checking a
- * single path multiple times, and also avoid stat()ing each level in a
- * many level cache.
*/
static char *
get_path_in_cache(const char *name, const char *suffix)
int i;
char *path;
char *result;
- struct stat st;
- /* Form the entire path */
path = x_strdup(cache_dir);
for (i = 0; i < nlevels; ++i) {
char *p = format("%s/%c", path, name[i]);
path = p;
}
- /* First see if whole path exists, so can avoid directory one-by-one check */
- if (!(stat(path, &st) == 0 && S_ISDIR(st.st_mode))) {
- free(path);
- path = x_strdup(cache_dir);
- for (i = 0; i < nlevels; ++i) {
- char *p = format("%s/%c", path, name[i]);
- free(path);
- path = p;
- if (create_dir(path) != 0) {
- cc_log("Failed to create %s", path);
- failed();
- }
- }
- }
-
result = format("%s/%s%s", path, name + nlevels, suffix);
free(path);
return result;
size_t added_bytes = 0;
unsigned added_files = 0;
+ create_parent_dirs(cached_obj);
tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
temp_dir(), input_base, tmp_string(), i_extension);
path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir(), tmp_string());
+ if (create_parent_dirs(path_stdout) != 0) {
+ char *parent = dirname(path_stdout);
+ fprintf(stderr,
+ "ccache: failed to create %s (%s)\n",
+ parent, strerror(errno));
+ free(parent);
+ exit(1);
+ }
+
time_of_compilation = time(NULL);
if (!direct_i_file) {
setup_uncached_err();
- /* make sure the cache dir exists */
- if (create_dir(cache_dir) != 0) {
- fprintf(stderr,
- "ccache: failed to create %s (%s)\n",
- cache_dir, strerror(errno));
- exit(1);
- }
-
ccache(argc, argv);
return 1;
}
const char *get_extension(const char *path);
char *remove_extension(const char *path);
size_t file_size(struct stat *st);
-int safe_open(const char *fname);
+int safe_create_wronly(const char *fname);
char *x_realpath(const char *path);
char *gnu_getcwd(void);
int create_empty_file(const char *fname);
fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
cc_log("lockfile_acquire: open WRONLY %s: %s", lockfile, strerror(errno));
+ if (errno == ENOENT) {
+ /* Directory doesn't exist? */
+ if (create_parent_dirs(lockfile) == 0) {
+ /* OK. Retry. */
+ continue;
+ }
+ }
if (errno != EEXIST) {
/* Directory doesn't exist or isn't writable? */
goto out;
goto out;
}
cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(errno));
+ if (errno == ENOENT) {
+ /* Directory doesn't exist? */
+ if (create_parent_dirs(lockfile) == 0) {
+ /* OK. Retry. */
+ continue;
+ }
+ }
if (errno != EEXIST) {
/* Directory doesn't exist or isn't writable? */
goto out;
int ret = 0;
int fd1;
int fd2;
- struct stat st;
gzFile f1 = NULL;
gzFile f2 = NULL;
struct manifest *mf = NULL;
* not a big deal, and it's also very unlikely.
*/
- fd1 = safe_open(manifest_path);
+ fd1 = open(manifest_path, O_RDONLY | O_BINARY);
if (fd1 == -1) {
- cc_log("Failed to open manifest file");
- goto out;
- }
- if (fstat(fd1, &st) != 0) {
- cc_log("Failed to stat manifest file");
- close(fd1);
- goto out;
- }
- if (st.st_size == 0) {
/* New file. */
mf = create_empty_manifest();
} else {
}
tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());
- fd2 = safe_open(tmp_file);
+ fd2 = safe_create_wronly(tmp_file);
if (fd2 == -1) {
cc_log("Failed to open %s", tmp_file);
goto out;
tmp_file = format("%s.tmp.%s", path, tmp_string());
f = fopen(tmp_file, "wb");
+ if (!f && errno == ENOENT) {
+ if (create_parent_dirs(path) == 0) {
+ f = fopen(tmp_file, "wb");
+ }
+ }
if (!f) {
cc_log("Failed to open %s", tmp_file);
goto end;
if (!cache_dir) return;
stats_dir = format("%s/%x", cache_dir, hash_from_int(getpid()) % 16);
stats_file = format("%s/stats", stats_dir);
- create_dir(stats_dir);
free(stats_dir);
}
maxsize /= 16;
}
- if (create_dir(cache_dir) != 0) {
- return 1;
- }
-
/* set the limits in each directory */
for (dir = 0; dir <= 0xF; dir++) {
char *fname, *cdir;
cdir = format("%s/%1x", cache_dir, dir);
- if (create_dir(cdir) != 0) {
- free(cdir);
- return 1;
- }
fname = format("%s/stats", cdir);
free(cdir);
struct counters *counters = counters_init(STATS_END);
char *statsfile;
- create_dir(dir);
statsfile = format("%s/stats", dir);
if (lockfile_acquire(statsfile, lock_staleness_limit)) {
#endif
}
-/* a safe open/create for read-write */
+/*
+ * Create a file for writing. Creates parent directories if they don't exist.
+ */
int
-safe_open(const char *fname)
+safe_create_wronly(const char *fname)
{
- int fd = open(fname, O_RDWR|O_BINARY);
+ int fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
if (fd == -1 && errno == ENOENT) {
- fd = open(fname, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0666);
- if (fd == -1 && errno == EEXIST) {
- fd = open(fname, O_RDWR|O_BINARY);
+ /*
+ * Only make sure parent directories exist when have failed to open the
+ * file -- this saves stat() calls.
+ */
+ if (create_parent_dirs(fname) == 0) {
+ fd = open(fname, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0666);
}
}
return fd;