Line data Source code
1 : // Copyright (c) 2012-2019 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // This program is free software; you can redistribute it and/or modify
4 : // it under the terms of the GNU General Public License as published by
5 : // the Free Software Foundation; either version 2 of the License, or
6 : // (at your option) any later version.
7 : //
8 : // This program is distributed in the hope that it will be useful,
9 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 : // GNU General Public License for more details.
12 : //
13 : // You should have received a copy of the GNU General Public License
14 : // along with this program; if not, write to the Free Software
15 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 : #pragma once
17 :
18 : // self
19 : //
20 : #include "eventdispatcher/connection.h"
21 : //#include "eventdispatcher/udp_client_server.h"
22 : //#include "eventdispatcher/utils.h"
23 :
24 :
25 : //// cppthread lib
26 : ////
27 : //#include "cppthread/thread.h"
28 : //
29 : //
30 : //// snapdev lib
31 : ////
32 : //#include "snapdev/not_used.h"
33 : //
34 : //
35 : // C++ lib
36 : //
37 : #include <map>
38 :
39 : //// C lib
40 : ////
41 : //#include <signal.h>
42 : //#include <sys/signalfd.h>
43 :
44 :
45 :
46 : namespace ed
47 : {
48 :
49 :
50 :
51 : class file_changed
52 : : public connection
53 : {
54 : public:
55 : typedef std::shared_ptr<file_changed> pointer_t;
56 : typedef std::uint32_t event_mask_t;
57 :
58 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_NO_EVENTS = 0x0000;
59 :
60 : // bits added to watch_...() functions
61 : //
62 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_ATTRIBUTES = 0x0001; // chmod, chown (timestamp, link count, user/group, etc.)
63 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_READ = 0x0002; // read, execve
64 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_WRITE = 0x0004; // write, truncate
65 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_CREATED = 0x0008; // open & O_CREAT, rename, mkdir, link, symlink, bind
66 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_DELETED = 0x0010; // unlink, rename
67 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_ACCESS = 0x0020; // open, close
68 :
69 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_IO = SNAP_FILE_CHANGED_EVENT_READ
70 : | SNAP_FILE_CHANGED_EVENT_WRITE;
71 :
72 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_ALL = SNAP_FILE_CHANGED_EVENT_ATTRIBUTES
73 : | SNAP_FILE_CHANGED_EVENT_IO
74 : | SNAP_FILE_CHANGED_EVENT_CREATED
75 : | SNAP_FILE_CHANGED_EVENT_DELETED
76 : | SNAP_FILE_CHANGED_EVENT_ACCESS;
77 :
78 : // flags added in event_t objects
79 : //
80 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_DIRECTORY = 0x1000; // object is a directory
81 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_GONE = 0x2000; // removed
82 : static event_mask_t const SNAP_FILE_CHANGED_EVENT_UNMOUNTED = 0x4000; // unmounted
83 :
84 0 : class event_t
85 : {
86 : public:
87 : event_t(std::string const & watched_path
88 : , event_mask_t events
89 : , std::string const & filename);
90 :
91 : std::string const & get_watched_path() const;
92 : event_mask_t get_events() const;
93 : std::string const & get_filename() const;
94 :
95 : bool operator < (event_t const & rhs) const;
96 :
97 : private:
98 : std::string f_watched_path = std::string();
99 : event_mask_t f_events = 0;
100 : std::string f_filename = std::string();
101 : };
102 :
103 : file_changed();
104 : virtual ~file_changed() override;
105 :
106 : void watch_file(std::string const & watched_path, event_mask_t const events);
107 : void watch_symlink(std::string const & watched_path, event_mask_t const events);
108 : void watch_directory(std::string const & watched_path, event_mask_t const events);
109 :
110 : void stop_watch(std::string const & watched_path);
111 :
112 : // snap_connection implementation
113 : virtual bool is_reader() const override;
114 : virtual int get_socket() const override;
115 : virtual void set_enable(bool enabled);
116 : virtual void process_read() override;
117 :
118 : // new callback
119 : virtual void process_event(event_t const & watch_event) = 0;
120 :
121 : private:
122 : // TODO: RAII would be great with an impl and a counter...
123 : // (i.e. we make copies at the moment.)
124 0 : struct watch_t
125 : {
126 : typedef std::map<int, watch_t> map_t;
127 :
128 : watch_t();
129 : watch_t(std::string const & watched_path, event_mask_t events, uint32_t add_flags);
130 :
131 : void add_watch(int inotify);
132 : void merge_watch(int inotify, event_mask_t const events);
133 : void remove_watch(int inotify);
134 :
135 : std::string f_watched_path = std::string();
136 : event_mask_t f_events = SNAP_FILE_CHANGED_EVENT_NO_EVENTS;
137 : uint32_t f_mask = 0;
138 : int f_watch = -1;
139 : };
140 :
141 : bool merge_watch(std::string const & watched_path, event_mask_t const events);
142 : static uint32_t events_to_mask(event_mask_t const events);
143 : static event_mask_t mask_to_events(uint32_t const mask);
144 :
145 : int f_inotify = -1;
146 : watch_t::map_t f_watches = watch_t::map_t();
147 : };
148 :
149 :
150 :
151 : } // namespace ed
152 : // vim: ts=4 sw=4 et
|