]> pilppa.org Git - libplpha.git/blob - src/servicedir_listener.c
copy headers with make install, start integrating sysout methods to use libplp
[libplpha.git] / src / servicedir_listener.c
1 /*
2  * servicedir_listener.c
3  *
4  *  Created on: Sep 25, 2010
5  *      Author: lamikr
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <sys/inotify.h>
14 #include <stdbool.h>
15 #include <pthread.h>
16 #include <fcntl.h>
17
18 #include <plp/log.h>
19
20 #include "common.h"
21 #include "servicedir_listener.h"
22
23 static pthread_t        _listener_thread;
24 static bool             _listener_stop_requested;
25 static bool             _listener_running               = false;
26 static int              _dir_handle                     = -1;
27 static int              _inotify_handle                 = -1;
28 static pthread_mutex_t  _listener_mutex;
29
30 static void init_servicedir_listener() {
31         //_listener_mutex                       = PTHREAD_MUTEX_INITIALIZER;
32         pthread_mutex_init(&_listener_mutex, NULL);
33 }
34
35 static void deinit_servicedir_listener() {
36         pthread_mutex_destroy(&_listener_mutex);
37 }
38
39 static void *servicedir_listener_thread(void *thread_args_pointer)
40 {
41         int                     b_count;
42         int                     ii;
43         char                    *buffer;
44         struct inotify_event    *event;
45         int                     buffer_max_size;
46
47         /*
48          * Size of each i-notify event read: size of event structure + filename length that caused the event. (name follows the struct).
49          * We create a buffer that could in theory handle 16 events for files which name would be in maximum 1024 chars. (=CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE)
50          */
51         buffer_max_size = CONST_MAX_INOTIFY_EVENT_COUNT_READ * (sizeof(struct inotify_event) + CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE);
52         buffer          = calloc(1, buffer_max_size);
53         if (buffer != NULL) {
54                 _inotify_handle = inotify_init();
55                 if (_inotify_handle >= 0) {
56                         _dir_handle     = inotify_add_watch(_inotify_handle,
57                                                 CONST_SERVICE_DIRECTORY_LOCATION,
58                                                 IN_CREATE | IN_ATTRIB | IN_MODIFY | IN_DELETE);
59                         if (_dir_handle >= 0) {
60                                 log_info("Waiting service directory file events\n");
61                                 while (_listener_stop_requested == false) {
62                                         ii      = 0;
63                                         log_debug("Waiting service directory file event\n");
64                                         b_count = read(_inotify_handle,
65                                                         buffer,
66                                                         buffer_max_size);
67                                         log_debug("Service directory file event received\n");
68                                         if (b_count >= 0) {
69                                                 while (ii < b_count) {
70                                                         event   = (struct inotify_event *)&buffer[ii];
71                                                         log_debug("event length = %d\n", event->len);
72                                                         if (event->len) {
73                                                                 if (event->mask & IN_CREATE) {
74                                                                         if ((event->mask & IN_ISDIR) == 0) {
75                                                                                 log_info("file create event: %s\n", event->name);
76                                                                         }
77                                                                         else {
78                                                                                 log_debug("sub-directory create event: %s, no need to process\n", event->name);
79                                                                         }
80                                                                 }
81                                                                 else if (event->mask & IN_ATTRIB) {
82                                                                         if ((event->mask & IN_ISDIR) == 0) {
83                                                                                 log_info("file attribute change event: %s\n", event->name);
84                                                                         }
85                                                                         else {
86                                                                                 log_debug("sub-directory attribute change event: %s, no need to process\n", event->name);
87                                                                         }
88                                                                 }
89                                                                 else if (event->mask & IN_MODIFY) {
90                                                                         if ((event->mask & IN_ISDIR) == 0) {
91                                                                                 log_info("file modify event: %s\n", event->name);
92                                                                         }
93                                                                         else {
94                                                                                 log_debug("sub-directory modify event: %s, no need to process\n", event->name);
95                                                                         }
96                                                                 }
97                                                                 else if (event->mask & IN_DELETE) {
98                                                                         if ((event->mask & IN_ISDIR) == 0) {
99                                                                                 log_info("file delete event: %s\n", event->name);
100                                                                         }
101                                                                         else {
102                                                                                 log_debug("sub-directory delete event: %s, no need to process\n", event->name);
103                                                                         }
104                                                                 }
105                                                         }
106                                                         ii      = ii + sizeof(struct inotify_event) + event->len;
107                                                 }
108                                         }
109                                         else {
110                                                 log_error("Failed to initialize service directory listener: %s, event read failed.\n", CONST_SERVICE_DIRECTORY_LOCATION);
111                                         }
112                                 }
113                                 log_info("Closing service directory listener: %s, close request received.\n", CONST_SERVICE_DIRECTORY_LOCATION);
114                                 pthread_mutex_lock(&_listener_mutex);
115                                 if ((_inotify_handle > 0) && (_dir_handle)) {
116                                         inotify_rm_watch(_inotify_handle, _dir_handle);
117                                         _dir_handle     = -1;
118                                 }
119                                 pthread_mutex_unlock(&_listener_mutex);
120                         }
121                         else {
122                                 log_error("Failed to initialize service directory listener: %s, event listener start-up error.\n", CONST_SERVICE_DIRECTORY_LOCATION);
123                         }
124                         pthread_mutex_lock(&_listener_mutex);
125                         if (_inotify_handle > 0) {
126                                 close(_inotify_handle);
127                                 _inotify_handle = -1;
128                         }
129                         pthread_mutex_unlock(&_listener_mutex);
130                 }
131                 else {
132                         log_error("Failed to initialize service directory listener: %s\n", CONST_SERVICE_DIRECTORY_LOCATION);
133                 }
134                 if (buffer != NULL) {
135                         free(buffer);
136                         buffer  = NULL;
137                 }
138         }
139         else {
140                 log_error("Failed to initialize service directory listener: %s, buffer allocation error.\n", CONST_SERVICE_DIRECTORY_LOCATION);
141         }
142         _listener_running       = false;
143         pthread_exit(NULL);
144 }
145
146 void start_servicedir_listener() {
147         log_debug("listen_closed_processes()\n");
148         init_servicedir_listener();
149         if (_listener_running == false) {
150                 _listener_thread                = 0;
151                 _listener_stop_requested        = false;
152                 _listener_running               = true;
153                 pthread_create(&_listener_thread,
154                                NULL,
155                                servicedir_listener_thread,
156                                (void *)NULL);
157         }
158 }
159
160 void stop_servicedir_listener() {
161         _listener_stop_requested        = true;
162         pthread_mutex_lock(&_listener_mutex);
163         if ((_inotify_handle > 0) && (_dir_handle)) {
164                 inotify_rm_watch(_inotify_handle, _dir_handle);
165                 close(_inotify_handle);
166                 _dir_handle     = -1;
167                 _inotify_handle = -1;
168         }
169         pthread_mutex_unlock(&_listener_mutex);
170         pthread_join(_listener_thread, NULL);
171         deinit_servicedir_listener();
172 }