2 #include <stdio.h> // for stdio, NULL
3 #include <stdlib.h> // for malloc, etc
4 #include <unistd.h> // for close
5 #include <time.h> // for time()
6 #include <sys/types.h> // for kill
7 #include <signal.h> // for kill signal
8 #include <string.h> // for bzero
9 #include <poll.h> // for poll()
11 #include "pnd_dbusnotify.h"
12 #include "pnd_logger.h"
15 * Not yet doing a real libdbus implementation.
16 * First cut is using dbus-monitor; I'll work on a real dbus listener soon.
21 pid_t child_pid; // pid for dbus-monitor
22 int fd [ 2 ]; // pipe fd pair
25 #define MONITOR "/usr/bin/dbus-monitor"
26 #define MONARG1 "--system"
27 #define MONARG2 "interface=org.freedesktop.Hal.Device"
28 #define MONGREP "volume.is_mounted"
30 pnd_dbusnotify_handle pnd_dbusnotify_init ( void ) {
34 // and I will brandish it for Zo Kath Ra
36 p = malloc ( sizeof(pnd_dbusnotify_t) );
39 return ( NULL ); // uhh..
42 bzero ( p, sizeof(pnd_dbusnotify_t) );
44 // can we make a pipe?
45 if ( pipe ( p -> fd ) == -1 ) {
50 // spawn child process
51 p -> child_pid = fork();
53 if ( p -> child_pid == -1 ) {
55 return ( NULL ); // borked
57 } else if ( p -> child_pid == 0 ) {
60 close ( p -> fd [ 0 ] ); // ditch stdin on child
61 dup2 ( p -> fd [ 1 ], 1 ); // assign write-end of pipe to stdout
62 close ( p -> fd [ 1 ] ); // we don't need this anymore anyway
63 execlp ( MONITOR, MONITOR, MONARG1, MONARG2, NULL );
70 close ( p -> fd [ 1 ] ); // ditch write end, we're a grepper
77 void pnd_dbusnotify_shutdown ( pnd_dbusnotify_handle h ) {
78 pnd_dbusnotify_t *p = (pnd_dbusnotify_t*) h;
81 close ( p -> fd [ 0 ] ); // kill reader end of pipe
83 // destroy child process
84 kill ( p -> child_pid, SIGKILL );
91 unsigned char pnd_dbusnotify_rediscover_p ( pnd_dbusnotify_handle h ) {
92 pnd_dbusnotify_t *p = (pnd_dbusnotify_t*) h;
94 struct pollfd fds [ 1 ];
96 fds [ 0 ].fd = p -> fd [ 0 ]; // read side of pipe
97 fds [ 0 ].events = POLLIN | POLLPRI /* | POLLRDHUP */;
98 fds [ 0 ].revents = 0;
100 r = poll ( fds, 1, 0 /* timeout*/ );
104 // should rebuild a new child process
107 } else if ( r == 0 ) {
108 // no input on the pipe
113 // something on the pipe, lets check it
115 if ( fds [ 0 ].revents & ( POLLERR|POLLHUP/*|POLLRDHUP*/ ) ) {
117 // should rebuild a new child process
121 // something useful on the pipe
125 readcount = read ( fds [ 0 ].fd, buf, 4000 );
127 if ( readcount < 0 ) {
132 // terminate the string
133 *( buf + readcount + 1 ) = '\0';
135 if ( strstr ( buf, MONGREP ) != NULL ) {