unsigned added_files = 0;
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());
+ create_empty_file(tmp_stderr);
tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
+ create_empty_file(tmp_obj);
args_add(args, "-o");
args_add(args, tmp_obj);
int fd_result;
char *tmp_stderr2;
- tmp_stderr2 = format("%s.tmp.stderr2.%s", cached_obj, tmp_string());
+ tmp_stderr2 = format("%s.2", tmp_stderr);
if (x_rename(tmp_stderr, tmp_stderr2)) {
cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
strerror(errno));
}
path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
+ create_empty_file(path_stderr);
add_pending_tmp_file(path_stderr);
time_of_compilation = time(NULL);
if (!direct_i_file) {
- path_stdout = format("%s/%s.tmp.%s.%s",
- temp_dir, input_base, tmp_string(), i_extension);
+ /* 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 =
+ 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, i_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 */
can skip the cpp stage and directly form the
correct i_tmpfile */
path_stdout = input_file;
- if (create_empty_file(path_stderr) != 0) {
- cc_log("Failed to create %s: %s", path_stderr, strerror(errno));
- stats_update(STATS_ERROR);
- failed();
- }
status = 0;
}
int safe_open(const char *fname);
char *x_realpath(const char *path);
char *gnu_getcwd(void);
-int create_empty_file(const char *fname);
+int create_empty_file(char *fname);
const char *get_home_directory(void);
char *get_cwd();
bool same_executable_name(const char *s1, const char *s2);
}
tmp_file = format("%s.tmp.%s", manifest_path, tmp_string());
- fd2 = safe_open(tmp_file);
+ 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");
+ fd = mkstemp(tmp_file);
+ if (fd == -1) {
+ cc_log("Failed to open %s", tmp_file);
+ goto end;
+ }
+ f = fdopen(fd, "wb");
if (!f) {
cc_log("Failed to open %s", tmp_file);
goto end;
fatal("Failed to write to %s", tmp_file);
}
}
- fclose(f);
+ fclose(f); /* This also implicitly closes the fd. */
x_rename(tmp_file, path);
end:
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");
}
/*
- * Return a string to be used to distinguish temporary files. Also tries to
- * cope with NFS by adding the local hostname.
+ * Return a string to be passed to mkstemp to create a temporary file. Also
+ * tries to cope with NFS by adding the local hostname.
*/
const char *
tmp_string(void)
static char *ret;
if (!ret) {
- ret = format("%s.%u", get_hostname(), (unsigned)getpid());
+ ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
}
return ret;
/* create an empty file */
int
-create_empty_file(const char *fname)
+create_empty_file(char *fname)
{
int fd;
- fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
+ fd = mkstemp(fname);
if (fd == -1) {
+ cc_log("Failed to create %s: %s", fname, strerror(errno));
return -1;
}
close(fd);
goto out;
}
if (unlink(tmp_name) == -1) {
- result = -1;
+ /* If it was released in a race, that's OK. */
+ if (errno != ENOENT) {
+ result = -1;
+ }
}
out:
free(tmp_name);