diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2014-05-03 19:36:22 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2014-05-03 19:36:22 -0700 |
commit | 8cbd66b0f9aa7bbbfc75d61f51520d653f9e34f3 (patch) | |
tree | 75d9c58b074886f5ed12a499bf589a2f2345d982 | |
parent | 56bf209f84d91d905dfd61905713c9c52b590872 (diff) | |
parent | 47a81c2b39cd814e9d225c714f47aa3e3a7324c4 (diff) |
Merge branch 'death_of_fishd' of https://github.com/fish-shell/fish-shell into death_of_fishd
-rw-r--r-- | env_universal_common.cpp | 65 | ||||
-rw-r--r-- | fish_tests.cpp | 4 |
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 } |