1 diff -urP orig/acconfig.h dnotify/acconfig.h
2 --- orig/acconfig.h Mon Oct 22 02:33:09 2001
3 +++ dnotify/acconfig.h Thu Nov 29 18:18:10 2001
5 /* Define if the system has imon and IMONIOC_ ioctl flags. */
8 +/* Define if the system has the dnotify fcntl and it's gonna be used. */
11 /* Define if the system has the struct revokdi and the IMONIOC_REVOKDI
12 ** ioctl flag. (IRIX 5.3 doesn't.)
14 diff -urP orig/configure.in dnotify/configure.in
15 --- orig/configure.in Mon Nov 5 00:31:30 2001
16 +++ dnotify/configure.in Thu Nov 29 18:18:10 2001
18 dnl AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h syslog.h unistd.h)
21 +dnl Test for the linux dnotify fcntl
23 +AC_MSG_CHECKING([for dnotify fcntl support])
24 +fam_save_cppflags="$CPPFLAGS"
25 +CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
32 + fcntl (fd, F_NOTIFY, (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB)|DN_MULTISHOT);
33 +], have_dnotify=yes, have_dnotify=no)
35 +CPPFLAGS="$pango_save_cppflags"
36 +AC_MSG_RESULT($have_dnotify)
39 dnl See if imon is available; if so, is it IRIX or Linux?
41 if test `uname` = 'IRIX' || test `uname` = 'IRIX64'; then
43 if test "$have_imon" != "yes"; then
45 AC_DEFINE(HAVE_IMON, 0)
46 + if test "$have_dnotify" = "yes"; then
47 + AC_DEFINE(USE_DNOTIFY)
52 +AM_CONDITIONAL(USE_DNOTIFY, $use_dnotify)
54 echo "Using imon support module $IMON_FUNCS"
57 AC_CHECK_HEADER(sys/statvfs.h, [AC_DEFINE(HAVE_STATVFS, 1) have_statvfs="yes"], [AC_DEFINE(HAVE_STATVFS, 0) have_statvfs="no"])
58 AC_CHECK_HEADER(sys/syssgi.h, AC_DEFINE(HAVE_SYSSGI, 1), AC_DEFINE(HAVE_SYSSGI, 0))
59 AC_CHECK_HEADER(sys/fs/nfs_clnt.h, AC_DEFINE(HAVE_SYS_FS_NFS_CLNT_H, 1), AC_DEFINE(HAVE_SYS_FS_NFS_CLNT_H, 0))
62 dnl fam is a good deal less interesting without imon.
64 -if test "$have_imon" != 'yes'; then
65 +if test "$have_imon" != 'yes' -a "$have_dnotify" != 'yes'; then
68 ******************************************************************
69 diff -urP orig/fam/DNotify.c++ dnotify/fam/DNotify.c++
70 --- orig/fam/DNotify.c++ Wed Dec 31 19:00:00 1969
71 +++ dnotify/fam/DNotify.c++ Thu Nov 29 18:18:10 2001
73 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
74 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
76 +// This program is free software; you can redistribute it and/or modify it
77 +// under the terms of version 2 of the GNU General Public License as
78 +// published by the Free Software Foundation.
80 +// This program is distributed in the hope that it would be useful, but
81 +// WITHOUT ANY WARRANTY; without even the implied warranty of
82 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
83 +// license provided herein, whether implied or otherwise, is limited to
84 +// this program in accordance with the express provisions of the GNU
85 +// General Public License. Patent licenses, if any, provided herein do not
86 +// apply to combinations of this program with other product or programs, or
87 +// any other product whatsoever. This program is distributed without any
88 +// warranty that the program is delivered free of the rightful claim of any
89 +// third person by way of infringement or the like. See the GNU General
90 +// Public License for more details.
92 +// You should have received a copy of the GNU General Public License along
93 +// with this program; if not, write the Free Software Foundation, Inc., 59
94 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
103 +#include <sys/types.h>
104 +#include <sys/stat.h>
107 +#include "DNotify.h"
109 +#include "Interest.h"
111 +#include "Scheduler.h"
115 +int DNotify::pipe_write_fd = -2;
116 +int DNotify::pipe_read_fd = -2;
117 +volatile sig_atomic_t DNotify::queue_overflowed = 0;
118 +volatile sig_atomic_t DNotify::queue_changed = 0;
119 +int DNotify::change_queue[QUEUESIZE];
120 +volatile int DNotify::queue_head = 0; // Only modified by read handler
121 +volatile int DNotify::queue_tail = 0; // Only modified by signal handler
122 +DNotify::EventHandler DNotify::ehandler;
124 +DNotify::DirWatch *DNotify::dir_hash[DIR_HASHSIZE];
125 +DNotify::FileWatch *DNotify::file_hash[FILE_HASHSIZE];
127 +struct DNotify::FileWatch
129 + DirWatch *dir_watch;
132 + FileWatch *next; // The DirWatch.watches list
133 + FileWatch *hash_link;
136 +struct DNotify::DirWatch
142 + DirWatch *hash_link;
143 + FileWatch *watches;
146 +DNotify::DNotify(EventHandler h)
148 + assert(ehandler == NULL);
154 + if (pipe_read_fd >= 0)
156 + // Tell the scheduler.
158 + (void) Scheduler::remove_read_handler(pipe_read_fd);
162 + if (close(pipe_read_fd) < 0)
163 + Log::perror("can't pipe read end");
165 + Log::debug("closed pipe read end");
167 + if (close(pipe_write_fd) < 0)
168 + Log::perror("can't pipe write end");
170 + Log::debug("closed pipe write end");
177 +DNotify::overflow_signal_handler(int sig, siginfo_t *si, void *data)
182 + char *str = "*************** overflow sigqueue ***********************\n";
183 + write (0, str, strlen(str));
186 + if (!queue_overflowed)
188 + queue_overflowed = 1;
189 + // Trigger the read handler
190 + write(pipe_write_fd, &c, 1);
195 +DNotify::signal_handler(int sig, siginfo_t *si, void *data)
200 + if (queue_head <= queue_tail)
201 + left = (QUEUESIZE + queue_head) - queue_tail;
203 + left = queue_head - queue_tail;
205 + // Must leave at least one item unused to see difference
206 + // Betweeen empty and full
209 + queue_overflowed = 1;
211 + char *str = "*************** overflow famqueue ****************\n";
212 + write (0, str, strlen(str));
217 + change_queue[queue_tail] = si->si_fd;
218 + queue_tail = (queue_tail + 1) % QUEUESIZE;
221 + if (!queue_changed)
224 + // Trigger the read handler
225 + write(pipe_write_fd, &c, 1);
230 +DNotify::is_active()
232 + if (pipe_read_fd == -2)
237 + res = pipe (filedes);
239 + { Log::debug("opened pipe");
240 + pipe_read_fd = filedes[0];
241 + pipe_write_fd = filedes[1];
243 + // Setup signal handler:
244 + struct sigaction act;
246 + act.sa_sigaction = signal_handler;
247 + sigemptyset(&act.sa_mask);
248 + act.sa_flags = SA_SIGINFO;
249 + sigaction(SIGRTMIN, &act, NULL);
251 + // When the RT queue overflows we get a SIGIO
252 + act.sa_sigaction = overflow_signal_handler;
253 + sigemptyset(&act.sa_mask);
254 + sigaction(SIGIO, &act, NULL);
256 + (void) Scheduler::install_read_handler(pipe_read_fd, read_handler, NULL);
259 + return pipe_read_fd >= 0;
263 +DNotify::lookup_dirwatch (int fd)
268 + p = dir_hashchain (fd);
283 +// This colud be made faster by using another hash table.
284 +// But it's not that bad, since it is only used by express/revoke
286 +DNotify::lookup_dirwatch (dev_t dir_dev, ino_t dir_ino)
291 + for (i=0;i<DIR_HASHSIZE;i++)
297 + if (p->dir_dev == dir_dev && p->dir_ino == dir_ino)
307 +DNotify::FileWatch *
308 +DNotify::lookup_filewatch (dev_t dev, ino_t ino)
313 + p = file_hashchain (dev, ino);
319 + if (w->file_dev == dev && w->file_ino == ino)
328 +// Make sure w is not already in the hash table before calling
331 +DNotify::hash_dirwatch(DirWatch *w)
334 + p = dir_hashchain (w->fd);
339 +// Make sure w is not already in the hash table before calling
342 +DNotify::hash_filewatch(FileWatch *w)
345 + p = file_hashchain (w->file_dev, w->file_ino);
351 +DNotify::unhash_dirwatch(DirWatch *w)
355 + p = dir_hashchain (w->fd);
364 + p = &(*p)->hash_link;
366 + w->hash_link = NULL;
370 +DNotify::unhash_filewatch(FileWatch *w)
374 + p = file_hashchain (w->file_dev, w->file_ino);
383 + p = &(*p)->hash_link;
385 + w->hash_link = NULL;
389 +DNotify::watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino)
398 + if (lstat (notify_dir, &stat) == -1)
401 + dwatch = lookup_dirwatch(stat.st_dev, stat.st_ino);
404 + Log::debug ("New DirWatch for %s (%x %x)\n",
405 + notify_dir, (int)stat.st_dev, (int)stat.st_ino);
406 + dwatch = new DirWatch;
407 + dwatch->watches = NULL;
408 + dwatch->hash_link = NULL;
409 + dwatch->dir_dev = stat.st_dev;
410 + dwatch->dir_ino = stat.st_ino;
412 + dwatch->fd = open(notify_dir, O_RDONLY);
413 + fcntl (dwatch->fd, F_SETSIG, SIGRTMIN);
414 + fcntl (dwatch->fd, F_NOTIFY,
415 + (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB) | DN_MULTISHOT);
416 + hash_dirwatch (dwatch);
419 + for (p=&dwatch->watches; *p; p=&(*p)->next)
422 + if (fw->file_dev == file_dev && fw->file_ino == file_ino)
426 + // No old FileWatch, need to add one:
427 + Log::debug("New FileWatch for %x %x\n", (int)file_dev, (int)file_ino);
428 + *p = new FileWatch;
431 + fw->file_dev = file_dev;
432 + fw->file_ino = file_ino;
433 + fw->dir_watch = dwatch;
434 + hash_filewatch(fw);
439 +dirname_dup (const char *name)
441 + char *copy = strdup(name);
442 + char *res = dirname(copy);
449 +DNotify::express(const char *name, struct stat *status)
458 + Log::debug("express() name: %s\n", name);
463 + if (::lstat (name, &stat) == -1)
469 + if ((stat.st_mode & S_IFMT) != S_IFDIR)
470 + notify_dir = dirname_dup (name);
472 + notify_dir = (char *)name;
474 + s = watch_dir (notify_dir, dev, ino);
475 + if (notify_dir != name)
480 + // Check for a race condition; if someone removed or changed the
481 + // file at the same time that we are expressing interest in it,
482 + // revoke the interest so we don't get notifications about changes
483 + // to a recycled inode that we don't otherwise care about.
486 + if (status == NULL) {
489 + if (::lstat(name, status) == -1) {
490 + Log::perror("stat on \"%s\" failed", name);
491 + revoke(name, stat.st_dev, stat.st_ino);
494 + if (status->st_dev != stat.st_dev
495 + || status->st_ino != stat.st_ino) {
496 + Log::error("File \"%s\" changed between express and stat",
498 + revoke(name, stat.st_dev, stat.st_ino);
502 + Log::debug("told dnotify to monitor \"%s\" = dev %d/%d, ino %d", name,
503 + major(status->st_dev), minor(status->st_dev),
509 +DNotify::revoke(const char *name, dev_t dev, ino_t ino)
514 + Log::debug("revoke() name: %s, dev: %x, ino: %x\n", name, dev, ino);
519 + // Lookup FileWatch by dev:ino, and its DirWatch.
520 + fwatch = lookup_filewatch (dev, ino);
521 + if (fwatch == NULL)
524 + dwatch = fwatch->dir_watch;
526 + // delete FileWatch, if last FileWatch: close fd, delete DirWatch
527 + Log::debug ("Destroying FileWatch for (%x %x)\n",
528 + (int)fwatch->file_dev, (int)fwatch->file_ino);
530 + for (p=&dwatch->watches; *p; p=&(*p)->next)
538 + unhash_filewatch(fwatch);
540 + if (dwatch->watches == NULL)
542 + Log::debug ("Destroying DirWatch for (%x %x)\n",
543 + (int)dwatch->dir_dev, (int)dwatch->dir_ino);
545 + unhash_dirwatch(dwatch);
554 +DNotify::all_watches_changed(void)
559 + for (i=0; i<FILE_HASHSIZE; i++)
564 + (*ehandler)(fw->file_dev, fw->file_ino, CHANGE);
566 + fw = fw->hash_link;
573 +DNotify::read_handler(int fd, void *)
575 + static char readbuf[5000];
578 + int snap_queue_tail;
581 + int rc = read(fd, readbuf, sizeof readbuf);
584 + Log::perror("pipe read");
585 + else if (queue_overflowed)
587 + // There is a *slight* race condition here. Between reading
588 + // the queue_overflow flag and resetting it. But it doesn't
589 + // matter, since I'm gonna handle the overflow after reseting
591 + queue_overflowed = false;
593 + // We're soon gonna check all watches anyway, so
594 + // get rid of the current queue
595 + queue_head = queue_tail;
597 + all_watches_changed ();
601 + // Don't read events that happen later than
602 + // the initial read. (Otherwise skipping fd's
603 + // might miss some changes).
604 + snap_queue_tail = queue_tail;
606 + while (queue_head != snap_queue_tail)
608 + fd = change_queue[queue_head];
609 + queue_head = (queue_head + 1) % QUEUESIZE;
611 + // Skip multiple changes to the same fd
614 + dw = lookup_dirwatch (fd);
617 + Log::debug("dnotify said dev %d/%d, ino %ld changed",
618 + major(dw->dir_dev), minor(dw->dir_dev), dw->dir_ino);
619 + for (fw=dw->watches; fw; fw=fw->next)
621 + (*ehandler)(fw->file_dev, fw->file_ino, CHANGE);
630 diff -urP orig/fam/DNotify.h dnotify/fam/DNotify.h
631 --- orig/fam/DNotify.h Wed Dec 31 19:00:00 1969
632 +++ dnotify/fam/DNotify.h Thu Nov 29 18:18:10 2001
634 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
635 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
637 +// This program is free software; you can redistribute it and/or modify it
638 +// under the terms of version 2 of the GNU General Public License as
639 +// published by the Free Software Foundation.
641 +// This program is distributed in the hope that it would be useful, but
642 +// WITHOUT ANY WARRANTY; without even the implied warranty of
643 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
644 +// license provided herein, whether implied or otherwise, is limited to
645 +// this program in accordance with the express provisions of the GNU
646 +// General Public License. Patent licenses, if any, provided herein do not
647 +// apply to combinations of this program with other product or programs, or
648 +// any other product whatsoever. This program is distributed without any
649 +// warranty that the program is delivered free of the rightful claim of any
650 +// third person by way of infringement or the like. See the GNU General
651 +// Public License for more details.
653 +// You should have received a copy of the GNU General Public License along
654 +// with this program; if not, write the Free Software Foundation, Inc., 59
655 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
657 +#ifndef DNotify_included
658 +#define DNotify_included
661 +#include "Monitor.h"
664 +// DNotify is an object encapsulating the dnotify linux fcntl.
665 +// It "emulates" the IMon interface.
666 +// There can only be one instantiation of the DNotify object.
668 +// The user of this object uses express() and revoke() to
669 +// express/revoke interest in a file. There is also
670 +// a callback, the EventHandler. When an dnotify event comes in,
671 +// the EventHandler is called.
673 +// The user of the DNotify object is the Interest class.
675 +class DNotify : public Monitor {
677 + DNotify(EventHandler h);
680 + static bool is_active();
682 + virtual Status express(const char *name, struct stat *stat_return);
683 + virtual Status revoke(const char *name, dev_t dev, ino_t ino);
690 + enum { QUEUESIZE = 1024 };
691 + static int pipe_write_fd;
692 + static int pipe_read_fd;
693 + static int change_queue[QUEUESIZE];
694 + static volatile sig_atomic_t DNotify::queue_overflowed;
695 + static volatile sig_atomic_t DNotify::queue_changed;
696 + static volatile int queue_head; // Only modified by read handler
697 + static volatile int queue_tail; // Only modified by signal handler
698 + static EventHandler ehandler;
699 + static void overflow_signal_handler(int sig, siginfo_t *si, void *data);
700 + static void signal_handler(int sig, siginfo_t *si, void *data);
701 + static void read_handler(int fd, void *closure);
703 + enum { DIR_HASHSIZE = 257 };
704 + static DirWatch *dir_hash[DIR_HASHSIZE];
705 + enum { FILE_HASHSIZE = 257 };
706 + static FileWatch *file_hash[FILE_HASHSIZE];
708 + static DirWatch **dir_hashchain(int fd)
709 + { return &dir_hash[(unsigned) (fd) % DIR_HASHSIZE]; }
710 + static FileWatch **file_hashchain(dev_t d, ino_t i)
711 + { return &file_hash[(unsigned) (d+i) % FILE_HASHSIZE]; }
713 + static DirWatch *lookup_dirwatch (int fd);
714 + static DirWatch *lookup_dirwatch (dev_t dir_dev, ino_t dir_ino);
715 + static FileWatch *lookup_filewatch (dev_t file_dev, ino_t file_ino);
716 + static void hash_dirwatch(DirWatch *w);
717 + static void hash_filewatch(FileWatch *w);
718 + static void unhash_dirwatch(DirWatch *w);
719 + static void unhash_filewatch(FileWatch *w);
720 + static Status watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino);
722 + static void all_watches_changed(void);
724 + DNotify(const DNotify&); // Do not copy
725 + DNotify & operator = (const DNotify&); // or assign.
728 +#endif /* !IMon_included */
731 diff -urP orig/fam/IMon.h dnotify/fam/IMon.h
732 --- orig/fam/IMon.h Mon Oct 22 02:33:10 2001
733 +++ dnotify/fam/IMon.h Thu Nov 29 18:18:10 2001
735 #define IMon_included
738 -#include <sys/stat.h>
739 -#include <sys/types.h>
741 -#include "Boolean.h"
742 +#include "Monitor.h"
748 // The user of the IMon object is the Interest class.
751 +class IMon : public Monitor {
755 - enum Status { OK = 0, BAD = -1 };
756 - enum Event { EXEC, EXIT, CHANGE };
758 - typedef void (*EventHandler)(dev_t, ino_t, int event);
760 IMon(EventHandler h);
763 static bool is_active();
765 - Status express(const char *name, struct stat *stat_return);
766 - Status revoke(const char *name, dev_t dev, ino_t ino);
767 + virtual Status express(const char *name, struct stat *stat_return);
768 + virtual Status revoke(const char *name, dev_t dev, ino_t ino);
775 diff -urP orig/fam/Interest.c++ dnotify/fam/Interest.c++
776 --- orig/fam/Interest.c++ Mon Oct 22 02:33:10 2001
777 +++ dnotify/fam/Interest.c++ Thu Nov 29 18:19:59 2001
780 #include "FileSystem.h"
782 +#include "DNotify.h"
784 #include "Pollster.h"
787 Interest *Interest::hashtable[];
788 -IMon Interest::imon(imon_handler);
791 +static DNotify dnotify(Interest::monitor_handler);
792 +Monitor * Interest::monitor = &dnotify;
794 +static IMon imon(Interest::monitor_handler);
795 +Monitor * Interest::monitor = &imon;
798 bool Interest::xtab_verification = true;
800 Interest::Interest(const char *name, FileSystem *fs, in_addr host, ExportVerification ev)
803 mypath_exported_to_host(ev == NO_VERIFY_EXPORTED)
805 - memset(&old_stat, 0, sizeof(old_stat));
806 - IMon::Status s = IMon::BAD;
808 - s = imon.express(name, &old_stat);
810 + memset(&old_stat, 0, sizeof(old_stat));
812 + Monitor::Status s = Monitor::BAD;
813 + s = monitor->express(name, &old_stat);
814 + if (s != Monitor::OK)
815 { int rc = lstat(name, &old_stat);
817 { Log::info("can't lstat %s", name);
822 - if (exported_to_host()) fs->ll_monitor(this, s == IMon::OK);
823 + if (exported_to_host()) fs->ll_monitor(this, s == Monitor::OK);
826 Interest::~Interest()
828 pp = &p->hashlink; // move to next element
831 - (void) imon.revoke(name(), dev, ino);
832 + (void) monitor->revoke(name(), dev, ino);
839 IMon::Status s = IMon::BAD;
840 - s = imon.express(name(), NULL);
841 + s = monitor->express(name(), NULL);
845 @@ -242,23 +251,23 @@
849 -Interest::imon_handler(dev_t device, ino_t inumber, int event)
850 +Interest::monitor_handler(dev_t device, ino_t inumber, int event)
852 assert(device || inumber);
854 for (Interest *p = *hashchain(device, inumber), *next = p; p; p = next)
855 { next = p->hashlink;
856 if (p->ino == inumber && p->dev == device)
857 - { if (event == IMon::EXEC)
858 + { if (event == Monitor::EXEC)
859 { p->cur_exec_state = EXECUTING;
860 (void) p->report_exec_state();
862 - else if (event == IMon::EXIT)
863 + else if (event == Monitor::EXIT)
864 { p->cur_exec_state = NOT_EXECUTING;
865 (void) p->report_exec_state();
868 - { assert(event == IMon::CHANGE);
869 + { assert(event == Monitor::CHANGE);
873 diff -urP orig/fam/Interest.h dnotify/fam/Interest.h
874 --- orig/fam/Interest.h Mon Oct 22 02:33:10 2001
875 +++ dnotify/fam/Interest.h Thu Nov 29 18:18:10 2001
884 // Interest -- abstract base class for filesystem entities of interest.
887 // Public Class Method
889 - static void imon_handler(dev_t, ino_t, int event);
890 + static void monitor_handler(dev_t, ino_t, int event);
892 static void enable_xtab_verification(bool enable);
899 + static Monitor *monitor;
900 static Interest *hashtable[HASHSIZE];
901 static bool xtab_verification;
903 diff -urP orig/fam/Makefile.am dnotify/fam/Makefile.am
904 --- orig/fam/Makefile.am Mon Oct 22 02:33:10 2001
905 +++ dnotify/fam/Makefile.am Thu Nov 29 18:18:10 2001
908 sysconf_DATA = fam.conf
911 +DNOTIFY_FILES = DNotify.c++
921 DirectoryScanner.c++ \
943 -EXTRA_fam_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++
944 +EXTRA_fam_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++ DNotify.c++
946 fam_LDADD = -lrpcsvc $(top_srcdir)/support/libsupport.a
948 diff -urP orig/fam/Monitor.h dnotify/fam/Monitor.h
949 --- orig/fam/Monitor.h Wed Dec 31 19:00:00 1969
950 +++ dnotify/fam/Monitor.h Thu Nov 29 18:18:10 2001
952 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
953 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
955 +// This program is free software; you can redistribute it and/or modify it
956 +// under the terms of version 2 of the GNU General Public License as
957 +// published by the Free Software Foundation.
959 +// This program is distributed in the hope that it would be useful, but
960 +// WITHOUT ANY WARRANTY; without even the implied warranty of
961 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
962 +// license provided herein, whether implied or otherwise, is limited to
963 +// this program in accordance with the express provisions of the GNU
964 +// General Public License. Patent licenses, if any, provided herein do not
965 +// apply to combinations of this program with other product or programs, or
966 +// any other product whatsoever. This program is distributed without any
967 +// warranty that the program is delivered free of the rightful claim of any
968 +// third person by way of infringement or the like. See the GNU General
969 +// Public License for more details.
971 +// You should have received a copy of the GNU General Public License along
972 +// with this program; if not, write the Free Software Foundation, Inc., 59
973 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
975 +#ifndef Monitor_included
976 +#define Monitor_included
979 +#include <sys/stat.h>
980 +#include <sys/types.h>
984 +// Monitor is an abstract baseclass for differend file monitoring
985 +// systems. The original system used was IMon, and the Montor API
986 +// is heavily influenced by that.
987 +// There can only be one instantiation of the Monitor object.
989 +// The user of this object uses express() and revoke() to
990 +// express/revoke interest in a file to imon. There is also
991 +// a callback, the EventHandler. When an event comes in,
992 +// the EventHandler is called.
994 +// The main implementers of the Monitor class is IMon and DNotify
999 + enum Status { OK = 0, BAD = -1 };
1000 + enum Event { EXEC, EXIT, CHANGE };
1002 + typedef void (*EventHandler)(dev_t, ino_t, int event);
1004 + virtual Status express(const char *name, struct stat *stat_return) = 0;
1005 + virtual Status revoke(const char *name, dev_t dev, ino_t ino) = 0;
1008 +#endif /* !Monitor_included */
1009 diff -urP orig/include/BTree.h dnotify/include/BTree.h
1010 --- orig/include/BTree.h Wed Nov 7 23:09:50 2001
1011 +++ dnotify/include/BTree.h Thu Nov 29 18:18:10 2001
1014 link[n] = that->link[that->n];
1016 - that->link[0] = NULL;
1017 + that->link[0] = 0;
1020 ///////////////////////////////////////////////////////////////////////////////
1023 template <class K, class V>
1024 BTree<K, V>::BTree()
1025 - : root(NULL), npairs(0)
1026 + : root(0), npairs(0)
1028 assert(!(fanout % 2));
1031 BTree<Key, Value>::Closure
1032 BTree<Key, Value>::insert(Node *p, const Key& key, const Value& value)
1034 - if (!p) return Closure(key, value, NULL);
1035 + if (!p) return Closure(key, value, 0);
1036 // If you're running Purify on a client linking with libfam, and it says
1037 // that line is causing a 3-byte UMR for BTree<int, bool>::insert() in
1038 // FAMNextEvent() ("Reading 8 bytes from 0x... on the stack (3 bytes at
1042 { Node *nr = root->link[0];
1043 - root->link[0] = NULL; // don't delete subtree
1044 + root->link[0] = 0; // don't delete subtree
1049 Node *cp = p->link[i];
1052 - Node *rp = i < p->n ? p->link[i + 1] : NULL;
1053 - Node *lp = i > 0 ? p->link[i - 1] : NULL;
1054 + Node *rp = i < p->n ? p->link[i + 1] : 0;
1055 + Node *lp = i > 0 ? p->link[i - 1] : 0;
1056 assert(!rp || rp->n >= fanout / 2);
1057 assert(!lp || lp->n >= fanout / 2);