diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index 04c42468a4..2dcb5473bd 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -211,7 +211,7 @@ void write_buffer_to_file(Buffer& buffer, StringView filename, if (force and ::chmod(zfilename, st.st_mode | S_IWUSR) < 0) throw runtime_error(format("unable to change file permissions: {}", strerror(errno))); - char temp_filename[PATH_MAX]; + String temp_filename; const int fd = replace ? open_temp_file(filename, temp_filename) : create_file(zfilename); if (fd == -1) @@ -229,14 +229,14 @@ void write_buffer_to_file(Buffer& buffer, StringView filename, ::fsync(fd); } - if (replace and geteuid() == 0 and ::chown(temp_filename, st.st_uid, st.st_gid) < 0) + if (replace and geteuid() == 0 and ::chown(temp_filename.c_str(), st.st_uid, st.st_gid) < 0) throw runtime_error(format("unable to set replacement file ownership: {}", strerror(errno))); - if (replace and ::chmod(temp_filename, st.st_mode) < 0) + if (replace and ::chmod(temp_filename.c_str(), st.st_mode) < 0) throw runtime_error(format("unable to set replacement file permissions: {}", strerror(errno))); if (force and not replace and ::chmod(zfilename, st.st_mode) < 0) throw runtime_error(format("unable to restore file permissions: {}", strerror(errno))); - if (replace and rename(temp_filename, zfilename) != 0) + if (replace and rename(temp_filename.c_str(), zfilename) != 0) { if (force) ::chmod(zfilename, st.st_mode); diff --git a/src/file.cc b/src/file.cc index eb17379c55..eaa14b8524 100644 --- a/src/file.cc +++ b/src/file.cc @@ -63,24 +63,33 @@ std::pair split_path(StringView path) return { {path.begin(), slash+1}, {slash+1, path.end()} }; } +struct MallocDeleter +{ + void operator()(char *ptr) const + { + free(ptr); + } +}; + String real_path(StringView filename) { if (filename.empty()) return {}; - char buffer[PATH_MAX+1]; - StringView existing = filename; StringView non_existing{}; + using unique_cstr = std::unique_ptr; + while (true) { - if (char* res = realpath(existing.zstr(), buffer)) + unique_cstr res(realpath(existing.zstr(), nullptr)); + if (res) { if (non_existing.empty()) - return res; + return String(res.get()); - StringView dir = res; + StringView dir = res.get(); while (not dir.empty() and dir.back() == '/') dir = dir.substr(0_byte, dir.length()-1_byte); return format("{}/{}", dir, non_existing); @@ -295,22 +304,25 @@ void write_to_file(StringView filename, StringView data) write(fd, data); } -int open_temp_file(StringView filename, char (&buffer)[PATH_MAX]) +int open_temp_file(StringView filename, String &buffer) { String path = real_path(filename); auto [dir,file] = split_path(path); if (dir.empty()) - format_to(buffer, ".{}.kak.XXXXXX", file); + buffer = format(".{}.kak.XXXXXX", file); else - format_to(buffer, "{}/.{}.kak.XXXXXX", dir, file); + buffer = format("{}/.{}.kak.XXXXXX", dir, file); - return mkstemp(buffer); + char* tmplt = strndup(buffer.c_str(), (size_t)buffer.length()); + int fp = mkstemp(tmplt); + buffer = tmplt; + return fp; } int open_temp_file(StringView filename) { - char buffer[PATH_MAX]; + String buffer; return open_temp_file(filename, buffer); } @@ -368,9 +380,9 @@ void make_directory(StringView dir, mode_t mode) void list_files(StringView dirname, FunctionRef callback) { - char buffer[PATH_MAX+1]; - format_to(buffer, "{}", dirname); - DIR* dir = opendir(dirname.empty() ? "./" : buffer); + String buffer; + buffer = format("{}", dirname); + DIR* dir = opendir(dirname.empty() ? "./" : buffer.c_str()); if (not dir) return; @@ -384,12 +396,12 @@ void list_files(StringView dirname, FunctionRef void write(int fd, StringView data); void write_to_file(StringView filename, StringView data); int create_file(const char* filename); +int open_temp_file(StringView filename, String &tmpFile); int open_temp_file(StringView filename); -int open_temp_file(StringView filename, char (&buffer)[PATH_MAX]); struct MappedFile { diff --git a/src/main.cc b/src/main.cc index c584a48701..b4d4dfaaa1 100644 --- a/src/main.cc +++ b/src/main.cc @@ -116,10 +116,9 @@ String runtime_directory() if (const char* runtime_directory = getenv("KAKOUNE_RUNTIME")) return runtime_directory; - char relpath[PATH_MAX+1]; - format_to(relpath, "{}../share/kak", split_path(get_kak_binary_path()).first); + auto relpath = format("{}../share/kak", split_path(get_kak_binary_path()).first); struct stat st; - if (stat(relpath, &st) == 0 and S_ISDIR(st.st_mode)) + if (stat(relpath.c_str(), &st) == 0 and S_ISDIR(st.st_mode)) return real_path(relpath); return "/usr/share/kak";