Welcome to mirror list, hosted at ThFree Co, Russian Federation.

inotify.cpp « mirall « src - github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 57c4e24246ed940937d4234918571ef7123afd58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/**
Based on example by:
Copyright (c) Ashish Shukla

This is licensed under GNU GPL v2 or later.
For license text, Refer to the the file COPYING or visit
http://www.gnu.org/licenses/gpl.txt .
*/

#include <sys/inotify.h>
#include <unistd.h>
#include <QDebug>
#include <QStringList>

#include "inotify.h"


// Buffer Size for read() buffer
#define BUFFERSIZE 512

namespace Mirall {

// Allocate space for static members of class.
int INotify::s_fd;
INotify::INotifyThread* INotify::s_thread;

//INotify::INotify(int wd) : _wd(wd)
//{
//}

INotify::INotify(int mask) : _mask(mask)
{
}

INotify::~INotify()
{
    // Unregister from iNotifier thread.
    s_thread->unregisterForNotification(this);

    // Remove all inotify watchs.
    QMap<QString, int>::const_iterator it;
    for (it = _wds.begin(); it != _wds.end(); ++it) {
        inotify_rm_watch(s_fd, *it);
    }
}

void INotify::addPath(const QString &path)
{
    // Add an inotify watch.
    qDebug() << path;

    path.toAscii().constData();
    return;


    int wd = inotify_add_watch(s_fd, path.toAscii().constData(), _mask);
    _wds[path] = wd;

    // Register for iNotifycation from iNotifier thread.
    s_thread->registerForNotification(this, wd);
}

void INotify::removePath(const QString &path)
{
    // Remove the inotify watch.
    inotify_rm_watch(s_fd, _wds[path]);
}

QStringList INotify::directories() const
{
    return _wds.keys();
}

void
INotify::INotifyThread::unregisterForNotification(INotify* notifier)
{
    //_map.remove(notifier->_wd);
    QHash<int, INotify*>::iterator it;
    for (it = _map.begin(); it != _map.end(); ++it) {
        if (it.value() == notifier)
            _map.remove(it.key());
    }
}

void
INotify::INotifyThread::registerForNotification(INotify* notifier, int wd)
{
    _map[wd] = notifier;
}

void
INotify::fireEvent(int mask, char* name)
{
    emit notifyEvent(mask, QString::fromUtf8(name));
}

void
INotify::initialize()
{
    s_fd = inotify_init();
    s_thread = new INotifyThread(s_fd);
    s_thread->start();
}

void
INotify::cleanup()
{
    close(s_fd);
    s_thread->terminate();
    s_thread->wait(3000);
    delete s_thread;
}

INotify::INotifyThread::INotifyThread(int fd) : _fd(fd)
{
}


// Thread routine
void
INotify::INotifyThread::run()
{
    int len;
    struct inotify_event* event;
    char buffer[BUFFERSIZE];
    INotify* n = NULL;
    int i;

    // read the inotify file descriptor.
    while((len = read(_fd, buffer, BUFFERSIZE)) > 0)
    {
        // reset counter
        i = 0;
        // while there are enough events in the buffer
        while(i + sizeof(struct inotify_event) < len)
        {
            // cast an inotify_event
            event = (struct inotify_event*)&buffer[i];
            // with the help of watch descriptor, retrieve, corresponding INotify
            n = _map[event->wd];
            // fire event
            n->fireEvent(event->mask, event->name);
            // increment counter
            i += sizeof(struct inotify_event) + event->len;
        }
    }
}

} // ns mirall

#include "inotify.moc"