source:
scripts/untested/blfs-patches/fam-2.7.0-dnotify.patch@
e5345f18
Last change on this file since e5345f18 was 617118d, checked in by , 19 years ago | |
---|---|
|
|
File size: 25.8 KB |
-
src/DNotify.c++
old new 1 // Copyright (C) 2001 Red Hat, Inc. All Rights Reserved. 2 // Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of version 2 of the GNU General Public License as 6 // published by the Free Software Foundation. 7 // 8 // This program is distributed in the hope that it would be useful, but 9 // WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any 11 // license provided herein, whether implied or otherwise, is limited to 12 // this program in accordance with the express provisions of the GNU 13 // General Public License. Patent licenses, if any, provided herein do not 14 // apply to combinations of this program with other product or programs, or 15 // any other product whatsoever. This program is distributed without any 16 // warranty that the program is delivered free of the rightful claim of any 17 // third person by way of infringement or the like. See the GNU General 18 // Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License along 21 // with this program; if not, write the Free Software Foundation, Inc., 59 22 // Temple Place - Suite 330, Boston MA 02111-1307, USA. 23 24 #define _GNU_SOURCE 25 #include <fcntl.h> 26 27 #include <string.h> 28 #include <signal.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <libgen.h> 34 35 #include "DNotify.h" 36 37 #include "Interest.h" 38 #include "Log.h" 39 #include "Scheduler.h" 40 #include <memory> 41 42 43 int DNotify::pipe_write_fd = -2; 44 int DNotify::pipe_read_fd = -2; 45 volatile sig_atomic_t DNotify::queue_overflowed = 0; 46 volatile sig_atomic_t DNotify::queue_changed = 0; 47 int DNotify::change_queue[QUEUESIZE]; 48 volatile int DNotify::queue_head = 0; // Only modified by read handler 49 volatile int DNotify::queue_tail = 0; // Only modified by signal handler 50 DNotify::EventHandler DNotify::ehandler; 51 52 DNotify::DirWatch *DNotify::dir_hash[DIR_HASHSIZE]; 53 DNotify::FileWatch *DNotify::file_hash[FILE_HASHSIZE]; 54 55 struct DNotify::FileWatch 56 { 57 DirWatch *dir_watch; 58 dev_t file_dev; 59 ino_t file_ino; 60 FileWatch *next; // The DirWatch.watches list 61 FileWatch *hash_link; 62 }; 63 64 struct DNotify::DirWatch 65 { 66 int fd; 67 dev_t dir_dev; 68 ino_t dir_ino; 69 70 DirWatch *hash_link; 71 FileWatch *watches; 72 }; 73 74 struct DNotify::ChangeEventData 75 { 76 dev_t file_dev; 77 ino_t file_ino; 78 }; 79 80 DNotify::DNotify(EventHandler h) 81 { 82 assert(ehandler == NULL); 83 ehandler = h; 84 } 85 86 DNotify::~DNotify() 87 { 88 if (pipe_read_fd >= 0) 89 { 90 // Tell the scheduler. 91 92 (void) Scheduler::remove_read_handler(pipe_read_fd); 93 94 // Close the pipe. 95 96 if (close(pipe_read_fd) < 0) 97 Log::perror("can't pipe read end"); 98 else 99 Log::debug("closed pipe read end"); 100 101 if (close(pipe_write_fd) < 0) 102 Log::perror("can't pipe write end"); 103 else 104 Log::debug("closed pipe write end"); 105 pipe_read_fd = -1; 106 } 107 ehandler = NULL; 108 } 109 110 void 111 DNotify::overflow_signal_handler(int sig, siginfo_t *si, void *data) 112 { 113 char c = 'x'; 114 115 { 116 char *str = "*************** overflow sigqueue ***********************\n"; 117 write (STDERR_FILENO, str, strlen(str)); 118 } 119 120 if (!queue_overflowed) 121 { 122 queue_overflowed = 1; 123 // Trigger the read handler 124 write(pipe_write_fd, &c, 1); 125 } 126 } 127 128 void 129 DNotify::signal_handler(int sig, siginfo_t *si, void *data) 130 { 131 int left; 132 char c = 'x'; 133 134 if (queue_head <= queue_tail) 135 left = (QUEUESIZE + queue_head) - queue_tail; 136 else 137 left = queue_head - queue_tail; 138 139 // Must leave at least one item unused to see difference 140 // Betweeen empty and full 141 if (left <= 1) 142 { 143 queue_overflowed = 1; 144 { 145 char *str = "*************** overflow famqueue ****************\n"; 146 write (STDERR_FILENO, str, strlen(str)); 147 } 148 } 149 else 150 { 151 change_queue[queue_tail] = si->si_fd; 152 queue_tail = (queue_tail + 1) % QUEUESIZE; 153 } 154 155 if (!queue_changed) 156 { 157 queue_changed = 1; 158 // Trigger the read handler 159 write(pipe_write_fd, &c, 1); 160 } 161 } 162 163 bool 164 DNotify::is_active() 165 { 166 if (pipe_read_fd == -2) 167 { 168 int filedes[2]; 169 int res; 170 171 res = pipe (filedes); 172 if (res >= 0) 173 { Log::debug("opened pipe"); 174 pipe_read_fd = filedes[0]; 175 pipe_write_fd = filedes[1]; 176 177 // Setup signal handler: 178 struct sigaction act; 179 180 act.sa_sigaction = signal_handler; 181 sigemptyset(&act.sa_mask); 182 act.sa_flags = SA_SIGINFO; 183 sigaction(SIGRTMIN, &act, NULL); 184 185 // When the RT queue overflows we get a SIGIO 186 act.sa_sigaction = overflow_signal_handler; 187 sigemptyset(&act.sa_mask); 188 sigaction(SIGIO, &act, NULL); 189 190 (void) Scheduler::install_read_handler(pipe_read_fd, read_handler, NULL); 191 } 192 } 193 return pipe_read_fd >= 0; 194 } 195 196 DNotify::DirWatch * 197 DNotify::lookup_dirwatch (int fd) 198 { 199 DirWatch **p; 200 DirWatch *w; 201 202 p = dir_hashchain (fd); 203 204 while (*p) 205 { 206 w = *p; 207 208 if (w->fd == fd) 209 return w; 210 211 p = &w->hash_link; 212 } 213 214 return *p; 215 } 216 217 // This colud be made faster by using another hash table. 218 // But it's not that bad, since it is only used by express/revoke 219 DNotify::DirWatch * 220 DNotify::lookup_dirwatch (dev_t dir_dev, ino_t dir_ino) 221 { 222 DirWatch *p; 223 int i; 224 225 for (i=0;i<DIR_HASHSIZE;i++) 226 { 227 p = dir_hash[i]; 228 229 while (p) 230 { 231 if (p->dir_dev == dir_dev && p->dir_ino == dir_ino) 232 return p; 233 234 p = p->hash_link; 235 } 236 } 237 238 return NULL; 239 } 240 241 DNotify::FileWatch * 242 DNotify::lookup_filewatch (dev_t dev, ino_t ino) 243 { 244 FileWatch **p; 245 FileWatch *w; 246 247 p = file_hashchain (dev, ino); 248 249 while (*p) 250 { 251 w = *p; 252 253 if (w->file_dev == dev && w->file_ino == ino) 254 return w; 255 256 p = &w->hash_link; 257 } 258 259 return *p; 260 } 261 262 // Make sure w is not already in the hash table before calling 263 // this function. 264 void 265 DNotify::hash_dirwatch(DirWatch *w) 266 { 267 DirWatch **p; 268 p = dir_hashchain (w->fd); 269 w->hash_link = *p; 270 *p = w; 271 } 272 273 // Make sure w is not already in the hash table before calling 274 // this function. 275 void 276 DNotify::hash_filewatch(FileWatch *w) 277 { 278 FileWatch **p; 279 p = file_hashchain (w->file_dev, w->file_ino); 280 w->hash_link = *p; 281 *p = w; 282 } 283 284 void 285 DNotify::unhash_dirwatch(DirWatch *w) 286 { 287 DirWatch **p; 288 289 p = dir_hashchain (w->fd); 290 291 while (*p) 292 { 293 if (*p == w) 294 { 295 *p = w->hash_link; 296 break; 297 } 298 p = &(*p)->hash_link; 299 } 300 w->hash_link = NULL; 301 } 302 303 void 304 DNotify::unhash_filewatch(FileWatch *w) 305 { 306 FileWatch **p; 307 308 p = file_hashchain (w->file_dev, w->file_ino); 309 310 while (*p) 311 { 312 if (*p == w) 313 { 314 *p = w->hash_link; 315 break; 316 } 317 p = &(*p)->hash_link; 318 } 319 w->hash_link = NULL; 320 } 321 322 DNotify::Status 323 DNotify::watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino) 324 { 325 struct stat stat; 326 dev_t dir_dev; 327 ino_t dir_ino; 328 DirWatch *dwatch; 329 FileWatch *fw; 330 331 if (lstat (notify_dir, &stat) == -1) 332 return BAD; 333 334 dwatch = lookup_dirwatch(stat.st_dev, stat.st_ino); 335 if (!dwatch) 336 { 337 Log::debug ("New DirWatch for %s (%x %x)\n", 338 notify_dir, (int)stat.st_dev, (int)stat.st_ino); 339 dwatch = new DirWatch; 340 dwatch->watches = NULL; 341 dwatch->hash_link = NULL; 342 dwatch->dir_dev = stat.st_dev; 343 dwatch->dir_ino = stat.st_ino; 344 345 dwatch->fd = open(notify_dir, O_RDONLY); 346 fcntl (dwatch->fd, F_SETSIG, SIGRTMIN); 347 if (fcntl (dwatch->fd, F_NOTIFY, 348 (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB) 349 | DN_MULTISHOT) == -1) { 350 return BAD; 351 } 352 hash_dirwatch (dwatch); 353 } 354 355 fw = lookup_filewatch (file_dev, file_ino); 356 if (fw && fw->dir_watch == dwatch) 357 return OK; 358 359 // No old FileWatch, need to add one: 360 Log::debug("New FileWatch for %x %x\n", (int)file_dev, (int)file_ino); 361 fw = new FileWatch; 362 fw->next = dwatch->watches; 363 dwatch->watches = fw; 364 fw->file_dev = file_dev; 365 fw->file_ino = file_ino; 366 fw->dir_watch = dwatch; 367 hash_filewatch(fw); 368 return OK; 369 } 370 371 char * 372 dirname_dup (const char *name) 373 { 374 char *copy = strdup(name); 375 char *res = dirname(copy); 376 res = strdup(res); 377 free (copy); 378 return res; 379 } 380 381 DNotify::Status 382 DNotify::express(const char *name, struct stat *status) 383 { 384 struct stat stat; 385 char *notify_dir; 386 int res; 387 Status s; 388 dev_t dev; 389 ino_t ino; 390 391 Log::debug("express() name: %s\n", name); 392 393 if (!is_active()) 394 return BAD; 395 396 if (::lstat (name, &stat) == -1) 397 return BAD; 398 399 dev = stat.st_dev; 400 ino = stat.st_ino; 401 402 if ((stat.st_mode & S_IFMT) != S_IFDIR) 403 notify_dir = dirname_dup (name); 404 else 405 notify_dir = (char *)name; 406 407 s = watch_dir (notify_dir, dev, ino); 408 if (notify_dir != name) 409 free (notify_dir); 410 if (s) 411 return s; 412 413 // Check for a race condition; if someone removed or changed the 414 // file at the same time that we are expressing interest in it, 415 // revoke the interest so we don't get notifications about changes 416 // to a recycled inode that we don't otherwise care about. 417 // 418 struct stat st; 419 if (status == NULL) { 420 status = &st; 421 } 422 if (::lstat(name, status) == -1) { 423 Log::perror("stat on \"%s\" failed", name); 424 revoke(name, stat.st_dev, stat.st_ino); 425 return BAD; 426 } 427 if (status->st_dev != stat.st_dev 428 || status->st_ino != stat.st_ino) { 429 Log::error("File \"%s\" changed between express and stat", 430 name); 431 revoke(name, stat.st_dev, stat.st_ino); 432 return BAD; 433 } 434 435 Log::debug("told dnotify to monitor \"%s\" = dev %d/%d, ino %d", name, 436 major(status->st_dev), minor(status->st_dev), 437 status->st_ino); 438 return OK; 439 } 440 441 DNotify::Status 442 DNotify::revoke(const char *name, dev_t dev, ino_t ino) 443 { 444 FileWatch *fwatch; 445 DirWatch *dwatch; 446 447 Log::debug("revoke() name: %s, dev: %x, ino: %x\n", name, dev, ino); 448 449 if (!is_active()) 450 return BAD; 451 452 // Lookup FileWatch by dev:ino, and its DirWatch. 453 fwatch = lookup_filewatch (dev, ino); 454 if (fwatch == NULL) 455 return BAD; 456 457 dwatch = fwatch->dir_watch; 458 459 // delete FileWatch, if last FileWatch: close fd, delete DirWatch 460 Log::debug ("Destroying FileWatch for (%x %x)\n", 461 (int)fwatch->file_dev, (int)fwatch->file_ino); 462 FileWatch **p; 463 for (p=&dwatch->watches; *p; p=&(*p)->next) 464 { 465 if (*p == fwatch) 466 { 467 *p = (*p)->next; 468 break; 469 } 470 } 471 unhash_filewatch(fwatch); 472 delete fwatch; 473 if (dwatch->watches == NULL) 474 { 475 Log::debug ("Destroying DirWatch for (%x %x)\n", 476 (int)dwatch->dir_dev, (int)dwatch->dir_ino); 477 close(dwatch->fd); 478 unhash_dirwatch(dwatch); 479 delete dwatch; 480 } 481 482 return OK; 483 } 484 485 486 void 487 DNotify::all_watches_changed(void) 488 { 489 int i; 490 FileWatch *fw; 491 492 for (i=0; i<FILE_HASHSIZE; i++) 493 { 494 fw = file_hash[i]; 495 while (fw) 496 { 497 (*ehandler)(fw->file_dev, fw->file_ino, CHANGE); 498 499 fw = fw->hash_link; 500 } 501 } 502 } 503 504 505 void 506 DNotify::read_handler(int fd, void *) 507 { 508 static char readbuf[5000]; 509 DirWatch *dw; 510 FileWatch *fw; 511 int snap_queue_tail; 512 int last_fd; 513 514 int rc = read(fd, readbuf, sizeof readbuf); 515 queue_changed = 0; 516 if (rc < 0) 517 Log::perror("pipe read"); 518 else if (queue_overflowed) 519 { 520 // There is a *slight* race condition here. Between reading 521 // the queue_overflow flag and resetting it. But it doesn't 522 // matter, since I'm gonna handle the overflow after reseting 523 // anyway. 524 queue_overflowed = false; 525 526 // We're soon gonna check all watches anyway, so 527 // get rid of the current queue 528 queue_head = queue_tail; 529 530 all_watches_changed (); 531 } 532 else 533 { 534 // Don't read events that happen later than 535 // the initial read. (Otherwise skipping fd's 536 // might miss some changes). 537 snap_queue_tail = queue_tail; 538 last_fd = -1; 539 while (queue_head != snap_queue_tail) 540 { 541 fd = change_queue[queue_head]; 542 queue_head = (queue_head + 1) % QUEUESIZE; 543 544 // Skip multiple changes to the same fd 545 if (fd != last_fd) 546 { 547 dw = lookup_dirwatch (fd); 548 if (dw) 549 { 550 int n_watches, i; 551 ChangeEventData *data; 552 553 Log::debug("dnotify said dev %d/%d, ino %ld changed", 554 major(dw->dir_dev), minor(dw->dir_dev), dw->dir_ino); 555 556 n_watches = 0; 557 for (fw=dw->watches; fw; fw=fw->next) 558 n_watches++; 559 560 data = new ChangeEventData[n_watches]; 561 562 i = 0; 563 for (fw=dw->watches; fw; fw=fw->next) 564 { 565 data[i].file_dev = fw->file_dev; 566 data[i].file_ino = fw->file_ino; 567 i++; 568 } 569 570 for (i = 0; i < n_watches; i++) 571 { 572 (*ehandler)(data[i].file_dev, data[i].file_ino, CHANGE); 573 } 574 575 delete[] data; 576 } 577 } 578 last_fd = fd; 579 } 580 } 581 } 582 -
src/DNotify.h
old new 1 // Copyright (C) 2001 Red Hat, Inc. All Rights Reserved. 2 // Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of version 2 of the GNU General Public License as 6 // published by the Free Software Foundation. 7 // 8 // This program is distributed in the hope that it would be useful, but 9 // WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any 11 // license provided herein, whether implied or otherwise, is limited to 12 // this program in accordance with the express provisions of the GNU 13 // General Public License. Patent licenses, if any, provided herein do not 14 // apply to combinations of this program with other product or programs, or 15 // any other product whatsoever. This program is distributed without any 16 // warranty that the program is delivered free of the rightful claim of any 17 // third person by way of infringement or the like. See the GNU General 18 // Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License along 21 // with this program; if not, write the Free Software Foundation, Inc., 59 22 // Temple Place - Suite 330, Boston MA 02111-1307, USA. 23 24 #ifndef DNotify_included 25 #define DNotify_included 26 27 #include "config.h" 28 #include "Monitor.h" 29 #include <signal.h> 30 31 // DNotify is an object encapsulating the dnotify linux fcntl. 32 // It "emulates" the IMon interface. 33 // There can only be one instantiation of the DNotify object. 34 // 35 // The user of this object uses express() and revoke() to 36 // express/revoke interest in a file. There is also 37 // a callback, the EventHandler. When an dnotify event comes in, 38 // the EventHandler is called. 39 // 40 // The user of the DNotify object is the Interest class. 41 42 class DNotify : public Monitor { 43 public: 44 DNotify(EventHandler h); 45 ~DNotify(); 46 47 static bool is_active(); 48 49 virtual Status express(const char *name, struct stat *stat_return); 50 virtual Status revoke(const char *name, dev_t dev, ino_t ino); 51 52 private: 53 struct FileWatch; 54 struct DirWatch; 55 struct ChangeEventData; 56 57 // Class Variables 58 enum { QUEUESIZE = 1024 }; 59 static int pipe_write_fd; 60 static int pipe_read_fd; 61 static int change_queue[QUEUESIZE]; 62 static volatile sig_atomic_t DNotify::queue_overflowed; 63 static volatile sig_atomic_t DNotify::queue_changed; 64 static volatile int queue_head; // Only modified by read handler 65 static volatile int queue_tail; // Only modified by signal handler 66 static EventHandler ehandler; 67 static void overflow_signal_handler(int sig, siginfo_t *si, void *data); 68 static void signal_handler(int sig, siginfo_t *si, void *data); 69 static void read_handler(int fd, void *closure); 70 71 enum { DIR_HASHSIZE = 367 }; 72 static DirWatch *dir_hash[DIR_HASHSIZE]; 73 enum { FILE_HASHSIZE = 823 }; 74 static FileWatch *file_hash[FILE_HASHSIZE]; 75 76 static DirWatch **dir_hashchain(int fd) 77 { return &dir_hash[(unsigned) (fd) % DIR_HASHSIZE]; } 78 static FileWatch **file_hashchain(dev_t d, ino_t i) 79 { return &file_hash[(unsigned) (d+i) % FILE_HASHSIZE]; } 80 81 static DirWatch *lookup_dirwatch (int fd); 82 static DirWatch *lookup_dirwatch (dev_t dir_dev, ino_t dir_ino); 83 static FileWatch *lookup_filewatch (dev_t file_dev, ino_t file_ino); 84 static void hash_dirwatch(DirWatch *w); 85 static void hash_filewatch(FileWatch *w); 86 static void unhash_dirwatch(DirWatch *w); 87 static void unhash_filewatch(FileWatch *w); 88 static Status watch_dir(const char *notify_dir, dev_t file_dev, ino_t file_ino); 89 90 static void all_watches_changed(void); 91 92 DNotify(const DNotify&); // Do not copy 93 DNotify & operator = (const DNotify&); // or assign. 94 }; 95 96 #endif /* !IMon_included */ 97 98 -
src/Interest.c++
old new 42 42 #include "Event.h" 43 43 #include "FileSystem.h" 44 44 #include "IMon.h" 45 #include "DNotify.h" 45 46 #include "Log.h" 46 47 #include "Pollster.h" 47 48 #include "timeval.h" 48 49 49 50 Interest *Interest::hashtable[]; 50 IMon Interest::imon(imon_handler); 51 52 #ifdef USE_DNOTIFY 53 static DNotify dnotify(Interest::monitor_handler); 54 Monitor * Interest::monitor = &dnotify; 55 #else 56 static IMon imon(Interest::monitor_handler); 57 Monitor * Interest::monitor = &imon; 58 #endif 59 51 60 bool Interest::xtab_verification = true; 52 61 53 62 Interest::Interest(const char *name, FileSystem *fs, in_addr host, ExportVerification ev) … … 60 69 mypath_exported_to_host(ev == NO_VERIFY_EXPORTED) 61 70 { 62 71 memset(&old_stat, 0, sizeof(old_stat)); 63 IMon::Status s = IMon::BAD;64 72 65 s = imon.express(name, &old_stat); 66 if (s != IMon::OK) 73 Monitor::Status s = Monitor::BAD; 74 s = monitor->express(name, &old_stat); 75 if (s != Monitor::OK) 67 76 { int rc = lstat(name, &old_stat); 68 77 if (rc < 0) 69 78 { Log::info("can't lstat %s", name); … … 100 109 } 101 110 #endif 102 111 103 if (exported_to_host()) fs->ll_monitor(this, s == IMon::OK);112 if (exported_to_host()) fs->ll_monitor(this, s == Monitor::OK); 104 113 } 105 114 106 115 Interest::~Interest() … … 128 137 pp = &p->hashlink; // move to next element 129 138 } 130 139 if (!found_same) 131 (void) imon.revoke(name(), dev, ino);140 (void) monitor->revoke(name(), dev, ino); 132 141 } 133 142 } 134 143 … … 147 156 148 157 // Express interest. 149 158 IMon::Status s = IMon::BAD; 150 s = imon.express(name(), NULL);159 s = monitor->express(name(), NULL); 151 160 if (s != IMon::OK) { 152 161 return true; 153 162 } … … 248 257 } 249 258 250 259 void 251 Interest:: imon_handler(dev_t device, ino_t inumber, int event)260 Interest::monitor_handler(dev_t device, ino_t inumber, int event) 252 261 { 253 262 assert(device || inumber); 254 263 255 264 for (Interest *p = *hashchain(device, inumber), *next = p; p; p = next) 256 265 { next = p->hashlink; 257 266 if (p->ino == inumber && p->dev == device) 258 { if (event == IMon::EXEC)267 { if (event == Monitor::EXEC) 259 268 { p->cur_exec_state = EXECUTING; 260 269 (void) p->report_exec_state(); 261 270 } 262 else if (event == IMon::EXIT)271 else if (event == Monitor::EXIT) 263 272 { p->cur_exec_state = NOT_EXECUTING; 264 273 (void) p->report_exec_state(); 265 274 } 266 275 else 267 { assert(event == IMon::CHANGE);276 { assert(event == Monitor::CHANGE); 268 277 p->scan(); 269 278 } 270 279 } -
config.h.in
old new 180 180 181 181 /* Define to `int' if <sys/types.h> doesn't define. */ 182 182 #undef uid_t 183 184 /* Define to 1 if you have F_NOTIFY fcntl */ 185 #undef USE_DNOTIFY -
configure.ac
old new 34 34 AC_HEADER_DIRENT 35 35 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]) 36 36 37 if test "$have_sys_imon_h"; then 37 # Test for the linux dnotify fcntl 38 AC_MSG_CHECKING([for dnotify fcntl support]) 39 AC_TRY_COMPILE([ 40 #define _GNU_SOURCE 41 #include <fcntl.h> 42 #include <unistd.h> 43 ], 44 [ int fd = 1; 45 fcntl (fd, F_NOTIFY, (DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_ATTRIB) 46 |DN_MULTISHOT); 47 ], have_dnotify=yes, have_dnotify=no) 48 49 use_dnotify=false 50 AC_MSG_RESULT($have_dnotify) 51 52 if test "$have_dnotify"; then 53 MONITOR_FUNCS=IMonNone 54 AC_DEFINE([USE_DNOTIFY], [], [Use dnotify]) 55 use_dnotify=true 56 elif test "$have_sys_imon_h"; then 38 57 MONITOR_FUNCS=IMonIRIX 39 58 elif test "$have_linux_imon_h"; then 40 59 MONITOR_FUNCS=IMonLinux … … 42 62 MONITOR_FUNCS=IMonNone 43 63 fi 44 64 AC_SUBST(MONITOR_FUNCS) 65 AM_CONDITIONAL(USE_DNOTIFY, $use_dnotify) 45 66 46 67 # Checks for typedefs, structures, and compiler characteristics. 47 68 AC_HEADER_STDBOOL -
src/IMon.h
old new 24 24 #define IMon_included 25 25 26 26 #include "config.h" 27 #include <sys/stat.h> 28 #include <sys/types.h> 29 30 #include "Boolean.h" 27 #include "Monitor.h" 31 28 32 29 struct stat; 33 30 … … 41 38 // 42 39 // The user of the IMon object is the Interest class. 43 40 44 class IMon {41 class IMon : public Monitor { 45 42 46 43 public: 47 48 enum Status { OK = 0, BAD = -1 };49 enum Event { EXEC, EXIT, CHANGE };50 51 typedef void (*EventHandler)(dev_t, ino_t, int event);52 53 44 IMon(EventHandler h); 54 45 ~IMon(); 55 46 56 47 static bool is_active(); 57 48 58 Status express(const char *name, struct stat *stat_return);59 Status revoke(const char *name, dev_t dev, ino_t ino);49 virtual Status express(const char *name, struct stat *stat_return); 50 virtual Status revoke(const char *name, dev_t dev, ino_t ino); 60 51 61 52 private: 62 63 53 // Class Variables 64 54 65 55 static int imonfd; -
src/Interest.h
old new 32 32 33 33 class Event; 34 34 class FileSystem; 35 class IMon;35 class Monitor; 36 36 struct stat; 37 37 38 38 // Interest -- abstract base class for filesystem entities of interest. … … 74 74 75 75 // Public Class Method 76 76 77 static void imon_handler(dev_t, ino_t, int event);77 static void monitor_handler(dev_t, ino_t, int event); 78 78 79 79 static void enable_xtab_verification(bool enable); 80 80 … … 121 121 122 122 // Class Variables 123 123 124 static IMon imon;124 static Monitor *monitor; 125 125 static Interest *hashtable[HASHSIZE]; 126 126 static bool xtab_verification; 127 127 -
src/Makefile.am
old new 71 71 main.c++ \ 72 72 timeval.c++ \ 73 73 timeval.h \ 74 @MONITOR_FUNCS@.c++ 74 Monitor.h \ 75 DNotify.h \ 76 DNotify.c++ \ 77 @MONITOR_FUNCS@.c++ 75 78 76 EXTRA_famd_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++ 79 EXTRA_famd_SOURCES = IMonIrix.c++ IMonLinux.c++ IMonNone.c++ DNotify.c++ \ 80 DNotify.h Monitor.h 77 81 -
src/Monitor.h
old new 1 // Copyright (C) 2001 Red Hat, Inc. All Rights Reserved. 2 // Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of version 2 of the GNU General Public License as 6 // published by the Free Software Foundation. 7 // 8 // This program is distributed in the hope that it would be useful, but 9 // WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any 11 // license provided herein, whether implied or otherwise, is limited to 12 // this program in accordance with the express provisions of the GNU 13 // General Public License. Patent licenses, if any, provided herein do not 14 // apply to combinations of this program with other product or programs, or 15 // any other product whatsoever. This program is distributed without any 16 // warranty that the program is delivered free of the rightful claim of any 17 // third person by way of infringement or the like. See the GNU General 18 // Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License along 21 // with this program; if not, write the Free Software Foundation, Inc., 59 22 // Temple Place - Suite 330, Boston MA 02111-1307, USA. 23 24 #ifndef Monitor_included 25 #define Monitor_included 26 27 #include "config.h" 28 #include <sys/stat.h> 29 #include <sys/types.h> 30 31 struct stat; 32 33 // Monitor is an abstract baseclass for differend file monitoring 34 // systems. The original system used was IMon, and the Montor API 35 // is heavily influenced by that. 36 // There can only be one instantiation of the Monitor object. 37 // 38 // The user of this object uses express() and revoke() to 39 // express/revoke interest in a file to imon. There is also 40 // a callback, the EventHandler. When an event comes in, 41 // the EventHandler is called. 42 // 43 // The main implementers of the Monitor class is IMon and DNotify 44 45 class Monitor { 46 public: 47 48 enum Status { OK = 0, BAD = -1 }; 49 enum Event { EXEC, EXIT, CHANGE }; 50 51 typedef void (*EventHandler)(dev_t, ino_t, int event); 52 53 virtual Status express(const char *name, struct stat *stat_return) = 0; 54 virtual Status revoke(const char *name, dev_t dev, ino_t ino) = 0; 55 }; 56 57 #endif /* !Monitor_included */
Note:
See TracBrowser
for help on using the repository browser.