コード例 #1
0
 int DoAddInotify(wxFSWatchEntry* watch)
 {
     int flags = Watcher2NativeFlags(watch->GetFlags());
     int wd = inotify_add_watch(m_ifd, watch->GetPath().fn_str(), flags);
     // finally we can set watch descriptor
     watch->SetWatchDescriptor(wd);
     return wd;
 }
コード例 #2
0
ファイル: fswatcher_kqueue.cpp プロジェクト: madnessw/thesnow
    virtual bool DoAdd(wxSharedPtr<wxFSWatchEntryKq> watch)
    {
        wxCHECK_MSG( IsOk(), false,
                    "Kqueue not initialized or invalid kqueue descriptor" );

        struct kevent event;
        int action = EV_ADD | EV_ENABLE | EV_CLEAR | EV_ERROR;
        int flags = Watcher2NativeFlags(watch->GetFlags());
        EV_SET( &event, watch->GetFileDescriptor(), EVFILT_VNODE, action,
                flags, 0, watch.get() );

        // TODO more error conditions according to man
        // TODO best deal with the error here
        int ret = kevent(m_kfd, &event, 1, NULL, 0, NULL);
        if (ret == -1)
        {
            wxLogSysError(_("Unable to add kqueue watch"));
            return false;
        }

        return true;
    }
コード例 #3
0
ファイル: fswatcher.cpp プロジェクト: Richard-Ni/wxWidgets
bool wxFSWatcherImplMSW::DoSetUpWatch(wxFSWatchEntryMSW& watch)
{
    BOOL bWatchSubtree wxDUMMY_INITIALIZE(FALSE);

    switch ( watch.GetType() )
    {
        case wxFSWPath_File:
            wxLogError(_("Monitoring individual files for changes is not "
                         "supported currently."));
            return false;

        case wxFSWPath_Dir:
            bWatchSubtree = FALSE;
            break;

        case wxFSWPath_Tree:
            bWatchSubtree = TRUE;
            break;

        case wxFSWPath_None:
            wxFAIL_MSG( "Invalid watch type." );
            return false;
    }

    int flags = Watcher2NativeFlags(watch.GetFlags());
    int ret = ReadDirectoryChangesW(watch.GetHandle(), watch.GetBuffer(),
                                    wxFSWatchEntryMSW::BUFFER_SIZE,
                                    bWatchSubtree,
                                    flags, NULL,
                                    watch.GetOverlapped(), NULL);
    if (!ret)
    {
        wxLogSysError(_("Unable to set up watch for '%s'"),
                        watch.GetPath());
    }

    return ret != 0;
}
コード例 #4
0
    void ProcessNativeEvent(const inotify_event& inevt)
    {
        wxLogTrace(wxTRACE_FSWATCHER, InotifyEventToString(inevt));

        // after removing inotify watch we get IN_IGNORED for it, but the watch
        // will be already removed from our list at that time
        if (inevt.mask & IN_IGNORED)
        {
            return;
        }

        // get watch entry for this event
        wxFSWatchEntryDescriptors::iterator it = m_watchMap.find(inevt.wd);
        wxCHECK_RET(it != m_watchMap.end(),
                             "Watch descriptor not present in the watch map!");

        wxFSWatchEntry& watch = *(it->second);
        int nativeFlags = inevt.mask;
        int flags = Native2WatcherFlags(nativeFlags);

        // check out for error/warning condition
        if (flags & wxFSW_EVENT_WARNING || flags & wxFSW_EVENT_ERROR)
        {
            wxString errMsg = GetErrorDescription(Watcher2NativeFlags(flags));
            wxFileSystemWatcherEvent event(flags, errMsg);
            SendEvent(event);
        }
        // filter out ignored events and those not asked for.
        // we never filter out warnings or exceptions
        else if ((flags == 0) || !(flags & watch.GetFlags()))
        {
            return;
        }
        // renames
        else if (nativeFlags & IN_MOVE)
        {
            wxInotifyCookies::iterator it = m_cookies.find(inevt.cookie);
            if ( it == m_cookies.end() )
            {
                int size = sizeof(inevt) + inevt.len;
                inotify_event* e = (inotify_event*) operator new (size);
                memcpy(e, &inevt, size);

                wxInotifyCookies::value_type val(e->cookie, e);
                m_cookies.insert(val);
            }
            else
            {
                inotify_event& oldinevt = *(it->second);

                wxFileSystemWatcherEvent event(flags);
                if ( inevt.mask & IN_MOVED_FROM )
                {
                    event.SetPath(GetEventPath(watch, inevt));
                    event.SetNewPath(GetEventPath(watch, oldinevt));
                }
                else
                {
                    event.SetPath(GetEventPath(watch, oldinevt));
                    event.SetNewPath(GetEventPath(watch, inevt));
                }
                SendEvent(event);

                m_cookies.erase(it);
                delete &oldinevt;
            }
        }
        // every other kind of event
        else
        {
            wxFileName path = GetEventPath(watch, inevt);
            wxFileSystemWatcherEvent event(flags, path, path);
            SendEvent(event);
        }
    }
コード例 #5
0
    void ProcessNativeEvent(const inotify_event& inevt)
    {
        wxLogTrace(wxTRACE_FSWATCHER, InotifyEventToString(inevt));

        // after removing inotify watch we get IN_IGNORED for it, but the watch
        // will be already removed from our list at that time
        if (inevt.mask & IN_IGNORED)
        {
            // It is now safe to remove it from the stale descriptors too, we
            // won't get any more events for it.
            // However if we're here because a dir that we're still watching
            // has just been deleted, its wd won't be on this list
            const int pos = m_staleDescriptors.Index(inevt.wd);
            if ( pos != wxNOT_FOUND )
            {
                m_staleDescriptors.RemoveAt(static_cast<size_t>(pos));
                wxLogTrace(wxTRACE_FSWATCHER,
                       "Removed wd %i from the stale-wd cache", inevt.wd);
            }
            return;
        }

        // get watch entry for this event
        wxFSWatchEntryDescriptors::iterator it = m_watchMap.find(inevt.wd);
        if (it == m_watchMap.end())
        {
            // It's not in the map; check if was recently removed from it.
            if (m_staleDescriptors.Index(inevt.wd) != wxNOT_FOUND)
            {
                wxLogTrace(wxTRACE_FSWATCHER,
                           "Got an event for stale wd %i", inevt.wd);
            }
            else
            {
                wxFAIL_MSG("Event for unknown watch descriptor.");
            }

            // In any case, don't process this event: it's either for an
            // already removed entry, or for a completely unknown one.
            return;
        }

        wxFSWatchEntry& watch = *(it->second);
        int nativeFlags = inevt.mask;
        int flags = Native2WatcherFlags(nativeFlags);

        // check out for error/warning condition
        if (flags & wxFSW_EVENT_WARNING || flags & wxFSW_EVENT_ERROR)
        {
            wxString errMsg = GetErrorDescription(Watcher2NativeFlags(flags));
            wxFileSystemWatcherEvent event(flags, errMsg);
            SendEvent(event);
        }
        // filter out ignored events and those not asked for.
        // we never filter out warnings or exceptions
        else if ((flags == 0) || !(flags & watch.GetFlags()))
        {
            return;
        }

        // Creation
        // We need do something here only if the original watch was recursive;
        // we don't watch a child dir itself inside a non-tree watch.
        // We watch only dirs explicitly, so we don't want file IN_CREATEs.
        // Distinguish by whether nativeFlags contain IN_ISDIR
        else if ((nativeFlags & IN_CREATE) &&
                 (watch.GetType() == wxFSWPath_Tree) && (inevt.mask & IN_ISDIR))
        {
            wxFileName fn = GetEventPath(watch, inevt);
            // Though it's a dir, fn treats it as a file. So:
            fn.AssignDir(fn.GetFullPath());

            if (m_watcher->AddAny(fn, wxFSW_EVENT_ALL,
                                   wxFSWPath_Tree, watch.GetFilespec()))
            {
                // Tell the owner, in case it's interested
                // If there's a filespec, assume he's not
                if (watch.GetFilespec().empty())
                {
                    wxFileSystemWatcherEvent event(flags, fn, fn);
                    SendEvent(event);
                }
            }
        }

        // Deletion
        // We watch only dirs explicitly, so we don't want file IN_DELETEs.
        // We obviously can't check using DirExists() as the object has been
        // deleted; and nativeFlags here doesn't contain IN_ISDIR, even for
        // a dir. Fortunately IN_DELETE_SELF doesn't happen for files. We need
        // to do something here only inside a tree watch, or if it's the parent
        // dir that's deleted. Otherwise let the parent dir cope
        else if ((nativeFlags & IN_DELETE_SELF) &&
                    ((watch.GetType() == wxFSWPath_Dir) ||
                     (watch.GetType() == wxFSWPath_Tree)))
        {
            // We must remove the deleted directory from the map, so that
            // DoRemoveInotify() isn't called on it in the future. Don't assert
            // if the wd isn't found: repeated IN_DELETE_SELFs can occur
            wxFileName fn = GetEventPath(watch, inevt);
            wxString path(fn.GetPathWithSep());

            if (m_watchMap.erase(inevt.wd) == 1)
            {
                // Delete from wxFileSystemWatcher
                wxDynamicCast(m_watcher, wxInotifyFileSystemWatcher)->
                                            OnDirDeleted(path);

                // Now remove from our local list of watched items
                wxFSWatchEntries::iterator wit =
                                        m_watches.find(path);
                if (wit != m_watches.end())
                {
                    m_watches.erase(wit);
                }

                // Cache the wd in case any events arrive late
                m_staleDescriptors.Add(inevt.wd);
            }

            // Tell the owner, in case it's interested
            // If there's a filespec, assume he's not
            if (watch.GetFilespec().empty())
            {
                wxFileSystemWatcherEvent event(flags, fn, fn);
                SendEvent(event);
            }
        }

        // renames
        else if (nativeFlags & IN_MOVE)
        {
            wxInotifyCookies::iterator it2 = m_cookies.find(inevt.cookie);
            if ( it2 == m_cookies.end() )
            {
                int size = sizeof(inevt) + inevt.len;
                inotify_event* e = (inotify_event*) operator new (size);
                memcpy(e, &inevt, size);

                wxInotifyCookies::value_type val(e->cookie, e);
                m_cookies.insert(val);
            }
            else
            {
                inotify_event& oldinevt = *(it2->second);

                // Tell the owner, in case it's interested
                // If there's a filespec, assume he's not
                if ( watch.GetFilespec().empty() )
                {
                    wxFileSystemWatcherEvent event(flags);
                    if ( inevt.mask & IN_MOVED_FROM )
                    {
                        event.SetPath(GetEventPath(watch, inevt));
                        event.SetNewPath(GetEventPath(watch, oldinevt));
                    }
                    else
                    {
                        event.SetPath(GetEventPath(watch, oldinevt));
                        event.SetNewPath(GetEventPath(watch, inevt));
                    }
                    SendEvent(event);
                }

                m_cookies.erase(it2);
                delete &oldinevt;
            }
        }
        // every other kind of event
        else
        {
            wxFileName path = GetEventPath(watch, inevt);
            // For files, check that it matches any filespec
            if ( MatchesFilespec(path, watch.GetFilespec()) )
            {
                wxFileSystemWatcherEvent event(flags, path, path);
                SendEvent(event);
            }
        }
    }