Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kakoune moved away to a custom UniquePtr implementation for compilation speed reasons, it does not support custom deleters as we did not have actual uses, but in this specific case a OnScopeEnd free{[&] { free(res); }; would probably do the trick.


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;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren´t we leaking tmplt here ? I am not sure why we need the strndup call in the first place, you can just use mkstemp(buffer.data()) which will be a pointer to the buffer string buffer and can be mutated safely as long as the string length does not change.

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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do not use camel case for parameters in kakoune, it should be tmp_file

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