Initial commit of libpnd 0.0.5 so we cna restart with GIT
[pandora-libraries.git] / lib / pnd_notify.c
1
2 #include <sys/inotify.h>    // for INOTIFY duh
3 #include <stdio.h>          // for stdio, NULL
4 #include <stdlib.h>         // for malloc, etc
5 #include <unistd.h>         // for close
6
7 #include "pnd_notify.h"
8
9 typedef struct {
10   int fd;              // notify API file descriptor
11 } pnd_notify_t;
12
13 static void pnd_notify_hookup ( int fd );
14
15 pnd_notify_handle pnd_notify_init ( void ) {
16   int fd;
17   pnd_notify_t *p;
18
19   fd = inotify_init();
20
21   if ( fd < 0 ) {
22     return ( NULL );
23   }
24
25   p = malloc ( sizeof(pnd_notify_t) );
26
27   if ( ! p ) {
28     close ( fd );
29     return ( NULL ); // uhh..
30   }
31
32   p -> fd = fd;
33
34   // setup some default watches
35   pnd_notify_hookup ( fd );
36
37   return ( p );
38 }
39
40 void pnd_notify_shutdown ( pnd_notify_handle h ) {
41   pnd_notify_t *p = (pnd_notify_t*) h;
42
43   close ( p -> fd );
44
45   return;
46 }
47
48 static void pnd_notify_hookup ( int fd ) {
49
50   inotify_add_watch ( fd, "./testdata", IN_CREATE | IN_DELETE | IN_UNMOUNT );
51
52   return;
53 }
54
55 unsigned char pnd_notify_rediscover_p ( pnd_notify_handle h ) {
56   pnd_notify_t *p = (pnd_notify_t*) h;
57
58   struct timeval t;
59   fd_set rfds;
60   int retcode;
61
62   // don't block for long..
63   t.tv_sec = 1;
64   t.tv_usec = 0; //5000;
65
66   // only for our useful fd
67   FD_ZERO ( &rfds );
68   FD_SET ( (p->fd), &rfds );
69
70   // wait and test
71   retcode = select ( (p->fd) + 1, &rfds, NULL, NULL, &t );
72
73   if ( retcode < 0 ) {
74     return ( 0 ); // hmm.. need a better error code handler
75   } else if ( retcode == 0 ) {
76     return ( 0 ); // timeout
77   }
78
79   if ( ! FD_ISSET ( (p->fd), &rfds ) ) {
80     return ( 0 );
81   }
82
83   // by this point, something must have happened on our watch
84 #define BINBUFLEN ( 100 * ( sizeof(struct inotify_event) + 30 ) ) /* approx 100 events in a shot? */
85   unsigned char binbuf [ BINBUFLEN ];
86   int actuallen;
87
88   actuallen = read ( (p->fd), binbuf, BINBUFLEN );
89
90   if ( actuallen < 0 ) {
91     return ( 0 ); // error
92   } else if ( actuallen == 0 ) {
93     return ( 0 ); // nothing, or overflow, or .. whatever.
94   }
95
96   unsigned int i;
97   struct inotify_event *e;
98
99   while ( i < actuallen ) {
100     e = (struct inotify_event *) &binbuf [ i ];
101
102     /* do it!
103      */
104
105     if ( e -> len ) {
106       printf ( "Got event against '%s'\n", e -> name );
107     }
108
109     /* do it!
110      */
111
112     // next
113     i += ( sizeof(struct inotify_event) + e -> len );
114   } // while
115
116   return ( 1 );
117 }