]> git.pld-linux.org Git - packages/fam.git/blob - fam-dnotify.patch
- updated to 2.6.10
[packages/fam.git] / fam-dnotify.patch
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
4 @@ -17,6 +17,9 @@
5  /*  Define if the system has imon and IMONIOC_ ioctl flags.  */
6  #undef HAVE_IMON
7  
8 +/*  Define if the system has the dnotify fcntl and it's gonna be used.  */
9 +#undef USE_DNOTIFY
10 +
11  /*  Define if the system has the struct revokdi and the IMONIOC_REVOKDI
12  **  ioctl flag.  (IRIX 5.3 doesn't.)
13  */
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
17 @@ -96,6 +99,24 @@
18  dnl AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h syslog.h unistd.h)
19  
20  dnl
21 +dnl  Test for the linux dnotify fcntl
22 +dnl
23 +AC_MSG_CHECKING([for dnotify fcntl support])
24 +fam_save_cppflags="$CPPFLAGS"
25 +CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
26 +AC_TRY_COMPILE([
27 +#define _GNU_SOURCE  
28 +#include <fcntl.h>
29 +#include <unistd.h>
30 +],
31 +[ int fd = 1;
32 +  fcntl (fd, F_NOTIFY, (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB)|DN_MULTISHOT);
33 +], have_dnotify=yes, have_dnotify=no)
34 +use_dnotify=false
35 +CPPFLAGS="$pango_save_cppflags"
36 +AC_MSG_RESULT($have_dnotify)
37 +
38 +dnl
39  dnl  See if imon is available; if so, is it IRIX or Linux?
40  dnl
41  if test `uname` = 'IRIX' || test `uname` = 'IRIX64'; then
42 @@ -118,11 +139,17 @@
43  if test "$have_imon" != "yes"; then
44      have_imon=no
45      AC_DEFINE(HAVE_IMON, 0)
46 +    if test "$have_dnotify" = "yes"; then
47 +        AC_DEFINE(USE_DNOTIFY)
48 +       use_dnotify=true
49 +    fi
50      IMON_FUNCS=IMonNone
51  fi
52 +AM_CONDITIONAL(USE_DNOTIFY, $use_dnotify)
53  AC_SUBST(IMON_FUNCS)
54  echo "Using imon support module $IMON_FUNCS"
55  
56 +
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))
60 @@ -572,7 +599,7 @@
61  dnl 
62  dnl  fam is a good deal less interesting without imon.
63  dnl 
64 -if test "$have_imon" != 'yes'; then
65 +if test "$have_imon" != 'yes' -a "$have_dnotify" != 'yes'; then
66      cat << EOF
67  
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
72 @@ -0,0 +1,557 @@
73 +//  Copyright (C) 2001 Red Hat, Inc.  All Rights Reserved.
74 +//  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.
75 +//  
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.
79 +//
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.
91 +//
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.
95 +
96 +#define _GNU_SOURCE  
97 +#include <fcntl.h>
98 +
99 +#include <string.h>
100 +#include <signal.h>
101 +#include <stdio.h>
102 +#include <unistd.h>
103 +#include <sys/types.h>
104 +#include <sys/stat.h>
105 +#include <libgen.h>
106 +
107 +#include "DNotify.h"
108 +
109 +#include "Interest.h"
110 +#include "Log.h"
111 +#include "Scheduler.h"
112 +#include "alloc.h"
113 +
114 +
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;
123 +
124 +DNotify::DirWatch *DNotify::dir_hash[DIR_HASHSIZE];
125 +DNotify::FileWatch *DNotify::file_hash[FILE_HASHSIZE];
126 +
127 +struct DNotify::FileWatch
128 +{
129 +    DirWatch *dir_watch;
130 +    dev_t file_dev;
131 +    ino_t file_ino;
132 +    FileWatch *next; // The DirWatch.watches list
133 +    FileWatch *hash_link;
134 +};
135 +
136 +struct DNotify::DirWatch
137 +{
138 +    int fd;
139 +    dev_t dir_dev;
140 +    ino_t dir_ino;
141 +    
142 +    DirWatch *hash_link;
143 +    FileWatch *watches;
144 +};
145 +
146 +DNotify::DNotify(EventHandler h)
147 +{
148 +    assert(ehandler == NULL);
149 +    ehandler = h;
150 +}
151 +
152 +DNotify::~DNotify()
153 +{
154 +    if (pipe_read_fd >= 0)
155 +    {
156 +       //  Tell the scheduler.
157 +
158 +       (void) Scheduler::remove_read_handler(pipe_read_fd);
159 +
160 +       //  Close the pipe.
161 +
162 +       if (close(pipe_read_fd) < 0)
163 +           Log::perror("can't pipe read end");
164 +       else
165 +           Log::debug("closed pipe read end");
166 +       
167 +       if (close(pipe_write_fd) < 0)
168 +           Log::perror("can't pipe write end");
169 +       else
170 +           Log::debug("closed pipe write end");
171 +       pipe_read_fd = -1;
172 +    }
173 +    ehandler = NULL;
174 +}
175 +
176 +void
177 +DNotify::overflow_signal_handler(int sig, siginfo_t *si, void *data)
178 +{
179 +  char c = 'x';
180 +  
181 +  {
182 +    char *str = "*************** overflow sigqueue ***********************\n";
183 +    write (0, str, strlen(str));
184 +  }
185 +
186 +  if (!queue_overflowed)
187 +  {
188 +      queue_overflowed = 1;
189 +      // Trigger the read handler
190 +      write(pipe_write_fd, &c, 1);
191 +  }
192 +}
193 +
194 +void
195 +DNotify::signal_handler(int sig, siginfo_t *si, void *data)
196 +{
197 +  int left;
198 +  char c = 'x';
199 +
200 +  if (queue_head <= queue_tail)
201 +    left = (QUEUESIZE + queue_head) - queue_tail;
202 +  else 
203 +    left = queue_head - queue_tail;
204 +  
205 +  // Must leave at least one item unused to see difference
206 +  // Betweeen empty and full
207 +  if (left <= 1)
208 +  {
209 +      queue_overflowed = 1;
210 +      {
211 +       char *str = "*************** overflow famqueue ****************\n";
212 +       write (0, str, strlen(str));
213 +      }
214 +  }
215 +  else
216 +  {
217 +      change_queue[queue_tail] = si->si_fd;
218 +      queue_tail = (queue_tail + 1) % QUEUESIZE;
219 +  }
220 +  
221 +  if (!queue_changed)
222 +  {
223 +      queue_changed = 1;
224 +      // Trigger the read handler
225 +      write(pipe_write_fd, &c, 1);
226 +  }
227 +}
228 +
229 +bool
230 +DNotify::is_active()
231 +{
232 +    if (pipe_read_fd == -2)
233 +    {
234 +        int filedes[2];
235 +       int res;
236 +       
237 +       res = pipe (filedes);
238 +       if (res >= 0)
239 +       {   Log::debug("opened pipe");
240 +           pipe_read_fd = filedes[0];
241 +           pipe_write_fd = filedes[1];
242 +
243 +           // Setup signal handler:
244 +           struct sigaction act;
245 +           
246 +           act.sa_sigaction = signal_handler;
247 +           sigemptyset(&act.sa_mask);
248 +           act.sa_flags = SA_SIGINFO;
249 +           sigaction(SIGRTMIN, &act, NULL);
250 +
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);
255 +
256 +           (void) Scheduler::install_read_handler(pipe_read_fd, read_handler, NULL);
257 +       }
258 +    }
259 +    return pipe_read_fd >= 0;
260 +}
261 +
262 +DNotify::DirWatch *
263 +DNotify::lookup_dirwatch (int fd)
264 +{
265 +  DirWatch **p;
266 +  DirWatch *w;
267 +
268 +  p = dir_hashchain (fd);
269 +
270 +  while (*p)
271 +    {
272 +      w = *p;
273 +
274 +      if (w->fd == fd)
275 +       return w;
276 +
277 +      p = &w->hash_link;
278 +    }
279 +  
280 +  return *p;
281 +}
282 +
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
285 +DNotify::DirWatch *
286 +DNotify::lookup_dirwatch (dev_t dir_dev, ino_t dir_ino)
287 +{
288 +  DirWatch *p;
289 +  int i;
290 +
291 +  for (i=0;i<DIR_HASHSIZE;i++)
292 +    {
293 +      p = dir_hash[i];
294 +      
295 +      while (p)
296 +       {
297 +         if (p->dir_dev == dir_dev && p->dir_ino == dir_ino)
298 +           return p;
299 +         
300 +         p = p->hash_link;
301 +       }
302 +    }
303 +  
304 +  return NULL;
305 +}
306 +
307 +DNotify::FileWatch *
308 +DNotify::lookup_filewatch (dev_t dev, ino_t ino)
309 +{
310 +  FileWatch **p;
311 +  FileWatch *w;
312 +
313 +  p = file_hashchain (dev, ino);
314 +
315 +  while (*p)
316 +    {
317 +      w = *p;
318 +
319 +      if (w->file_dev == dev && w->file_ino == ino)
320 +       return w;
321 +
322 +      p = &w->hash_link;
323 +    }
324 +  
325 +  return *p;
326 +}
327 +
328 +// Make sure w is not already in the hash table before calling
329 +// this function.
330 +void
331 +DNotify::hash_dirwatch(DirWatch *w)
332 +{
333 +  DirWatch **p;
334 +  p = dir_hashchain (w->fd);
335 +  w->hash_link = *p;
336 +  *p = w;
337 +}
338 +
339 +// Make sure w is not already in the hash table before calling
340 +// this function.
341 +void
342 +DNotify::hash_filewatch(FileWatch *w)
343 +{
344 +  FileWatch **p;
345 +  p = file_hashchain (w->file_dev, w->file_ino);
346 +  w->hash_link = *p;
347 +  *p = w;
348 +}
349 +
350 +void
351 +DNotify::unhash_dirwatch(DirWatch *w)
352 +{
353 +  DirWatch **p;
354 +  
355 +  p = dir_hashchain (w->fd);
356 +  
357 +  while (*p)
358 +    {
359 +      if (*p == w)
360 +       {
361 +         *p = w->hash_link;
362 +         break;
363 +       }
364 +      p = &(*p)->hash_link;
365 +    }
366 +  w->hash_link = NULL;
367 +}
368 +
369 +void
370 +DNotify::unhash_filewatch(FileWatch *w)
371 +{
372 +  FileWatch **p;
373 +  
374 +  p = file_hashchain (w->file_dev, w->file_ino);
375 +  
376 +  while (*p)
377 +    {
378 +      if (*p == w)
379 +       {
380 +         *p = w->hash_link;
381 +         break;
382 +       }
383 +      p = &(*p)->hash_link;
384 +    }
385 +  w->hash_link = NULL;
386 +}
387 +
388 +DNotify::Status
389 +DNotify::watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino)
390 +{
391 +  struct stat stat;
392 +  dev_t dir_dev;
393 +  ino_t dir_ino;
394 +  DirWatch *dwatch;
395 +  FileWatch **p;
396 +  FileWatch *fw;
397 +    
398 +  if (lstat (notify_dir, &stat) == -1)
399 +      return BAD;
400 +  
401 +  dwatch = lookup_dirwatch(stat.st_dev, stat.st_ino);
402 +  if (!dwatch)
403 +    {
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;
411 +      
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);
417 +    }
418 +
419 +  for (p=&dwatch->watches; *p; p=&(*p)->next)
420 +    {
421 +      fw = *p;
422 +      if (fw->file_dev == file_dev && fw->file_ino == file_ino)
423 +       return OK;
424 +    }
425 +  
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;
429 +  fw = *p;
430 +  fw->next = NULL;
431 +  fw->file_dev = file_dev;
432 +  fw->file_ino = file_ino;
433 +  fw->dir_watch = dwatch;
434 +  hash_filewatch(fw);
435 +  return OK;
436 +}
437 +
438 +char *
439 +dirname_dup (const char *name)
440 +{
441 +  char *copy = strdup(name);
442 +  char *res = dirname(copy);
443 +  res = strdup(res);
444 +  free (copy);
445 +  return res;
446 +}
447 +
448 +DNotify::Status
449 +DNotify::express(const char *name, struct stat *status)
450 +{
451 +    struct stat stat;
452 +    char *notify_dir;
453 +    int res;
454 +    Status s;
455 +    dev_t dev;
456 +    ino_t ino;
457 +
458 +    Log::debug("express() name: %s\n", name);
459 +
460 +    if (!is_active())
461 +       return BAD;
462 +
463 +    if (::lstat (name, &stat) == -1)
464 +      return BAD;
465 +
466 +    dev = stat.st_dev;
467 +    ino = stat.st_ino;
468 +    
469 +    if ((stat.st_mode & S_IFMT) != S_IFDIR)
470 +       notify_dir = dirname_dup (name);
471 +    else
472 +       notify_dir = (char *)name;
473 +
474 +    s = watch_dir (notify_dir, dev, ino);
475 +    if (notify_dir != name)
476 +        free (notify_dir);
477 +    if (s)
478 +      return s;
479 +
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.
484 +    //
485 +    struct stat st;
486 +    if (status == NULL) {
487 +       status = &st;
488 +    }
489 +    if (::lstat(name, status) == -1) {
490 +       Log::perror("stat on \"%s\" failed", name);
491 +       revoke(name, stat.st_dev, stat.st_ino);
492 +       return BAD;
493 +    }
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",
497 +                  name);
498 +       revoke(name, stat.st_dev, stat.st_ino);
499 +       return BAD;
500 +    }  
501 +
502 +    Log::debug("told dnotify to monitor \"%s\" = dev %d/%d, ino %d", name,
503 +              major(status->st_dev), minor(status->st_dev),
504 +              status->st_ino);
505 +    return OK;
506 +}
507 +
508 +DNotify::Status
509 +DNotify::revoke(const char *name, dev_t dev, ino_t ino)
510 +{
511 +    FileWatch *fwatch;
512 +    DirWatch *dwatch;
513 +    
514 +    Log::debug("revoke() name: %s, dev: %x, ino: %x\n", name, dev, ino);
515 +
516 +    if (!is_active())
517 +       return BAD;
518 +
519 +    // Lookup FileWatch by dev:ino, and its DirWatch.
520 +    fwatch = lookup_filewatch (dev, ino);
521 +    if (fwatch == NULL)
522 +       return BAD;
523 +    
524 +    dwatch = fwatch->dir_watch;
525 +    
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);
529 +    FileWatch **p;
530 +    for (p=&dwatch->watches; *p; p=&(*p)->next)
531 +    {
532 +      if (*p == fwatch)
533 +       {
534 +         *p = (*p)->next;
535 +         break;
536 +       }
537 +    }
538 +    unhash_filewatch(fwatch);
539 +    delete fwatch;
540 +    if (dwatch->watches == NULL)
541 +      {
542 +       Log::debug ("Destroying DirWatch for (%x %x)\n",
543 +                   (int)dwatch->dir_dev, (int)dwatch->dir_ino);
544 +       close(dwatch->fd);
545 +       unhash_dirwatch(dwatch);
546 +       delete dwatch;
547 +      }
548 +  
549 +    return OK;
550 +}
551 +
552 +
553 +void
554 +DNotify::all_watches_changed(void)
555 +{
556 +  int i;
557 +  FileWatch *fw;
558 +
559 +  for (i=0; i<FILE_HASHSIZE; i++)
560 +  {
561 +      fw = file_hash[i];
562 +      while (fw)
563 +      {
564 +         (*ehandler)(fw->file_dev, fw->file_ino, CHANGE);
565 +
566 +         fw = fw->hash_link;
567 +      }
568 +  }
569 +}
570 +
571 +
572 +void
573 +DNotify::read_handler(int fd, void *)
574 +{
575 +    static char readbuf[5000];
576 +    DirWatch *dw;
577 +    FileWatch *fw;
578 +    int snap_queue_tail;
579 +    int last_fd;
580 +
581 +    int rc = read(fd, readbuf, sizeof readbuf);
582 +    queue_changed = 0;
583 +    if (rc < 0)
584 +        Log::perror("pipe read");
585 +    else if (queue_overflowed)
586 +    {
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
590 +         // anyway.
591 +         queue_overflowed = false;
592 +
593 +         // We're soon gonna check all watches anyway, so
594 +         // get rid of the current queue
595 +         queue_head = queue_tail;
596 +         
597 +         all_watches_changed ();
598 +    }
599 +    else
600 +    {
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;
605 +       last_fd = -1;
606 +       while (queue_head != snap_queue_tail)
607 +       {
608 +           fd = change_queue[queue_head];
609 +           queue_head = (queue_head + 1) % QUEUESIZE;
610 +
611 +           // Skip multiple changes to the same fd
612 +           if (fd != last_fd)
613 +           {
614 +               dw = lookup_dirwatch (fd);
615 +               if (dw)
616 +               {
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)
620 +                   {
621 +                       (*ehandler)(fw->file_dev, fw->file_ino, CHANGE);
622 +                   }
623 +               }
624 +           }
625 +           last_fd = fd;
626 +       }
627 +    }
628 +}
629 +
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
633 @@ -0,0 +1,97 @@
634 +//  Copyright (C) 2001 Red Hat, Inc.  All Rights Reserved.
635 +//  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.
636 +//
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.
640 +//
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.
652 +//
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.
656 +
657 +#ifndef DNotify_included
658 +#define DNotify_included
659 +
660 +#include "config.h"
661 +#include "Monitor.h"
662 +#include <signal.h>
663 +
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.
667 +//
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.
672 +//
673 +//  The user of the DNotify object is the Interest class.
674 +
675 +class DNotify : public Monitor {
676 +public:
677 +    DNotify(EventHandler h);
678 +    ~DNotify();
679 +
680 +    static bool is_active();
681 +
682 +    virtual Status express(const char *name, struct stat *stat_return);
683 +    virtual Status revoke(const char *name, dev_t dev, ino_t ino);
684 +
685 +private:
686 +    struct FileWatch;
687 +    struct DirWatch;
688 +  
689 +    //  Class Variables
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);
702
703 +    enum { DIR_HASHSIZE = 257 };
704 +    static DirWatch *dir_hash[DIR_HASHSIZE];
705 +    enum { FILE_HASHSIZE = 257 };
706 +    static FileWatch *file_hash[FILE_HASHSIZE];
707 +
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]; }
712 +
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);
721 +
722 +    static void all_watches_changed(void);
723 +    
724 +    DNotify(const DNotify&);                   // Do not copy
725 +    DNotify & operator = (const DNotify&);     //  or assign.
726 +};
727 +
728 +#endif /* !IMon_included */
729 +
730 +
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
734 @@ -24,10 +24,7 @@
735  #define IMon_included
736  
737  #include "config.h"
738 -#include <sys/stat.h>
739 -#include <sys/types.h>
740 -
741 -#include "Boolean.h"
742 +#include "Monitor.h"
743  
744  struct stat;
745  
746 @@ -41,25 +38,18 @@
747  //
748  //  The user of the IMon object is the Interest class.
749  
750 -class IMon {
751 +class IMon : public Monitor {
752  
753  public:
754 -
755 -    enum Status { OK = 0, BAD = -1 };
756 -    enum Event { EXEC, EXIT, CHANGE };
757 -
758 -    typedef void (*EventHandler)(dev_t, ino_t, int event);
759 -
760      IMon(EventHandler h);
761      ~IMon();
762  
763      static bool is_active();
764  
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);
769  
770  private:
771 -
772      //  Class Variables
773  
774      static int imonfd;
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
778 @@ -41,12 +41,21 @@
779  #include "Event.h"
780  #include "FileSystem.h"
781  #include "IMon.h"
782 +#include "DNotify.h"
783  #include "Log.h"
784  #include "Pollster.h"
785  #include "timeval.h"
786  
787  Interest *Interest::hashtable[];
788 -IMon      Interest::imon(imon_handler);
789 +
790 +#ifdef USE_DNOTIFY 
791 +static DNotify dnotify(Interest::monitor_handler);
792 +Monitor * Interest::monitor = &dnotify;
793 +#else
794 +static IMon imon(Interest::monitor_handler);
795 +Monitor * Interest::monitor = &imon;
796 +#endif
797 +
798  bool      Interest::xtab_verification = true;
799  
800  Interest::Interest(const char *name, FileSystem *fs, in_addr host, ExportVerification ev)
801 @@ -58,11 +67,11 @@
802        myhost(host),
803        mypath_exported_to_host(ev == NO_VERIFY_EXPORTED)
804  {
805 -    memset(&old_stat, 0, sizeof(old_stat)); 
806 -    IMon::Status s = IMon::BAD;
807 -
808 -    s = imon.express(name, &old_stat);
809 -    if (s != IMon::OK)
810 +    memset(&old_stat, 0, sizeof(old_stat));
811 +    
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);
816         if (rc < 0)
817         {   Log::info("can't lstat %s", name);
818 @@ -99,7 +108,7 @@
819      }
820  #endif
821  
822 -    if (exported_to_host()) fs->ll_monitor(this, s == IMon::OK);
823 +    if (exported_to_host()) fs->ll_monitor(this, s == Monitor::OK);
824  }
825  
826  Interest::~Interest()
827 @@ -127,7 +136,7 @@
828                 pp = &p->hashlink;      // move to next element
829             }
830         if (!found_same)
831 -           (void) imon.revoke(name(), dev, ino);
832 +         (void) monitor->revoke(name(), dev, ino);
833      }
834  }
835  
836 @@ -146,7 +155,7 @@
837  
838          // Express interest.
839          IMon::Status s = IMon::BAD;
840 -       s = imon.express(name(), NULL);
841 +       s = monitor->express(name(), NULL);
842          if (s != IMon::OK) {
843              return true;
844          }
845 @@ -242,23 +251,23 @@
846  }
847  
848  void
849 -Interest::imon_handler(dev_t device, ino_t inumber, int event)
850 +Interest::monitor_handler(dev_t device, ino_t inumber, int event)
851  {
852      assert(device || inumber);
853  
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();
861             }
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();
866             }
867             else
868 -           {   assert(event == IMon::CHANGE);
869 +           {   assert(event == Monitor::CHANGE);
870                 p->scan();
871             }
872         }
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
876 @@ -32,7 +32,7 @@
877  
878  class Event;
879  class FileSystem;
880 -class IMon;
881 +class Monitor;
882  struct stat;
883  
884  //  Interest -- abstract base class for filesystem entities of interest.
885 @@ -74,7 +74,7 @@
886  
887      //  Public Class Method
888  
889 -    static void imon_handler(dev_t, ino_t, int event);
890 +    static void monitor_handler(dev_t, ino_t, int event);
891  
892      static void enable_xtab_verification(bool enable);
893  
894 @@ -121,7 +121,7 @@
895  
896      //  Class Variables
897  
898 -    static IMon imon;
899 +    static Monitor *monitor;
900      static Interest *hashtable[HASHSIZE];
901      static bool xtab_verification;
902  
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
906 @@ -3,6 +3,12 @@
907  bin_PROGRAMS = fam
908  sysconf_DATA = fam.conf
909  
910 +if USE_DNOTIFY
911 +DNOTIFY_FILES = DNotify.c++
912 +else
913 +DNOTIFY_FILES =
914 +endif
915 +
916  fam_SOURCES = \
917    Activity.c++ \
918    Activity.h \
919 @@ -20,6 +26,7 @@
920    Directory.h \
921    DirectoryScanner.c++ \
922    DirectoryScanner.h \
923 +  DNotify.h \
924    Event.c++ \
925    Event.h \
926    File.c++ \
927 @@ -48,6 +55,7 @@
928    NFSFileSystem.h \
929    NetConnection.c++ \
930    NetConnection.h \
931 +  Monitor.h \
932    Pollster.c++ \
933    Pollster.h \
934    Request.h \
935 @@ -72,9 +80,10 @@
936    main.c++ \
937    timeval.c++ \
938    timeval.h \
939 -  @IMON_FUNCS@.c++
940 +  @IMON_FUNCS@.c++ \
941 +  $(DNOTIFY_FILES)
942  
943 -EXTRA_fam_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++
944 +EXTRA_fam_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++ DNotify.c++
945  
946  fam_LDADD = -lrpcsvc $(top_srcdir)/support/libsupport.a
947  
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
951 @@ -0,0 +1,57 @@
952 +//  Copyright (C) 2001 Red Hat, Inc.  All Rights Reserved.
953 +//  Copyright (C) 1999 Silicon Graphics, Inc.  All Rights Reserved.
954 +//  
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.
958 +//
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.
970 +//
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.
974 +
975 +#ifndef Monitor_included
976 +#define Monitor_included
977 +
978 +#include "config.h"
979 +#include <sys/stat.h>
980 +#include <sys/types.h>
981 +
982 +struct stat;
983 +
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.
988 +//
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.
993 +//
994 +//  The main implementers of the Monitor class is IMon and DNotify
995 +
996 +class Monitor {
997 +public:
998 +
999 +    enum Status { OK = 0, BAD = -1 };
1000 +    enum Event { EXEC, EXIT, CHANGE };
1001 +
1002 +    typedef void (*EventHandler)(dev_t, ino_t, int event);
1003 +
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;
1006 +};
1007 +
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
1012 @@ -272,7 +272,7 @@
1013      n += that->n + 1;
1014      link[n] = that->link[that->n];
1015      that->n = 0;
1016 -    that->link[0] = NULL;
1017 +    that->link[0] = 0;
1018  }
1019  
1020  ///////////////////////////////////////////////////////////////////////////////
1021 @@ -281,7 +281,7 @@
1022  
1023  template <class K, class V>
1024  BTree<K, V>::BTree()
1025 -    : root(NULL), npairs(0)
1026 +    : root(0), npairs(0)
1027  {
1028      assert(!(fanout % 2));
1029  }
1030 @@ -408,7 +408,7 @@
1031  BTree<Key, Value>::Closure
1032  BTree<Key, Value>::insert(Node *p, const Key& key, const Value& value)
1033  {
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
1039 @@ -476,7 +476,7 @@
1040      case UNDER:
1041         if (root->n == 0)
1042         {   Node *nr = root->link[0];
1043 -           root->link[0] = NULL;       // don't delete subtree
1044 +           root->link[0] = 0;  // don't delete subtree
1045             delete root;
1046             root = nr;
1047         }
1048 @@ -508,8 +508,8 @@
1049      Node *cp = p->link[i];
1050      assert(cp);
1051      
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);
1058  
This page took 0.326387 seconds and 3 git commands to generate.