| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Util/INotify.h>
- #include <AnKi/Util/Logger.h>
- #include <sys/inotify.h>
- #include <poll.h>
- #include <unistd.h>
- namespace anki {
- Error INotify::initInternal()
- {
- ANKI_ASSERT(m_fd < 0 && m_watch < 0);
- Error err = Error::kNone;
- m_fd = inotify_init();
- if(m_fd < 0)
- {
- ANKI_UTIL_LOGE("inotify_init() failed: %s", strerror(errno));
- err = Error::kFunctionFailed;
- }
- if(!err)
- {
- m_watch = inotify_add_watch(m_fd, &m_path[0], IN_MODIFY | IN_CREATE | IN_DELETE | IN_IGNORED | IN_DELETE_SELF);
- if(m_watch < 0)
- {
- ANKI_UTIL_LOGE("inotify_add_watch() failed: %s", strerror(errno));
- err = Error::kFunctionFailed;
- }
- }
- if(err)
- {
- destroyInternal();
- }
- return err;
- }
- void INotify::destroyInternal()
- {
- if(m_watch >= 0)
- {
- int err = inotify_rm_watch(m_fd, m_watch);
- if(err < 0)
- {
- ANKI_UTIL_LOGE("inotify_rm_watch() failed: %s\n", strerror(errno));
- }
- m_watch = -1;
- }
- if(m_fd >= 0)
- {
- int err = close(m_fd);
- if(err < 0)
- {
- ANKI_UTIL_LOGE("close() failed: %s\n", strerror(errno));
- }
- m_fd = -1;
- }
- }
- Error INotify::pollEvents(Bool& modified)
- {
- ANKI_ASSERT(m_fd >= 0 && m_watch >= 0);
- Error err = Error::kNone;
- modified = false;
- while(true)
- {
- pollfd pfd = {m_fd, POLLIN, 0};
- int ret = poll(&pfd, 1, 0);
- if(ret < 0)
- {
- ANKI_UTIL_LOGE("poll() failed: %s", strerror(errno));
- err = Error::kFunctionFailed;
- break;
- }
- else if(ret == 0)
- {
- // No events, move on
- break;
- }
- else
- {
- // Process the new event
- Array<U8, 2_KB> readBuff;
- PtrSize nbytes = read(m_fd, &readBuff[0], sizeof(readBuff));
- if(nbytes > 0)
- {
- inotify_event* event = reinterpret_cast<inotify_event*>(&readBuff[0]);
- if(event->mask & IN_IGNORED)
- {
- // File was moved or deleted. Some editors on save they delete the file and move another file to
- // its place. In that case the m_fd and the m_watch need to be re-created.
- m_watch = -1; // Watch descriptor was removed implicitly
- destroyInternal();
- err = initInternal();
- if(err)
- {
- break;
- }
- }
- else
- {
- modified = true;
- }
- }
- else
- {
- ANKI_UTIL_LOGE("read() failed to read the expected size of data: %s", strerror(errno));
- err = Error::kFunctionFailed;
- break;
- }
- }
- }
- return err;
- }
- } // end namespace anki
|