Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/buffer_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down
44 changes: 28 additions & 16 deletions src/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,33 @@ std::pair<StringView, StringView> 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<char, MallocDeleter>;

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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -368,9 +380,9 @@ void make_directory(StringView dir, mode_t mode)

void list_files(StringView dirname, FunctionRef<void (StringView, const struct stat&)> 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;

Expand All @@ -384,12 +396,12 @@ void list_files(StringView dirname, FunctionRef<void (StringView, const struct s

struct stat st;
auto fmt_str = (dirname.empty() or dirname.back() == '/') ? "{}{}" : "{}/{}";
format_to(buffer, fmt_str, dirname, filename);
if (stat(buffer, &st) != 0)
buffer = format(fmt_str, dirname, filename);
if (stat(buffer.c_str(), &st) != 0)
continue;

if (S_ISDIR(st.st_mode))
filename = format_to(buffer, "{}/", filename);
filename = format(buffer.c_str(), "{}/", filename);
callback(filename, st);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/file.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ template<bool force_blocking = false>
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
{
Expand Down
5 changes: 2 additions & 3 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down