1 --- /dev/null 2003-09-15 15:40:47.000000000 +0200
2 +++ fam-2.6.10/src/DNotify.c++ 2004-02-04 11:13:04.000000000 +0100
4 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
5 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
7 +// This program is free software; you can redistribute it and/or modify it
8 +// under the terms of version 2 of the GNU General Public License as
9 +// published by the Free Software Foundation.
11 +// This program is distributed in the hope that it would be useful, but
12 +// WITHOUT ANY WARRANTY; without even the implied warranty of
13 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
14 +// license provided herein, whether implied or otherwise, is limited to
15 +// this program in accordance with the express provisions of the GNU
16 +// General Public License. Patent licenses, if any, provided herein do not
17 +// apply to combinations of this program with other product or programs, or
18 +// any other product whatsoever. This program is distributed without any
19 +// warranty that the program is delivered free of the rightful claim of any
20 +// third person by way of infringement or the like. See the GNU General
21 +// Public License for more details.
23 +// You should have received a copy of the GNU General Public License along
24 +// with this program; if not, write the Free Software Foundation, Inc., 59
25 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
34 +#include <sys/types.h>
35 +#include <sys/stat.h>
40 +#include "Interest.h"
42 +#include "Scheduler.h"
46 +int DNotify::pipe_write_fd = -2;
47 +int DNotify::pipe_read_fd = -2;
48 +volatile sig_atomic_t DNotify::queue_overflowed = 0;
49 +volatile sig_atomic_t DNotify::queue_changed = 0;
50 +int DNotify::change_queue[QUEUESIZE];
51 +volatile int DNotify::queue_head = 0; // Only modified by read handler
52 +volatile int DNotify::queue_tail = 0; // Only modified by signal handler
53 +DNotify::EventHandler DNotify::ehandler;
55 +DNotify::DirWatch *DNotify::dir_hash[DIR_HASHSIZE];
56 +DNotify::FileWatch *DNotify::file_hash[FILE_HASHSIZE];
58 +struct DNotify::FileWatch
60 + DirWatch **dir_watch;
64 + FileWatch *hash_link;
71 + void add_dir_watch (DirWatch *w);
72 + bool has_dir_watch (DirWatch *w);
76 +struct DNotify::DirWatch
78 + class FileWatchList {
87 + FileWatchList(void) {
91 + void prepend(FileWatch *watch);
92 + void remove(FileWatch *watch);
102 + DirWatch *hash_link;
103 + FileWatchList file_watches;
106 +struct DNotify::ChangeEventData
113 +DNotify::FileWatch::has_dir_watch (DirWatch *w)
117 + for (i = 0; i < n_dir_watches; i++) {
118 + if (dir_watch[i] == w)
126 +DNotify::FileWatch::add_dir_watch (DirWatch *w)
129 + dir_watch = (DirWatch **)realloc (dir_watch, n_dir_watches*sizeof(DirWatch *));
130 + dir_watch[n_dir_watches-1] = w;
134 +DNotify::DirWatch::FileWatchList::empty(void)
136 + return first == NULL;
140 +DNotify::DirWatch::FileWatchList::len(void)
157 +DNotify::DirWatch::FileWatchList::prepend(FileWatch *watch)
162 + node->watch = watch;
163 + node->next = first;
169 +DNotify::DirWatch::FileWatchList::remove(FileWatch *watch) {
175 + if (l->watch == watch) {
177 + prev->next = l->next;
190 +DNotify::DNotify(EventHandler h)
192 + assert(ehandler == NULL);
198 + if (pipe_read_fd >= 0) {
199 + // Tell the scheduler.
201 + (void) Scheduler::remove_read_handler(pipe_read_fd);
205 + if (close(pipe_read_fd) < 0)
206 + Log::perror("can't pipe read end");
208 + Log::debug("closed pipe read end");
210 + if (close(pipe_write_fd) < 0)
211 + Log::perror("can't pipe write end");
213 + Log::debug("closed pipe write end");
220 +DNotify::overflow_signal_handler(int sig, siginfo_t *si, void *data)
225 + char *str = "*************** overflow sigqueue ***********************\n";
226 + write (STDERR_FILENO, str, strlen(str));
229 + if (!queue_overflowed) {
230 + queue_overflowed = 1;
231 + // Trigger the read handler
232 + write(pipe_write_fd, &c, 1);
237 +DNotify::signal_handler(int sig, siginfo_t *si, void *data)
242 + if (queue_head <= queue_tail)
243 + left = (QUEUESIZE + queue_head) - queue_tail;
245 + left = queue_head - queue_tail;
247 + // Must leave at least one item unused to see difference
248 + // Betweeen empty and full
250 + queue_overflowed = 1;
252 + char *str = "*************** overflow famqueue ****************\n";
253 + write (STDERR_FILENO, str, strlen(str));
256 + change_queue[queue_tail] = si->si_fd;
257 + queue_tail = (queue_tail + 1) % QUEUESIZE;
260 + if (!queue_changed) {
262 + // Trigger the read handler
263 + write(pipe_write_fd, &c, 1);
268 +DNotify::is_active()
270 + if (pipe_read_fd == -2) {
274 + res = pipe (filedes);
276 + Log::debug("opened pipe");
277 + pipe_read_fd = filedes[0];
278 + pipe_write_fd = filedes[1];
280 + // Setup signal handler:
281 + struct sigaction act;
283 + act.sa_sigaction = signal_handler;
284 + sigemptyset(&act.sa_mask);
285 + act.sa_flags = SA_SIGINFO;
286 + sigaction(SIGRTMIN, &act, NULL);
288 + // When the RT queue overflows we get a SIGIO
289 + act.sa_sigaction = overflow_signal_handler;
290 + sigemptyset(&act.sa_mask);
291 + sigaction(SIGIO, &act, NULL);
293 + (void) Scheduler::install_read_handler(pipe_read_fd, read_handler, NULL);
296 + return pipe_read_fd >= 0;
300 +DNotify::lookup_dirwatch (int fd)
305 + p = dir_hashchain (fd);
319 +// This colud be made faster by using another hash table.
320 +// But it's not that bad, since it is only used by express/revoke
322 +DNotify::lookup_dirwatch (dev_t dir_dev, ino_t dir_ino)
327 + for (i=0;i<DIR_HASHSIZE;i++) {
331 + if (p->dir_dev == dir_dev && p->dir_ino == dir_ino)
341 +DNotify::FileWatch *
342 +DNotify::lookup_filewatch (dev_t dev, ino_t ino)
347 + p = file_hashchain (dev, ino);
352 + if (w->file_dev == dev && w->file_ino == ino)
361 +// Make sure w is not already in the hash table before calling
364 +DNotify::hash_dirwatch(DirWatch *w)
367 + p = dir_hashchain (w->fd);
372 +// Make sure w is not already in the hash table before calling
375 +DNotify::hash_filewatch(FileWatch *w)
378 + p = file_hashchain (w->file_dev, w->file_ino);
384 +DNotify::unhash_dirwatch(DirWatch *w)
388 + p = dir_hashchain (w->fd);
395 + p = &(*p)->hash_link;
397 + w->hash_link = NULL;
401 +DNotify::unhash_filewatch(FileWatch *w)
405 + p = file_hashchain (w->file_dev, w->file_ino);
412 + p = &(*p)->hash_link;
414 + w->hash_link = NULL;
418 +DNotify::watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino)
426 + if (lstat (notify_dir, &stat) == -1)
429 + dwatch = lookup_dirwatch(stat.st_dev, stat.st_ino);
431 + Log::debug ("New DirWatch for %s (%x %x)\n",
432 + notify_dir, (int)stat.st_dev, (int)stat.st_ino);
433 + dwatch = new DirWatch;
434 + dwatch->hash_link = NULL;
435 + dwatch->dir_dev = stat.st_dev;
436 + dwatch->dir_ino = stat.st_ino;
437 + dwatch->fd = open(notify_dir, O_RDONLY);
438 + fcntl (dwatch->fd, F_SETSIG, SIGRTMIN);
439 + fcntl (dwatch->fd, F_NOTIFY,
440 + (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB) | DN_MULTISHOT);
441 + hash_dirwatch (dwatch);
444 + fw = lookup_filewatch(file_dev, file_ino);
446 + if (!fw->has_dir_watch(dwatch)) {
447 + fw->add_dir_watch(dwatch);
448 + dwatch->file_watches.prepend(fw);
453 + // No old FileWatch, need to add one:
454 + Log::debug("New FileWatch for %x %x\n", (int)file_dev, (int)file_ino);
455 + fw = new FileWatch;
456 + fw->add_dir_watch(dwatch);
457 + dwatch->file_watches.prepend(fw);
458 + fw->file_dev = file_dev;
459 + fw->file_ino = file_ino;
460 + hash_filewatch(fw);
465 +dirname_dup (const char *name)
467 + char *copy = strdup(name);
468 + char *res = dirname(copy);
475 +DNotify::express(const char *name, struct stat *status)
484 + Log::debug("express() name: %s\n", name);
489 + if (::lstat (name, &stat) == -1)
495 + if ((stat.st_mode & S_IFMT) != S_IFDIR)
496 + notify_dir = dirname_dup (name);
498 + notify_dir = (char *)name;
500 + s = watch_dir (notify_dir, dev, ino);
501 + if (notify_dir != name)
506 + // Check for a race condition; if someone removed or changed the
507 + // file at the same time that we are expressing interest in it,
508 + // revoke the interest so we don't get notifications about changes
509 + // to a recycled inode that we don't otherwise care about.
512 + if (status == NULL) {
515 + if (::lstat(name, status) == -1) {
516 + Log::perror("stat on \"%s\" failed", name);
517 + revoke(name, stat.st_dev, stat.st_ino);
520 + if (status->st_dev != stat.st_dev
521 + || status->st_ino != stat.st_ino) {
522 + Log::error("File \"%s\" changed between express and stat",
524 + revoke(name, stat.st_dev, stat.st_ino);
528 + Log::debug("told dnotify to monitor \"%s\" = dev %d/%d, ino %d", name,
529 + major(status->st_dev), minor(status->st_dev),
535 +DNotify::revoke(const char *name, dev_t dev, ino_t ino)
541 + Log::debug("revoke() name: %s, dev: %x, ino: %x\n", name, dev, ino);
546 + // Lookup FileWatch by dev:ino, and its DirWatch.
547 + fwatch = lookup_filewatch (dev, ino);
548 + if (fwatch == NULL)
551 + // delete FileWatch, if last FileWatch: close fd, delete DirWatch
552 + Log::debug ("Destroying FileWatch for (%x %x)\n",
553 + (int)fwatch->file_dev, (int)fwatch->file_ino);
554 + for (i = 0; i < fwatch->n_dir_watches; i++) {
555 + dwatch = fwatch->dir_watch[i];
556 + dwatch->file_watches.remove (fwatch);
558 + if (dwatch->file_watches.empty()) {
559 + Log::debug ("Destroying DirWatch for (%x %x)\n",
560 + (int)dwatch->dir_dev, (int)dwatch->dir_ino);
562 + unhash_dirwatch(dwatch);
566 + unhash_filewatch(fwatch);
574 +DNotify::all_watches_changed(void)
579 + for (i=0; i<FILE_HASHSIZE; i++) {
582 + (*ehandler)(fw->file_dev, fw->file_ino, CHANGE);
584 + fw = fw->hash_link;
591 +DNotify::read_handler(int fd, void *)
593 + static char readbuf[5000];
596 + int snap_queue_tail;
599 + int rc = read(fd, readbuf, sizeof readbuf);
602 + Log::perror("pipe read");
603 + else if (queue_overflowed) {
604 + // There is a *slight* race condition here. Between reading
605 + // the queue_overflow flag and resetting it. But it doesn't
606 + // matter, since I'm gonna handle the overflow after reseting
608 + queue_overflowed = false;
610 + // We're soon gonna check all watches anyway, so
611 + // get rid of the current queue
612 + queue_head = queue_tail;
614 + all_watches_changed ();
616 + // Don't read events that happen later than
617 + // the initial read. (Otherwise skipping fd's
618 + // might miss some changes).
619 + snap_queue_tail = queue_tail;
621 + while (queue_head != snap_queue_tail) {
622 + fd = change_queue[queue_head];
623 + queue_head = (queue_head + 1) % QUEUESIZE;
625 + // Skip multiple changes to the same fd
626 + if (fd != last_fd) {
627 + dw = lookup_dirwatch (fd);
630 + ChangeEventData *data;
631 + DirWatch::FileWatchList::Node *n;
633 + Log::debug("dnotify said dev %d/%d, ino %ld changed",
634 + major(dw->dir_dev), minor(dw->dir_dev), dw->dir_ino);
636 + n_watches = dw->file_watches.len();
637 + data = new ChangeEventData[n_watches];
640 + for (n=dw->file_watches.first; n; n=n->next) {
641 + data[i].file_dev = n->watch->file_dev;
642 + data[i].file_ino = n->watch->file_ino;
645 + assert(i == n_watches);
647 + for (i = 0; i < n_watches; i++) {
648 + (*ehandler)(data[i].file_dev, data[i].file_ino, CHANGE);
659 --- /dev/null 2003-09-15 15:40:47.000000000 +0200
660 +++ fam-2.6.10/src/DNotify.h 2004-02-03 18:30:26.000000000 +0100
662 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
663 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
665 +// This program is free software; you can redistribute it and/or modify it
666 +// under the terms of version 2 of the GNU General Public License as
667 +// published by the Free Software Foundation.
669 +// This program is distributed in the hope that it would be useful, but
670 +// WITHOUT ANY WARRANTY; without even the implied warranty of
671 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
672 +// license provided herein, whether implied or otherwise, is limited to
673 +// this program in accordance with the express provisions of the GNU
674 +// General Public License. Patent licenses, if any, provided herein do not
675 +// apply to combinations of this program with other product or programs, or
676 +// any other product whatsoever. This program is distributed without any
677 +// warranty that the program is delivered free of the rightful claim of any
678 +// third person by way of infringement or the like. See the GNU General
679 +// Public License for more details.
681 +// You should have received a copy of the GNU General Public License along
682 +// with this program; if not, write the Free Software Foundation, Inc., 59
683 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
685 +#ifndef DNotify_included
686 +#define DNotify_included
689 +#include "Monitor.h"
692 +// DNotify is an object encapsulating the dnotify linux fcntl.
693 +// It "emulates" the IMon interface.
694 +// There can only be one instantiation of the DNotify object.
696 +// The user of this object uses express() and revoke() to
697 +// express/revoke interest in a file. There is also
698 +// a callback, the EventHandler. When an dnotify event comes in,
699 +// the EventHandler is called.
701 +// The user of the DNotify object is the Interest class.
703 +class DNotify : public Monitor {
705 + DNotify(EventHandler h);
708 + static bool is_active();
710 + virtual Status express(const char *name, struct stat *stat_return);
711 + virtual Status revoke(const char *name, dev_t dev, ino_t ino);
716 + struct ChangeEventData;
719 + enum { QUEUESIZE = 1024 };
720 + static int pipe_write_fd;
721 + static int pipe_read_fd;
722 + static int change_queue[QUEUESIZE];
723 + static volatile sig_atomic_t DNotify::queue_overflowed;
724 + static volatile sig_atomic_t DNotify::queue_changed;
725 + static volatile int queue_head; // Only modified by read handler
726 + static volatile int queue_tail; // Only modified by signal handler
727 + static EventHandler ehandler;
728 + static void overflow_signal_handler(int sig, siginfo_t *si, void *data);
729 + static void signal_handler(int sig, siginfo_t *si, void *data);
730 + static void read_handler(int fd, void *closure);
732 + enum { DIR_HASHSIZE = 367 };
733 + static DirWatch *dir_hash[DIR_HASHSIZE];
734 + enum { FILE_HASHSIZE = 823 };
735 + static FileWatch *file_hash[FILE_HASHSIZE];
737 + static DirWatch **dir_hashchain(int fd)
738 + { return &dir_hash[(unsigned) (fd) % DIR_HASHSIZE]; }
739 + static FileWatch **file_hashchain(dev_t d, ino_t i)
740 + { return &file_hash[(unsigned) (d+i) % FILE_HASHSIZE]; }
742 + static DirWatch *lookup_dirwatch (int fd);
743 + static DirWatch *lookup_dirwatch (dev_t dir_dev, ino_t dir_ino);
744 + static FileWatch *lookup_filewatch (dev_t file_dev, ino_t file_ino);
745 + static void hash_dirwatch(DirWatch *w);
746 + static void hash_filewatch(FileWatch *w);
747 + static void unhash_dirwatch(DirWatch *w);
748 + static void unhash_filewatch(FileWatch *w);
749 + static Status watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino);
751 + static void all_watches_changed(void);
753 + DNotify(const DNotify&); // Do not copy
754 + DNotify & operator = (const DNotify&); // or assign.
757 +#endif /* !IMon_included */
760 --- fam-2.6.10/src/IMon.h.dnotify 2003-04-15 06:21:34.000000000 +0200
761 +++ fam-2.6.10/src/IMon.h 2004-02-03 18:30:26.000000000 +0100
763 #define IMon_included
766 -#include <sys/stat.h>
767 -#include <sys/types.h>
769 -#include "Boolean.h"
770 +#include "Monitor.h"
776 // The user of the IMon object is the Interest class.
779 +class IMon : public Monitor {
783 - enum Status { OK = 0, BAD = -1 };
784 - enum Event { EXEC, EXIT, CHANGE };
786 - typedef void (*EventHandler)(dev_t, ino_t, int event);
788 IMon(EventHandler h);
791 static bool is_active();
793 - Status express(const char *name, struct stat *stat_return);
794 - Status revoke(const char *name, dev_t dev, ino_t ino);
795 + virtual Status express(const char *name, struct stat *stat_return);
796 + virtual Status revoke(const char *name, dev_t dev, ino_t ino);
803 --- fam-2.6.10/src/Interest.c++.dnotify 2003-04-15 06:21:34.000000000 +0200
804 +++ fam-2.6.10/src/Interest.c++ 2004-02-03 18:30:26.000000000 +0100
807 #include "FileSystem.h"
809 +#include "DNotify.h"
811 #include "Pollster.h"
814 Interest *Interest::hashtable[];
815 -IMon Interest::imon(imon_handler);
818 +static DNotify dnotify(Interest::monitor_handler);
819 +Monitor * Interest::monitor = &dnotify;
821 +static IMon imon(Interest::monitor_handler);
822 +Monitor * Interest::monitor = &imon;
825 bool Interest::xtab_verification = true;
827 Interest::Interest(const char *name, FileSystem *fs, in_addr host, ExportVerification ev)
830 mypath_exported_to_host(ev == NO_VERIFY_EXPORTED)
832 - memset(&old_stat, 0, sizeof(old_stat));
833 - IMon::Status s = IMon::BAD;
835 - s = imon.express(name, &old_stat);
837 + memset(&old_stat, 0, sizeof(old_stat));
839 + Monitor::Status s = Monitor::BAD;
840 + s = monitor->express(name, &old_stat);
841 + if (s != Monitor::OK)
842 { int rc = lstat(name, &old_stat);
844 { Log::info("can't lstat %s", name);
849 - if (exported_to_host()) fs->ll_monitor(this, s == IMon::OK);
850 + if (exported_to_host()) fs->ll_monitor(this, s == Monitor::OK);
853 Interest::~Interest()
855 pp = &p->hashlink; // move to next element
858 - (void) imon.revoke(name(), dev, ino);
859 + (void) monitor->revoke(name(), dev, ino);
866 IMon::Status s = IMon::BAD;
867 - s = imon.express(name(), NULL);
868 + s = monitor->express(name(), NULL);
872 @@ -249,23 +258,23 @@
876 -Interest::imon_handler(dev_t device, ino_t inumber, int event)
877 +Interest::monitor_handler(dev_t device, ino_t inumber, int event)
879 assert(device || inumber);
881 for (Interest *p = *hashchain(device, inumber), *next = p; p; p = next)
882 { next = p->hashlink;
883 if (p->ino == inumber && p->dev == device)
884 - { if (event == IMon::EXEC)
885 + { if (event == Monitor::EXEC)
886 { p->cur_exec_state = EXECUTING;
887 (void) p->report_exec_state();
889 - else if (event == IMon::EXIT)
890 + else if (event == Monitor::EXIT)
891 { p->cur_exec_state = NOT_EXECUTING;
892 (void) p->report_exec_state();
895 - { assert(event == IMon::CHANGE);
896 + { assert(event == Monitor::CHANGE);
900 --- fam-2.6.10/src/Interest.h.dnotify 2003-04-15 06:21:34.000000000 +0200
901 +++ fam-2.6.10/src/Interest.h 2004-02-03 18:30:26.000000000 +0100
910 // Interest -- abstract base class for filesystem entities of interest.
913 // Public Class Method
915 - static void imon_handler(dev_t, ino_t, int event);
916 + static void monitor_handler(dev_t, ino_t, int event);
918 static void enable_xtab_verification(bool enable);
925 + static Monitor *monitor;
926 static Interest *hashtable[HASHSIZE];
927 static bool xtab_verification;
929 --- fam-2.6.10/src/Makefile.am.dnotify 2003-04-15 06:21:26.000000000 +0200
930 +++ fam-2.6.10/src/Makefile.am 2004-02-03 18:30:26.000000000 +0100
936 +DNOTIFY_FILES = DNotify.c++
946 DirectoryScanner.c++ \
964 - @MONITOR_FUNCS@.c++
965 + @MONITOR_FUNCS@.c++ \
968 -EXTRA_famd_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++
969 +EXTRA_famd_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++ DNotify.c++
971 --- /dev/null 2003-09-15 15:40:47.000000000 +0200
972 +++ fam-2.6.10/src/Monitor.h 2004-02-03 18:30:26.000000000 +0100
974 +// Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
975 +// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
977 +// This program is free software; you can redistribute it and/or modify it
978 +// under the terms of version 2 of the GNU General Public License as
979 +// published by the Free Software Foundation.
981 +// This program is distributed in the hope that it would be useful, but
982 +// WITHOUT ANY WARRANTY; without even the implied warranty of
983 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
984 +// license provided herein, whether implied or otherwise, is limited to
985 +// this program in accordance with the express provisions of the GNU
986 +// General Public License. Patent licenses, if any, provided herein do not
987 +// apply to combinations of this program with other product or programs, or
988 +// any other product whatsoever. This program is distributed without any
989 +// warranty that the program is delivered free of the rightful claim of any
990 +// third person by way of infringement or the like. See the GNU General
991 +// Public License for more details.
993 +// You should have received a copy of the GNU General Public License along
994 +// with this program; if not, write the Free Software Foundation, Inc., 59
995 +// Temple Place - Suite 330, Boston MA 02111-1307, USA.
997 +#ifndef Monitor_included
998 +#define Monitor_included
1000 +#include "config.h"
1001 +#include <sys/stat.h>
1002 +#include <sys/types.h>
1006 +// Monitor is an abstract baseclass for differend file monitoring
1007 +// systems. The original system used was IMon, and the Montor API
1008 +// is heavily influenced by that.
1009 +// There can only be one instantiation of the Monitor object.
1011 +// The user of this object uses express() and revoke() to
1012 +// express/revoke interest in a file to imon. There is also
1013 +// a callback, the EventHandler. When an event comes in,
1014 +// the EventHandler is called.
1016 +// The main implementers of the Monitor class is IMon and DNotify
1021 + enum Status { OK = 0, BAD = -1 };
1022 + enum Event { EXEC, EXIT, CHANGE };
1024 + typedef void (*EventHandler)(dev_t, ino_t, int event);
1026 + virtual Status express(const char *name, struct stat *stat_return) = 0;
1027 + virtual Status revoke(const char *name, dev_t dev, ino_t ino) = 0;
1030 +#endif /* !Monitor_included */
1031 --- fam-2.6.10/include/BTree.h.dnotify 2003-04-15 06:21:19.000000000 +0200
1032 +++ fam-2.6.10/include/BTree.h 2004-02-03 18:30:26.000000000 +0100
1035 link[n] = that->link[that->n];
1037 - that->link[0] = NULL;
1038 + that->link[0] = 0;
1041 ///////////////////////////////////////////////////////////////////////////////
1044 template <class K, class V>
1045 BTree<K, V>::BTree()
1046 - : root(NULL), npairs(0)
1047 + : root(0), npairs(0)
1049 assert(!(fanout % 2));
1052 BTree<Key, Value>::Closure
1053 BTree<Key, Value>::insert(Node *p, const Key& key, const Value& value)
1055 - if (!p) return Closure(key, value, NULL);
1056 + if (!p) return Closure(key, value, 0);
1057 // If you're running Purify on a client linking with libfam, and it says
1058 // that line is causing a 3-byte UMR for BTree<int, bool>::insert() in
1059 // FAMNextEvent() ("Reading 8 bytes from 0x... on the stack (3 bytes at
1063 { Node *nr = root->link[0];
1064 - root->link[0] = NULL; // don't delete subtree
1065 + root->link[0] = 0; // don't delete subtree
1070 Node *cp = p->link[i];
1073 - Node *rp = i < p->n ? p->link[i + 1] : NULL;
1074 - Node *lp = i > 0 ? p->link[i - 1] : NULL;
1075 + Node *rp = i < p->n ? p->link[i + 1] : 0;
1076 + Node *lp = i > 0 ? p->link[i - 1] : 0;
1077 assert(!rp || rp->n >= fanout / 2);
1078 assert(!lp || lp->n >= fanout / 2);
1080 --- fam-2.6.10/configure.ac.dnotify 2003-04-15 08:05:00.000000000 +0200
1081 +++ fam-2.6.10/configure.ac 2004-02-03 18:30:26.000000000 +0100
1082 @@ -100,6 +100,24 @@
1084 AC_CHECK_HEADERS([fcntl.h limits.h linux/imon.h netinet/in.h rpc/rpc.h rpcsvc/mount.h stddef.h stdlib.h string.h syslog.h sys/imon.h sys/param.h sys/select.h sys/statvfs.h sys/syssgi.h sys/time.h sys/types.h sys/un.h unistd.h])
1087 +dnl Test for the linux dnotify fcntl
1089 +AC_MSG_CHECKING([for dnotify fcntl support])
1090 +fam_save_cppflags="$CPPFLAGS"
1091 +CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
1093 +#define _GNU_SOURCE
1095 +#include <unistd.h>
1098 + fcntl (fd, F_NOTIFY, (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB)|DN_MULTISHOT);
1099 +], have_dnotify=yes, have_dnotify=no)
1101 +CPPFLAGS="$pango_save_cppflags"
1102 +AC_MSG_RESULT($have_dnotify)
1104 if test "$have_sys_imon_h"; then
1105 MONITOR_FUNCS=IMonIRIX
1106 elif test "$have_linux_imon_h"; then
1107 @@ -122,9 +140,14 @@
1108 elif test "$have_linux_imon_h"; then
1109 MONITOR_FUNCS=IMonLinux
1111 + if test "$have_dnotify" = "yes"; then
1113 + AC_DEFINE([USE_DNOTIFY], [1], [Define if the system has the dnotify fcntl and it's gonna be used.])
1115 MONITOR_FUNCS=IMonNone
1117 AC_SUBST(MONITOR_FUNCS)
1118 +AM_CONDITIONAL(USE_DNOTIFY, $use_dnotify)
1120 # Checks for typedefs, structures, and compiler characteristics.