aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-05-03 19:36:22 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-05-03 19:36:22 -0700
commit8cbd66b0f9aa7bbbfc75d61f51520d653f9e34f3 (patch)
tree75d9c58b074886f5ed12a499bf589a2f2345d982
parent56bf209f84d91d905dfd61905713c9c52b590872 (diff)
parent47a81c2b39cd814e9d225c714f47aa3e3a7324c4 (diff)
Merge branch 'death_of_fishd' of https://github.com/fish-shell/fish-shell into death_of_fishd
-rw-r--r--env_universal_common.cpp65
-rw-r--r--fish_tests.cpp4
2 files changed, 48 insertions, 21 deletions
diff --git a/env_universal_common.cpp b/env_universal_common.cpp
index 7d926efe..78c2515f 100644
--- a/env_universal_common.cpp
+++ b/env_universal_common.cpp
@@ -1590,43 +1590,53 @@ class universal_notifier_inotify_t : public universal_notifier_t
{
int watch_fd;
int watch_descriptor;
+ const std::string narrow_path;
+
+ void reestablish_watch()
+ {
+#if FISH_INOTIFY_AVAILABLE
+ if (this->watch_fd >= 0)
+ {
+ if (this->watch_descriptor >= 0)
+ {
+ inotify_rm_watch(this->watch_fd, this->watch_descriptor);
+ }
+ this->watch_descriptor = inotify_add_watch(this->watch_fd, narrow_path.c_str(), IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF | IN_EXCL_UNLINK);
+ if (this->watch_descriptor < 0)
+ {
+ wperror(L"inotify_add_watch");
+ }
+ }
+#endif
+ }
void setup_inotify(const wchar_t *test_path)
{
#if FISH_INOTIFY_AVAILABLE
-
- const wcstring path = test_path ? test_path : default_vars_path();
-
// Construct the watchfd
+
#if HAVE_INOTIFY_INIT1
this->watch_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
#else
this->watch_fd = inotify_init();
- if (this->watch_fd >= 0)
- {
- int flags = fcntl(this->watch_fd, F_GETFL, 0);
- fcntl(this->watch_fd, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC);
- }
#endif
+
if (this->watch_fd < 0)
{
wperror(L"inotify_init");
}
else
{
- std::string narrow_path = wcs2string(path);
- this->watch_descriptor = inotify_add_watch(this->watch_fd, narrow_path.c_str(), IN_MODIFY | IN_EXCL_UNLINK);
- if (this->watch_descriptor < 0)
- {
- wperror(L"inotify_add_watch");
- }
+ int flags = fcntl(this->watch_fd, F_GETFL, 0);
+ fcntl(this->watch_fd, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC);
}
+ reestablish_watch();
#endif
}
public:
- universal_notifier_inotify_t(const wchar_t *test_path) : watch_fd(-1), watch_descriptor(-1)
+ universal_notifier_inotify_t(const wchar_t *test_path) : watch_fd(-1), watch_descriptor(-1), narrow_path(wcs2string(test_path ? test_path : default_vars_path()))
{
setup_inotify(test_path);
}
@@ -1651,9 +1661,28 @@ public:
bool result = false;
#if FISH_INOTIFY_AVAILABLE
- struct inotify_event evt = {};
- ssize_t read_amt = read(watch_fd, &evt, sizeof evt);
- result = (read_amt > 0);
+ for (;;)
+ {
+ struct inotify_event evt = {};
+ ssize_t read_amt = read(watch_fd, &evt, sizeof evt);
+ if (read_amt >= sizeof evt)
+ {
+ if (evt.mask & (IN_DELETE_SELF | IN_MOVE_SELF))
+ {
+ // When a file is deleted, the watch is lost. Recreate it.
+ reestablish_watch();
+ result = true;
+ }
+ if (evt.mask & IN_MODIFY)
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
#endif
return result;
}
diff --git a/fish_tests.cpp b/fish_tests.cpp
index fc8eb569..7256c3df 100644
--- a/fish_tests.cpp
+++ b/fish_tests.cpp
@@ -2292,7 +2292,7 @@ static void trigger_or_wait_for_notification(universal_notifier_t *notifier, uni
{
// Hacktastic. Replace the file, then wait
char cmd[512];
- sprintf(cmd, "cp %ls %ls ; mv %ls %ls", UVARS_TEST_PATH, UVARS_TEST_PATH L".tmp", UVARS_TEST_PATH ".tmp", UVARS_TEST_PATH);
+ sprintf(cmd, "touch %ls ; mv %ls %ls", UVARS_TEST_PATH L".tmp", UVARS_TEST_PATH ".tmp", UVARS_TEST_PATH);
if (system(cmd)) err(L"Command failed: %s", cmd);
usleep(1000000 / 25);
break;
@@ -2371,8 +2371,6 @@ static void test_universal_notifiers()
test_notifiers_with_strategy(universal_notifier_t::strategy_notifyd);
#endif
#if __linux || linux
- if (system("mkdir -p /tmp/fish_uvars_test/ && touch /tmp/fish_uvars_test/varsfile.txt")) err(L"mkdir failed");
-
test_notifiers_with_strategy(universal_notifier_t::strategy_inotify);
#endif
}