static void
to_cache(struct args *args)
{
- char *tmp_stdout, *tmp_stderr, *tmp_obj;
+ char *tmp_stdout, *tmp_stderr, *tmp_dia;
struct stat st;
int status;
- size_t added_bytes = 0;
- unsigned added_files = 0;
+ if (create_parent_dirs(cached_obj) != 0) {
+ fatal("Failed to create parent directory for %s: %s",
+ cached_obj, strerror(errno));
+ }
tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
+ create_empty_file(tmp_stdout);
tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
- tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
- create_empty_file(tmp_obj);
+ create_empty_file(tmp_stderr);
args_add(args, "-o");
- args_add(args, tmp_obj);
+ args_add(args, output_obj);
+
+ if (output_dia) {
+ tmp_dia = x_strdup(output_dia);
+ args_add(args, "--serialize-diagnostics");
+ args_add(args, tmp_dia);
+ } else {
+ tmp_dia = NULL;
+ }
/* Turn off DEPENDENCIES_OUTPUT when running cc1, because
* otherwise it will emit a line like
input_base[10] = 0;
}
- 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());
+ path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir(), tmp_string());
-
- if (create_parent_dirs(path_stdout) != 0) {
++ if (create_parent_dirs(path_stderr) != 0) {
+ fatal("Failed to create parent directory for %s: %s\n",
- path_stdout, strerror(errno));
++ path_stderr, strerror(errno));
+ }
-
- add_pending_tmp_file(path_stdout);
+ create_empty_file(path_stderr);
add_pending_tmp_file(path_stderr);
time_of_compilation = time(NULL);
if (!direct_i_file) {
- format("%s/%s.tmp.%s", temp_dir, input_base, tmp_string());
+ /* The temporary file needs the proper i_extension for the compiler to do
+ * its thing. However, create_empty_file requires the tmp_string() part to
+ * be last, which is why the temporary file is created in two steps. */
+ char *path_stdout_tmp =
- path_stdout = format("%s.%s", path_stdout_tmp, i_extension);
++ format("%s/%s.tmp.%s", temp_dir(), input_base, tmp_string());
+ create_empty_file(path_stdout_tmp);
++ path_stdout = format("%s.%s", path_stdout_tmp, conf->cpp_extension);
+ x_rename(path_stdout_tmp, path_stdout);
+ free(path_stdout_tmp);
+ add_pending_tmp_file(path_stdout);
+
/* run cpp on the input file to obtain the .i */
args_add(args, "-E");
args_add(args, input_file);
const char *get_extension(const char *path);
char *remove_extension(const char *path);
size_t file_size(struct stat *st);
- int safe_create_wronly(const char *fname);
-int safe_open(const char *fname);
+char *format_human_readable_size(uint64_t size);
+char *format_parsable_size_with_suffix(uint64_t size);
+bool parse_size_with_suffix(const char *str, uint64_t *size);
char *x_realpath(const char *path);
char *gnu_getcwd(void);
- int create_empty_file(const char *fname);
+#ifndef HAVE_STRTOK_R
+char *strtok_r(char *str, const char *delim, char **saveptr);
+#endif
+ int create_empty_file(char *fname);
const char *get_home_directory(void);
-char *get_cwd();
+char *get_cwd(void);
bool same_executable_name(const char *s1, const char *s2);
size_t common_dir_prefix_length(const char *s1, const char *s2);
char *get_relative_path(const char *from, const char *to);
}
tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());
- fd2 = safe_create_wronly(tmp_file);
+ fd2 = mkstemp(tmp_file);
++ if (fd2 == -1 && errno == ENOENT) {
++ if (create_parent_dirs(tmp_file) == 0) {
++ reformat(&tmp_file, "%s.tmp.%s", manifest_path, tmp_string());
++ fd2 = mkstemp(tmp_file);
++ }
++ }
if (fd2 == -1) {
cc_log("Failed to open %s", tmp_file);
goto out;
size_t i;
char *tmp_file;
FILE *f;
+ int fd;
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");
+ fd = mkstemp(tmp_file);
++ if (fd == -1 && errno == ENOENT) {
++ if (create_parent_dirs(tmp_file) == 0) {
++ reformat(&tmp_file, "%s.tmp.%s", path, tmp_string());
++ fd = mkstemp(tmp_file);
+ }
+ }
+ if (fd == -1) {
+ cc_log("Failed to open %s", tmp_file);
++ close(fd);
+ goto end;
+ }
+ f = fdopen(fd, "wb");
if (!f) {
cc_log("Failed to open %s", tmp_file);
goto end;
for (dir = 0; dir <= 0xF; dir++) {
struct counters *counters = counters_init(STATS_END);
- fname = format("%s/%1x/stats", cache_dir, dir);
+ struct stat st;
+ fname = format("%s/%1x/stats", conf->cache_dir, dir);
+ if (stat(fname, &st) != 0) {
+ /* No point in trying to reset the stats file if it doesn't exist. */
+ free(fname);
+ continue;
+ }
if (lockfile_acquire(fname, lock_staleness_limit)) {
stats_read(fname, counters);
for (i = 0; stats_info[i].message; i++) {
struct stat st;
int errnum;
- tmp_name = format("%s.%s.XXXXXX", dest, tmp_string());
+ tmp_name = format("%s.%s", dest, tmp_string());
- cc_log("Copying %s to %s via %s (%s)",
- src, dest, tmp_name, compress_dest ? "compressed": "uncompressed");
+
+ /* open destination file */
+ fd_out = mkstemp(tmp_name);
+ if (fd_out == -1) {
+ cc_log("mkstemp error: %s", strerror(errno));
+ goto error;
+ }
+
+ cc_log("Copying %s to %s via %s (%scompressed)",
+ src, dest, tmp_name, compress_level > 0 ? "" : "un");
/* open source file */
fd_in = open(src, O_RDONLY | O_BINARY);
#endif
}
- /*
- * Create a file for writing. Creates parent directories if they don't exist.
- */
-/* a safe open/create for read-write */
--int
- safe_create_wronly(const char *fname)
- {
- int fd = open(fname, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
- if (fd == -1 && errno == ENOENT) {
- /*
- * 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;
- }
-
-safe_open(const char *fname)
+/* Format a size as a human-readable string. Caller frees. */
+char *
+format_human_readable_size(uint64_t v)
{
- int fd = open(fname, O_RDWR|O_BINARY);
- 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);
- }
+ char *s;
+ if (v >= 1000*1000*1000) {
+ s = format("%.1f GB", v/((double)(1000*1000*1000)));
+ } else if (v >= 1000*1000) {
+ s = format("%.1f MB", v/((double)(1000*1000)));
+ } else {
+ s = format("%.1f kB", v/((double)(1000)));
}
- return fd;
+ return s;
}
-/* Format a size (in KiB) as a human-readable string. Caller frees. */
+/* Format a size as a parsable string. Caller frees. */
char *
-format_size(size_t v)
+format_parsable_size_with_suffix(uint64_t size)
{
char *s;
- if (v >= 1024*1024) {
- s = format("%.1f Gbytes", v/((double)(1024*1024)));
- } else if (v >= 1024) {
- s = format("%.1f Mbytes", v/((double)(1024)));
+ if (size >= 1000*1000*1000) {
+ s = format("%.1fG", size / ((double)(1000*1000*1000)));
+ } else if (size >= 1000*1000) {
+ s = format("%.1fM", size / ((double)(1000*1000)));
+ } else if (size >= 1000) {
+ s = format("%.1fk", size / ((double)(1000)));
} else {
- s = format("%.0f Kbytes", (double)v);
+ s = format("%u", (unsigned)size);
}
return s;
}
}
}
+#ifndef HAVE_STRTOK_R
+/* strtok_r replacement */
+char *
+strtok_r(char *str, const char *delim, char **saveptr)
+{
+ int len;
+ char *ret;
+ if (!str)
+ str = *saveptr;
+ len = strlen(str);
+ ret = strtok(str, delim);
+ if (ret) {
+ char *save = ret;
+ while (*save++);
+ if ((len + 1) == (intptr_t) (save - str))
+ save--;
+ *saveptr = save;
+ }
+ return ret;
+}
+#endif
+
/* create an empty file */
int
- create_empty_file(const char *fname)
+ create_empty_file(char *fname)
{
int fd;