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