}
}
-std::pair<int, std::string>
-create_temp_fd(string_view path_prefix)
-{
- char* tmp_path = x_strndup(path_prefix.data(), path_prefix.length());
- int fd = create_tmp_fd(&tmp_path);
- std::string actual_path = tmp_path;
- free(tmp_path);
- return {fd, actual_path};
-}
-
string_view
dir_name(string_view path)
{
return path;
}
-string_view
-get_truncated_base_name(string_view path, size_t max_length)
-{
- string_view input_base = Util::base_name(path);
- size_t dot_pos = input_base.find('.');
- size_t truncate_pos =
- std::min(max_length, std::min(input_base.size(), dot_pos));
- return input_base.substr(0, truncate_pos);
-}
-
bool
is_absolute_path(string_view path)
{
// Returns true if the directory exists or could be created, otherwise false.
bool create_dir(nonstd::string_view dir);
-// Create a unique temporary file.
-//
-// Parameters:
-// - path_prefix: Base path. The resulting filename will be this path plus a
-// unique suffix.
-//
-// Returns the open file descriptor (in read/write mode) and the actual
-// filename.
-std::pair<int, std::string> create_temp_fd(nonstd::string_view path_prefix);
-
// Get directory name of path.
nonstd::string_view dir_name(nonstd::string_view path);
nonstd::string_view name,
nonstd::string_view suffix);
-// Return a shortened view into the base name of `path`. This view starts at the
-// beginning of the base name and ends at either the position the first dot, or
-// `max_length`, or the length of the base name, whichever is the shortest.
-nonstd::string_view get_truncated_base_name(nonstd::string_view path,
- size_t max_length);
-
// Write bytes in big endian order from an integer value.
//
// Parameters:
return true;
}
-#ifndef HAVE_MKSTEMP
-// Cheap and nasty mkstemp replacement.
-int
-mkstemp(char* name_template)
-{
-# ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-# endif
- mktemp(name_template);
-# ifdef __GNUC__
-# pragma GCC diagnostic pop
-# endif
- return open(name_template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
-}
-#endif
-
-#ifndef _WIN32
-static mode_t
-get_umask()
-{
- static bool mask_retrieved = false;
- static mode_t mask;
- if (!mask_retrieved) {
- mask = umask(0);
- umask(mask);
- mask_retrieved = true;
- }
- return mask;
-}
-#endif
-
// Clone a file from src to dest. If via_tmp_file is true, the file is cloned
// to a temporary file and then renamed to dest.
bool
clone_file(const char* src, const char* dest, bool via_tmp_file)
{
#ifdef FILE_CLONING_SUPPORTED
-
bool result;
# if defined(__linux__)
return 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()
-{
- static char* ret;
- if (!ret) {
- ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
- }
- return ret;
-}
-
// Construct a string according to a format. Caller frees.
char*
format(const char* format, ...)
}
#endif
-// Create an empty temporary file. *fname will be reallocated and set to the
-// resulting filename. Returns an open file descriptor to the file.
-int
-create_tmp_fd(char** fname)
-{
- char* tmpl = format("%s.%s", *fname, tmp_string());
- int fd = mkstemp(tmpl);
- if (fd == -1 && errno == ENOENT) {
- auto dir = Util::dir_name(*fname);
- if (!Util::create_dir(dir)) {
- fatal("Failed to create directory %s: %s",
- std::string(dir).c_str(),
- strerror(errno));
- }
- reformat(&tmpl, "%s.%s", *fname, tmp_string());
- fd = mkstemp(tmpl);
- }
- if (fd == -1) {
- fatal(
- "Failed to create temporary file for %s: %s", *fname, strerror(errno));
- }
- set_cloexec_flag(fd);
-
-#ifndef _WIN32
- fchmod(fd, 0666 & ~get_umask());
-#endif
-
- free(*fname);
- *fname = tmpl;
- return fd;
-}
-
// Return current user's home directory, or throw FatalError if it can't be
// determined.
const char*
bool copy_file(const char* src, const char* dest, bool via_tmp_file);
bool move_file(const char* src, const char* dest);
const char* get_hostname();
-const char* tmp_string();
char* format(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
void reformat(char** ptr, const char* format, ...) ATTR_FORMAT(printf, 2, 3);
char* x_strdup(const char* s);
#ifndef HAVE_LOCALTIME_R
struct tm* localtime_r(const time_t* timep, struct tm* result);
#endif
-int create_tmp_fd(char** fname);
const char* get_home_directory();
bool same_executable_name(const char* s1, const char* s2);
bool is_full_path(const char* path);
== "/zz/ccache/A/B/C/D/EF.suffix");
}
-TEST_CASE("Util:get_truncated_base_name")
-{
- CHECK(Util::get_truncated_base_name("", 5) == "");
- CHECK(Util::get_truncated_base_name("a", 5) == "a");
- CHECK(Util::get_truncated_base_name("abcdefg", 5) == "abcde");
- CHECK(Util::get_truncated_base_name("abc.foo", 5) == "abc");
- CHECK(Util::get_truncated_base_name("/path/to/abc.foo", 5) == "abc");
- CHECK(Util::get_truncated_base_name("/path/to/abcdefg.foo", 5) == "abcde");
- CHECK(Util::get_truncated_base_name("/path/to/.hidden", 5) == "");
- CHECK(Util::get_truncated_base_name("/path/to/", 5) == "");
-}
-
TEST_CASE("Util::int_to_big_endian")
{
uint8_t bytes[8];