summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-09-27 11:55:34 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-09-27 11:55:34 +0100
commite2720f1fbe09649e6da282cd33b9794867d3d0fb (patch)
treebb5f906151c28fc5fde6078b842a71c0ba4fc318 /src
parent122a799ecb7dd1a6d6ff392ab9dc9d88fafad770 (diff)
Store timespec for buffer fs timestamps, not just time_t
time_t has a resolution of one second, which cause troubles when a file changes multiple time during that same second.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.cc8
-rw-r--r--src/buffer.hh12
-rw-r--r--src/buffer_utils.cc4
-rw-r--r--src/buffer_utils.hh2
-rw-r--r--src/client.cc2
-rw-r--r--src/file.cc16
-rw-r--r--src/file.hh12
7 files changed, 33 insertions, 23 deletions
diff --git a/src/buffer.cc b/src/buffer.cc
index 0685e5b3..02f076d0 100644
--- a/src/buffer.cc
+++ b/src/buffer.cc
@@ -18,7 +18,7 @@ namespace Kakoune
{
Buffer::Buffer(String name, Flags flags, BufferLines lines,
- time_t fs_timestamp)
+ timespec fs_timestamp)
: Scope(GlobalScope::instance()),
m_name((flags & Flags::File) ? real_path(parse_filename(name)) : std::move(name)),
m_display_name((flags & Flags::File) ? compact_path(m_name) : m_name),
@@ -160,7 +160,7 @@ struct Buffer::Modification
}
};
-void Buffer::reload(BufferLines lines, time_t fs_timestamp)
+void Buffer::reload(BufferLines lines, timespec fs_timestamp)
{
if (lines.empty())
lines.emplace_back(StringData::create("\n"));
@@ -531,13 +531,13 @@ ByteCoord Buffer::char_prev(ByteCoord coord) const
return coord;
}
-time_t Buffer::fs_timestamp() const
+timespec Buffer::fs_timestamp() const
{
kak_assert(m_flags & Flags::File);
return m_fs_timestamp;
}
-void Buffer::set_fs_timestamp(time_t ts)
+void Buffer::set_fs_timestamp(timespec ts)
{
kak_assert(m_flags & Flags::File);
m_fs_timestamp = ts;
diff --git a/src/buffer.hh b/src/buffer.hh
index ba5a62df..5342dd83 100644
--- a/src/buffer.hh
+++ b/src/buffer.hh
@@ -14,7 +14,7 @@ namespace Kakoune
class Buffer;
-constexpr time_t InvalidTime = 0;
+constexpr timespec InvalidTime = { -1, -1 };
// A BufferIterator permits to iterate over the characters of a buffer
class BufferIterator
@@ -79,7 +79,7 @@ public:
};
Buffer(String name, Flags flags, BufferLines lines = {},
- time_t fs_timestamp = InvalidTime);
+ timespec fs_timestamp = InvalidTime);
Buffer(const Buffer&) = delete;
Buffer& operator= (const Buffer&) = delete;
~Buffer();
@@ -93,8 +93,8 @@ public:
BufferIterator erase(BufferIterator begin, BufferIterator end);
size_t timestamp() const;
- time_t fs_timestamp() const;
- void set_fs_timestamp(time_t ts);
+ timespec fs_timestamp() const;
+ void set_fs_timestamp(timespec ts);
void commit_undo_group();
bool undo();
@@ -152,7 +152,7 @@ public:
void run_hook_in_own_context(StringView hook_name, StringView param);
- void reload(BufferLines lines, time_t fs_timestamp = InvalidTime);
+ void reload(BufferLines lines, timespec fs_timestamp = InvalidTime);
void check_invariant() const;
@@ -213,7 +213,7 @@ private:
Vector<Change, MemoryDomain::BufferMeta> m_changes;
- time_t m_fs_timestamp;
+ timespec m_fs_timestamp;
// Values are just data holding by the buffer, they are not part of its
// observable state
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index c6795fe1..0bebf5d6 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -47,7 +47,7 @@ ByteCount get_byte_to_column(const Buffer& buffer, CharCount tabstop, CharCoord
}
Buffer* create_buffer_from_data(StringView data, StringView name,
- Buffer::Flags flags, time_t fs_timestamp)
+ Buffer::Flags flags, timespec fs_timestamp)
{
bool bom = false, crlf = false;
@@ -98,7 +98,7 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll)
if (buffer)
{
buffer->flags() |= Buffer::Flags::NoUndo;
- buffer->reload({"\n"_ss}, 0);
+ buffer->reload({"\n"_ss}, InvalidTime);
}
else
buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
diff --git a/src/buffer_utils.hh b/src/buffer_utils.hh
index 33609150..ab02451f 100644
--- a/src/buffer_utils.hh
+++ b/src/buffer_utils.hh
@@ -34,7 +34,7 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll = false);
Buffer* create_buffer_from_data(StringView data, StringView name,
Buffer::Flags flags,
- time_t fs_timestamp = InvalidTime);
+ timespec fs_timestamp = InvalidTime);
void write_to_debug_buffer(StringView str);
diff --git a/src/client.cc b/src/client.cc
index 9da589b5..da218b7c 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -246,7 +246,7 @@ void Client::check_if_buffer_needs_reloading()
return;
const String& filename = buffer.name();
- time_t ts = get_fs_timestamp(filename);
+ timespec ts = get_fs_timestamp(filename);
if (ts == InvalidTime or ts == buffer.fs_timestamp())
return;
if (reload == Ask)
diff --git a/src/file.cc b/src/file.cc
index 2e67f872..ad526a93 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -180,13 +180,13 @@ Buffer* create_buffer_from_file(StringView filename)
throw file_access_error(real_filename, "is a directory");
if (S_ISFIFO(st.st_mode)) // Do not try to read fifos, use them as write only
return create_buffer_from_data({}, real_filename,
- Buffer::Flags::File, st.st_mtime);
+ Buffer::Flags::File, st.st_mtim);
const char* data = (const char*)mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
auto unmap = on_scope_end([&]{ munmap((void*)data, st.st_size); });
return create_buffer_from_data({data, data + st.st_size}, real_filename,
- Buffer::Flags::File, st.st_mtime);
+ Buffer::Flags::File, st.st_mtim);
}
static void write(int fd, StringView data)
@@ -423,11 +423,11 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
return res;
}
- typedef decltype(stat::st_mtime) TimeSpec;
+ typedef decltype(stat::st_mtim) TimeSpec;
struct CommandCache
{
- TimeSpec mtime = {};
+ TimeSpec mtim = {};
Vector<String> commands;
};
static UnorderedMap<String, CommandCache, MemoryDomain::Commands> command_cache;
@@ -442,7 +442,7 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
continue;
auto& cache = command_cache[dirname];
- if (memcmp(&cache.mtime, &st.st_mtime, sizeof(TimeSpec)) != 0)
+ if (memcmp(&cache.mtim, &st.st_mtim, sizeof(TimeSpec)) != 0)
{
auto filter = [&](const dirent& entry) {
struct stat st;
@@ -457,7 +457,7 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
};
cache.commands = list_files("", dirname, filter);
- memcpy(&cache.mtime, &st.st_mtime, sizeof(TimeSpec));
+ memcpy(&cache.mtim, &st.st_mtim, sizeof(TimeSpec));
}
for (auto& cmd : cache.commands)
{
@@ -471,12 +471,12 @@ Vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
return res;
}
-time_t get_fs_timestamp(StringView filename)
+timespec get_fs_timestamp(StringView filename)
{
struct stat st;
if (stat(filename.zstr(), &st) != 0)
return InvalidTime;
- return st.st_mtime;
+ return st.st_mtim;
}
String get_kak_binary_path()
diff --git a/src/file.hh b/src/file.hh
index ef51c2d8..6061d402 100644
--- a/src/file.hh
+++ b/src/file.hh
@@ -52,7 +52,17 @@ Vector<String> list_files(StringView directory);
void make_directory(StringView dir);
-time_t get_fs_timestamp(StringView filename);
+timespec get_fs_timestamp(StringView filename);
+
+constexpr bool operator==(const timespec& lhs, const timespec& rhs)
+{
+ return lhs.tv_sec == rhs.tv_sec and lhs.tv_nsec == rhs.tv_nsec;
+}
+
+constexpr bool operator!=(const timespec& lhs, const timespec& rhs)
+{
+ return not (lhs == rhs);
+}
CandidateList complete_filename(StringView prefix, const Regex& ignore_regex,
ByteCount cursor_pos = -1);