Changeset 367 for trunk/src


Ignore:
Timestamp:
Oct 30, 2011, 9:18:31 AM (13 years ago)
Author:
katerina
Message:

Modifications for ticket #265 (inotify support). Needs testing.

Location:
trunk/src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/samhain.c

    r354 r367  
    6464#include "samhain.h"
    6565#include "sh_pthread.h"
    66 #include "sh_files.h"
    6766#include "sh_utils.h"
    6867#include "sh_error.h"
    6968#include "sh_unix.h"
     69#include "sh_files.h"
    7070#include "sh_getopt.h"
    7171#include "sh_readconf.h"
     
    393393  sh.flag.hidefile        = S_FALSE;
    394394  sh.flag.loop            = S_FALSE;
     395  sh.flag.inotify         = 0;
    395396
    396397#ifdef MKB_09
     
    17101711  (void) sh_files_test_setup();
    17111712
    1712 
    17131713  /* --------  NICE LEVEL   ---------
    17141714   */
     
    18431843              (void) sh_files_setrec();
    18441844              (void) sh_files_test_setup();
     1845
    18451846              if (0 != sh.flag.nice)
    18461847                {
     
    19651966       */
    19661967      if      (sh.flag.checkSum == SH_CHECK_INIT ||
     1968               (sh.flag.inotify & SH_INOTIFY_DOSCAN) != 0 ||
    19671969               (sh.flag.checkSum == SH_CHECK_CHECK &&
    19681970                (sh.flag.isdaemon == S_FALSE && sh.flag.loop == S_FALSE)))
     
    20602062          flag_check_2 = 0;
    20612063          check_done   = 1;
     2064          sh.flag.inotify &= ~SH_INOTIFY_DOSCAN;
    20622065
    20632066          (void) sh_prelink_run (NULL, NULL, 0);
  • trunk/src/sh_files.c

    r365 r367  
    6969#include "sh_hash.h"
    7070#include "sh_ignore.h"
     71#include "sh_inotify.h"
    7172#include "zAVLTree.h"
    7273
    7374#undef  FIL__
    7475#define FIL__  _("sh_files.c")
     76
     77extern sh_watches sh_file_watches;
    7578
    7679static char * sh_files_C_dequote (char * s, size_t * length)
     
    356359              sh_error_handle ((-1),  FIL__, __LINE__, 0,
    357360                               MSG_FI_CHK, pstr, tmp);
     361            }
     362
     363          if ((sh.flag.inotify & SH_INOTIFY_DOSCAN) != 0)
     364            {
     365              sh_inotify_add_watch_later(ptr->name, &sh_file_watches, NULL,
     366                                         ptr->class, ptr->check_mask);
    358367            }
    359368
     
    18431852    }
    18441853
     1854  if ((sh.flag.inotify & SH_INOTIFY_DOSCAN) != 0)
     1855    {
     1856      sh_inotify_add_watch_later(iname, &sh_file_watches, &status,
     1857                                 iclass, check_mask);
     1858    }
     1859   
    18451860  /* ---- stat the directory ----
    18461861   */
     
    25002515
    25012516/* -----------------------------------
     2517 * Routines required for inotify
     2518 * -----------------------------------
     2519 */
     2520int sh_files_search_file(char * name, int * class, unsigned long *check_mask, int *reported)
     2521{
     2522  dirstack_t * item = zAVLSearch(zfileList, name);
     2523
     2524  if (item)
     2525    {
     2526      *check_mask = item->check_mask;
     2527      *class      = item->class;
     2528      *reported   = item->is_reported;
     2529      return 1;
     2530    }
     2531  return 0;
     2532}
     2533
     2534void sh_files_set_file_reported(char * name)
     2535{
     2536  dirstack_t * item = zAVLSearch(zfileList, name);
     2537
     2538  if (item)
     2539    {
     2540      if (sh.flag.reportonce == S_TRUE)
     2541        SET_SH_FFLAG_REPORTED(item->is_reported);
     2542    }
     2543  return;
     2544}
     2545
     2546void sh_files_clear_file_reported(char * name)
     2547{
     2548  dirstack_t * item = zAVLSearch(zfileList, name);
     2549
     2550  if (item)
     2551    {
     2552      CLEAR_SH_FFLAG_REPORTED(item->is_reported);
     2553    }
     2554  return;
     2555}
     2556
     2557/* -----------------------------------
    25022558 *
    25032559 *  The following two routines serve to
  • trunk/src/sh_getopt.c

    r355 r367  
    3030#include "sh_error.h"
    3131#include "sh_getopt.h"
     32#include "sh_unix.h"
    3233#include "sh_files.h"
    3334#include "sh_utils.h"
  • trunk/src/sh_hash.c

    r362 r367  
    434434  char * str;
    435435  char hashbuf[KEYBUF_SIZE];
    436   int  retval;
     436  volatile int  retval;
    437437
    438438  /* --------  find the entry for the file ----------------       */
     
    459459  str = all_items(theFile, fileHash, 0);
    460460  tmp = sh_util_safe_name(fullpath);
     461
     462  SH_MUTEX_LOCK(mutex_thread_nolog);
    461463  sh_error_handle (level, FIL__, __LINE__, 0,
    462464                   MSG_FI_MISS2, tmp, str);
     465  SH_MUTEX_UNLOCK(mutex_thread_nolog);
    463466
    464467  SH_FREE(tmp);
  • trunk/src/sh_inotify.c

    r364 r367  
    5151
    5252#if defined(HAVE_PTHREAD)
     53
     54SH_MUTEX_STATIC(mutex_list_dormant, PTHREAD_MUTEX_INITIALIZER);
     55SH_MUTEX_STATIC(mutex_watches,      PTHREAD_MUTEX_INITIALIZER);
     56
    5357static pthread_key_t  inotify_key;
    5458static pthread_once_t inotify_key_once = PTHREAD_ONCE_INIT;
     
    122126  int    watch;
    123127  int    flag;
     128  int    class;
     129  unsigned long check_mask;
    124130  char * file;
    125131} sh_watch;
     
    190196#define SH_INOTIFY_MODIFY 1
    191197
    192 static void sh_inotify_init(sh_watches * watches)
    193 {
     198void sh_inotify_init(sh_watches * watches)
     199{
     200  SH_MUTEX_LOCK_UNSAFE(mutex_watches);
    194201  watches->list_of_watches = NULL;
    195202  watches->count           = 0;
    196203  watches->max_count       = 0;
     204  SH_MUTEX_UNLOCK_UNSAFE(mutex_watches);
     205
     206  SH_MUTEX_LOCK_UNSAFE(mutex_list_dormant);
     207  watches->dormant_watches = NULL;
     208  SH_MUTEX_UNLOCK_UNSAFE(mutex_list_dormant);
     209
    197210  return;
     211}
     212
     213ssize_t sh_inotify_read(char * buffer, size_t count)
     214{
     215  ssize_t len;
     216  int     ifd = sh_inotify_getfd();
     217
     218  do {
     219    len = read (ifd, &buffer, count);
     220  } while (len < 0 || errno == EINTR);
     221
     222  return len;
    198223}
    199224
     
    226251};
    227252
     253static void sh_inotify_listitem_destroy(struct sh_inotify_litem * this)
     254{
     255  if (this)
     256    SH_FREE(this);
     257  return;
     258}
     259
     260/* No Mutex in the list cursor functions, must be in the caller
     261 * function...
     262 */
    228263typedef struct {
    229264  struct sh_inotify_litem *prenode;
     
    231266} sh_inotify_listCursor;
    232267
    233 static sh_watch * sh_inotify_list_first(sh_inotify_listCursor * listcursor, sh_watches * watches)
     268static sh_watch * sh_inotify_list_first(sh_inotify_listCursor * listcursor,
     269                                        sh_watches * watches)
    234270{
    235271  listcursor->prenode = watches->dormant_watches;
    236272  listcursor->curnode = watches->dormant_watches;
    237 
    238   return listcursor->curnode->watch;
    239 }
    240 
    241 static sh_watch * sh_inotify_list_next(sh_inotify_listCursor * listcursor, sh_watches * watches)
    242 {
    243   (void) watches;
    244 
    245   listcursor->prenode = listcursor->curnode;
    246   listcursor->curnode = listcursor->curnode->next;
    247273
    248274  if (listcursor->curnode)
     
    251277}
    252278
    253 static void sh_inotify_listitem_destroy(struct sh_inotify_litem * this)
    254 {
    255   SH_FREE(this);
    256   return;
    257 }
    258 
    259 static sh_watch * sh_inotify_list_del_current(sh_inotify_listCursor * listcursor, sh_watches * watches)
     279static sh_watch * sh_inotify_list_next(sh_inotify_listCursor * listcursor,
     280                                       sh_watches * watches)
     281{
     282  (void) watches;
     283
     284  listcursor->prenode = listcursor->curnode;
     285
     286  if (listcursor->curnode)
     287    {
     288      listcursor->curnode = listcursor->curnode->next;
     289      return listcursor->curnode->watch;
     290    }
     291
     292  return NULL;
     293}
     294
     295static sh_watch * sh_inotify_list_del_cur(sh_inotify_listCursor * listcursor,
     296                                          sh_watches * watches)
    260297{
    261298  sh_watch * ret = NULL;
     
    277314          listcursor->curnode       = this->next;
    278315        }
    279       ret = listcursor->curnode->watch;
     316      if (listcursor->curnode)
     317        ret = listcursor->curnode->watch;
     318      else
     319        ret = NULL;
    280320      sh_inotify_listitem_destroy(this);
    281321    }
     
    285325static int sh_inotify_add_dormant(sh_watches * watches, sh_watch * item)
    286326{
    287   struct sh_inotify_litem * this = SH_ALLOC(sizeof(struct sh_inotify_litem));
     327  struct sh_inotify_litem * this;
     328
     329  SH_MUTEX_LOCK(mutex_list_dormant);
     330  this = SH_ALLOC(sizeof(struct sh_inotify_litem));
    288331
    289332  this->watch = item;
     
    291334 
    292335  watches->dormant_watches = this;
     336  SH_MUTEX_UNLOCK(mutex_list_dormant);
    293337  return 0;
     338}
     339
     340static void * sh_dummy_popret = NULL;
     341
     342char * sh_inotify_pop_dormant(sh_watches * watches,
     343                              int * class, unsigned long * check_mask)
     344{
     345  char * popret = NULL;
     346  struct sh_inotify_litem * this;
     347
     348  /* Take the address to keep gcc from putting it into a register.
     349   * Avoids the 'clobbered by longjmp' warning.
     350   */
     351  sh_dummy_popret = (void *) &popret;
     352
     353  SH_MUTEX_LOCK(mutex_list_dormant);
     354
     355  this = (struct sh_inotify_litem *) watches->dormant_watches;
     356
     357  if (this)
     358    {
     359      *class = this->watch->class;
     360      *check_mask = this->watch->check_mask;
     361      popret = sh_util_strdup(this->watch->file);
     362
     363      watches->dormant_watches = this->next;
     364
     365      sh_inotify_free_watch(this->watch);
     366      SH_FREE(this);
     367    }
     368  SH_MUTEX_UNLOCK(mutex_list_dormant);
     369
     370  return popret;
     371}
     372
     373void sh_inotify_purge_dormant(sh_watches * watches)
     374{
     375  struct sh_inotify_litem * this;
     376
     377  SH_MUTEX_LOCK(mutex_list_dormant);
     378  this = (struct sh_inotify_litem *) watches->dormant_watches;
     379
     380  watches->dormant_watches = NULL;
     381
     382  while (this)
     383    {
     384      struct sh_inotify_litem * cur = this;
     385     
     386      this = this->next;
     387
     388      sh_inotify_free_watch(cur->watch);
     389      SH_FREE(cur);
     390    }
     391  SH_MUTEX_UNLOCK(mutex_list_dormant);
     392  return;
    294393}
    295394
     
    308407{
    309408  int     ifd = sh_inotify_getfd();
    310   zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
     409  zAVLTree   * all_watches;
     410
     411  SH_MUTEX_LOCK(mutex_watches);
     412  all_watches = (zAVLTree *)(watches->list_of_watches);
    311413
    312414  if (all_watches)
    313415    zAVLFreeTree(all_watches, sh_inotify_free_watch);
    314416
    315   sh_inotify_init(watches);
     417  watches->list_of_watches = NULL;
     418  watches->count = 0;
     419  SH_MUTEX_UNLOCK(mutex_watches);
    316420
    317421  if (ifd >= 0)
    318422    close(ifd);
    319423  sh_set_inotify_fd(-1);
    320 
    321   watches->count = 0;
    322424
    323425  return;
     
    345447}
    346448
     449#define SH_INOTIFY_FILEFLAGS \
     450  (IN_ATTRIB|IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)
     451#define SH_INOTIFY_DIRFLAGS \
     452  (SH_INOTIFY_FILEFLAGS|IN_DELETE|IN_CREATE|IN_MOVED_FROM|IN_MOVED_TO)
     453
     454#define SH_INOTIFY_FLAGS (SH_INOTIFY_FILEFLAGS|SH_INOTIFY_DIRFLAGS)
     455
     456/* Create an item and put it on the 'dormant' list for later watch creation
     457 */
     458int sh_inotify_add_watch_later(char * filename, sh_watches * watches,
     459                               int * errnum,
     460                               int class, unsigned long check_mask)
     461{
     462  sh_watch   * item;
     463
     464  item = sh_inotify_create_watch(filename, -1, /* flag */ 0);
     465
     466  item->class      = class;
     467  item->check_mask = check_mask;
     468
     469  sh_inotify_add_dormant(watches, item);
     470  if (errnum)
     471    *errnum = 0;
     472
     473  return 0;
     474}
     475         
     476int sh_inotify_rm_watch (sh_watches * watches, sh_watches * save, int wd)
     477{
     478  int ifd = sh_get_inotify_fd();
     479
     480  if (watches)
     481    {
     482      sh_watch   * item;
     483 
     484      SH_MUTEX_LOCK(mutex_watches);
     485      item = zAVLSearch(watches->list_of_watches, &wd);
     486     
     487      if (item)
     488        {
     489          zAVLDelete(watches->list_of_watches, &wd);
     490          if (save) /* optionally save the item */
     491            {
     492              item->watch = -1;
     493              sh_inotify_add_dormant(save, item);
     494            }
     495          else
     496            {
     497              sh_inotify_free_watch(item);
     498            }
     499        }
     500      SH_MUTEX_UNLOCK(mutex_watches);
     501    }
     502  return inotify_rm_watch(ifd, wd);
     503}
     504
     505#if (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
     506static void * sh_dummy_litem;
     507
     508int sh_inotify_recheck_watches (sh_watches * watches, sh_watches * save)
     509{
     510  sh_watch   * litem;
     511  sh_inotify_listCursor listcursor;
     512  int ifd = sh_get_inotify_fd();
     513
     514  extern void sh_fInotify_report_add(char * path, int class, unsigned long check_mask);
     515
     516  sh_dummy_litem = (void*) &litem;
     517
     518  /* -- Check dormant watches for reopening.
     519   */
     520  SH_MUTEX_LOCK(mutex_list_dormant);
     521 
     522  for (litem = sh_inotify_list_first(&listcursor, save); litem;
     523       litem = sh_inotify_list_next(&listcursor, save))
     524    {
     525    have_next:
     526
     527      /* sh_inotify_list_del_cur may return NULL */
     528      if (litem && litem->file && litem->watch == -1)
     529        {
     530          litem->watch = inotify_add_watch (ifd, litem->file,
     531                                            SH_INOTIFY_FLAGS);
     532         
     533          if (litem->watch >= 0)
     534            {
     535              SH_MUTEX_LOCK(mutex_watches);
     536              if (watches->list_of_watches)
     537                zAVLInsert(watches->list_of_watches, litem);
     538              SH_MUTEX_UNLOCK(mutex_watches);
     539
     540              sh_fInotify_report_add(litem->file, litem->class, litem->check_mask);
     541
     542              litem = sh_inotify_list_del_cur(&listcursor, save);
     543             
     544              goto have_next;
     545            }
     546        }
     547    }
     548  SH_MUTEX_UNLOCK(mutex_list_dormant);
     549  return 0;
     550}
     551#endif
     552
    347553/* This function is idempotent; it will add the watch only once
    348554 */
    349 int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum)
    350 {
     555int sh_inotify_add_watch(char * filename, sh_watches * watches, int * errnum,
     556                         int class, unsigned long check_mask)
     557{
     558  volatile int retval = 0;
     559
     560  SH_MUTEX_LOCK(mutex_watches);
     561
    351562  *errnum = 0;
    352563
     
    375586
    376587          nwatch = inotify_add_watch (ifd, filename,
    377                                       IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
     588                                      SH_INOTIFY_FLAGS);
    378589          if (nwatch < 0)
    379590            {
    380591              *errnum = errno;
    381               return -1;
     592              retval = -1;
     593              goto retpoint;
    382594            }
    383595
    384596          item = sh_inotify_create_watch(filename, nwatch, /* flag */ 0);
     597
     598          item->class      = class;
     599          item->check_mask = check_mask;
    385600         
    386601          if (NULL == watches->list_of_watches)
    387             watches->list_of_watches = zAVLAllocTree (sh_inotify_getkey, zAVL_KEY_INT);
     602            watches->list_of_watches = zAVLAllocTree (sh_inotify_getkey,
     603                                                      zAVL_KEY_INT);
    388604 
    389605          if (watches->list_of_watches)
    390606            {
    391               *errnum =  zAVLInsert((zAVLTree *)(watches->list_of_watches), item);
     607              *errnum =  zAVLInsert((zAVLTree *)(watches->list_of_watches),
     608                                    item);
     609
    392610              if (*errnum != 0)
    393611                {
     612                  (*errnum == -1) ? *errnum = ENOMEM : EEXIST;
    394613                  sh_inotify_free_watch(item);
    395                   return -1;
     614                  retval = -1;
     615                  goto retpoint;
    396616                }
    397617            }
    398618          else
    399619            {
    400               *errnum = -1;
    401               return -1;
     620              *errnum = ENOMEM;
     621              retval = -1;
     622              goto retpoint;
    402623            }
    403624
     
    405626        }
    406627    }
    407   return 0;
    408 }
     628 retpoint:
     629  SH_MUTEX_UNLOCK(mutex_watches);
     630  return retval;
     631}
     632
     633static void * sh_dummy_sret = NULL;
     634
     635char * sh_inotify_search_item(sh_watches * watches, int watch,
     636                              int * class, unsigned long * check_mask)
     637{
     638  sh_watch * item;
     639  char     * sret = NULL;
     640
     641  /* Take the address to keep gcc from putting it into a register.
     642   * Avoids the 'clobbered by longjmp' warning.
     643   */
     644  sh_dummy_sret = (void *) &sret;
     645
     646  SH_MUTEX_LOCK(mutex_watches);
     647  item = zAVLSearch(watches->list_of_watches, &watch);
     648
     649  if (item)
     650    {
     651      *class      = item->class;
     652      *check_mask = item->check_mask;
     653      sret = sh_util_strdup(item->file);
     654    }
     655  SH_MUTEX_UNLOCK(mutex_watches);
     656  return sret;
     657}
     658
     659static void * sh_dummy_litem = NULL;
    409660
    410661int sh_inotify_wait_for_change(char * filename, sh_watches * watches,
    411662                               int  * errnum, int waitsec)
    412663{
    413   sh_watch   * item;
    414   zAVLTree   * all_watches = (zAVLTree *)(watches->list_of_watches);
     664  sh_watch   * litem;
     665  sh_watch   * zitem;
    415666  int          ifd = sh_inotify_getfd();
    416  
     667
     668  /* Take the address to keep gcc from putting it into a register.
     669   * Avoids the 'clobbered by longjmp' warning.
     670   */
     671  sh_dummy_litem = (void*) &litem;
     672
    417673  *errnum = 0;
    418674
     
    421677  if (ifd >= 0)
    422678    {
     679      volatile ssize_t  i  = 0;
    423680      ssize_t len = -1;
    424       ssize_t  i  = 0;
    425681      int  flag = 0;
    426682      char buffer[1024];
     
    432688      if (filename)
    433689        {
    434           if (sh_inotify_add_watch(filename, watches, errnum) < 0)
     690          if (sh_inotify_add_watch(filename, watches, errnum, 0, 0) < 0)
    435691            {
    436692              retry_msleep(waitsec, 0);
     
    441697      /* -- Check dormant watches for reopening.
    442698       */
    443       for (item = sh_inotify_list_first(&listcursor, watches); item;
    444            item = sh_inotify_list_next(&listcursor, watches))
     699      SH_MUTEX_LOCK(mutex_list_dormant);
     700
     701      for (litem = sh_inotify_list_first(&listcursor, watches); litem;
     702           litem = sh_inotify_list_next(&listcursor, watches))
    445703        {
    446704        have_next:
    447           if (item->file && item->watch == -1)
     705          /* sh_inotify_list_del_cur may return NULL */
     706          if (litem && litem->file && litem->watch == -1)
    448707            {
    449               item->watch = inotify_add_watch (ifd, item->file,
    450                                                IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
    451               if (item->watch >= 0)
     708              litem->watch = inotify_add_watch (ifd, litem->file,
     709                                                SH_INOTIFY_FLAGS);
     710
     711              if (litem->watch >= 0)
    452712                {
    453                   zAVLInsert(all_watches, item);
    454                   item = sh_inotify_list_del_current(&listcursor, watches);
     713                  SH_MUTEX_LOCK(mutex_watches);
     714                  if (watches->list_of_watches)
     715                    zAVLInsert(watches->list_of_watches, litem);
     716                  SH_MUTEX_UNLOCK(mutex_watches);
     717                  litem = sh_inotify_list_del_cur(&listcursor, watches);
    455718                  goto have_next;
    456719                }
    457720            }
    458721        }
     722      SH_MUTEX_UNLOCK(mutex_list_dormant);
    459723
    460724
    461725      /* -- Blocking read on inotify file descriptor
    462726       */
    463       do {
    464         len = read (ifd, &buffer, sizeof(buffer));
    465       } while (len < 0 || errno == EINTR);
     727      sh_inotify_read(buffer, sizeof(buffer));
    466728
    467729      if (len > 0)
     
    475737            event = (struct inotify_event *) &buffer[i];
    476738
    477             item = zAVLSearch(all_watches, &(event->wd));
    478 
    479             if (item)
     739            SH_MUTEX_LOCK(mutex_watches);
     740            zitem = zAVLSearch(watches->list_of_watches, &(event->wd));
     741
     742            if (zitem)
    480743              {
    481744                if (event->mask & IN_MODIFY)
    482745                  {
    483                     item->flag |= SH_INOTIFY_MODIFY;
     746                    zitem->flag |= SH_INOTIFY_MODIFY;
    484747                    flag |= SH_INOTIFY_MODIFY;
    485748                  }
     
    488751                         event->mask & IN_MOVE_SELF   )
    489752                  {
    490                     item->flag |= SH_INOTIFY_REOPEN;
    491                     (void) inotify_rm_watch(ifd, item->watch);
    492                     zAVLDelete(all_watches, item);
    493                     sh_inotify_add_dormant(watches, item);
    494                     item->watch    = -1;
     753                    zitem->flag |= SH_INOTIFY_REOPEN;
     754                    (void) inotify_rm_watch(ifd, zitem->watch);
     755                    zAVLDelete(watches->list_of_watches, zitem);
     756                    sh_inotify_add_dormant(watches, zitem);
     757                    zitem->watch    = -1;
    495758                    flag |= SH_INOTIFY_REOPEN;
    496759                  }
    497760              }
     761            SH_MUTEX_UNLOCK(mutex_watches);
    498762           
    499763            i += sizeof (struct inotify_event) + event->len;
     
    527791}
    528792
     793
    529794/* !defined(HAVE_SYS_INOTIFY_H) */
    530795#else
     
    553818}
    554819
    555 int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum)
     820int sh_inotify_add_watch(char * filename, sh_watches * watches, int  * errnum,
     821                         int class, unsigned long check_mask)
    556822{
    557823  (void) filename;
    558824  (void) watches;
     825  (void) class;
     826  (void) check_mask;
    559827  *errnum = 0;
    560828  return 0;
    561829}
    562830
     831int sh_inotify_add_watch_later(char * filename, sh_watches * watches,
     832                               int  * errnum,
     833                               int class, unsigned long check_mask)
     834{
     835  (void) filename;
     836  (void) watches;
     837  (void) class;
     838  (void) check_mask;
     839  *errnum = 0;
     840  return 0;
     841}
     842
    563843#endif
     844
     845#ifdef SH_CUTEST
     846#include "CuTest.h"
     847void Test_inotify(CuTest *tc) {
     848#if defined(HAVE_SYS_INOTIFY_H) && (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
     849
     850  int          ret;
     851  sh_watches   twatch = SH_INOTIFY_INITIALIZER;
     852  sh_watch   * litem;
     853  sh_inotify_listCursor listcursor;
     854  char * p;
     855  int class;
     856  unsigned long check_mask;
     857  int           nrun = 0;
     858
     859  sh_watch aw1 = { -1, 0, 1, 1, "a1" };
     860  sh_watch aw2 = { -1, 0, 2, 1, "a2" };
     861  sh_watch aw3 = {  2, 0, 3, 1, "a3" };
     862  sh_watch aw4 = { -1, 0, 4, 1, "a4" };
     863  sh_watch aw5 = {  5, 0, 5, 1, "a5" };
     864
     865  do {
     866
     867    int          count = 0;
     868
     869    sh_watch * w1 = SH_ALLOC(sizeof(sh_watch));
     870    sh_watch * w2 = SH_ALLOC(sizeof(sh_watch));
     871    sh_watch * w3 = SH_ALLOC(sizeof(sh_watch));
     872    sh_watch * w4 = SH_ALLOC(sizeof(sh_watch));
     873    sh_watch * w5 = SH_ALLOC(sizeof(sh_watch));
     874
     875    memcpy(w1, &aw1, sizeof(sh_watch));
     876    w1->file = sh_util_strdup(aw1.file);
     877    memcpy(w2, &aw2, sizeof(sh_watch));
     878    w2->file = sh_util_strdup(aw2.file);
     879    memcpy(w3, &aw3, sizeof(sh_watch));
     880    w3->file = sh_util_strdup(aw3.file);
     881    memcpy(w4, &aw4, sizeof(sh_watch));
     882    w4->file = sh_util_strdup(aw4.file);
     883    memcpy(w5, &aw5, sizeof(sh_watch));
     884    w5->file = sh_util_strdup(aw5.file);
     885   
     886    ret = sh_inotify_add_dormant(&twatch, w1);
     887    CuAssertIntEquals(tc, ret, 0);
     888    ret = sh_inotify_add_dormant(&twatch, w2);
     889    CuAssertIntEquals(tc, ret, 0);
     890    ret = sh_inotify_add_dormant(&twatch, w3);
     891    CuAssertIntEquals(tc, ret, 0);
     892    ret = sh_inotify_add_dormant(&twatch, w4);
     893    CuAssertIntEquals(tc, ret, 0);
     894    ret = sh_inotify_add_dormant(&twatch, w5);
     895    CuAssertIntEquals(tc, ret, 0);
     896   
     897    /* -- Check dormant watches for reopening.
     898     */
     899    for (litem = sh_inotify_list_first(&listcursor, &twatch); litem;
     900         litem = sh_inotify_list_next(&listcursor, &twatch))
     901      {
     902      have_next:
     903       
     904        /* sh_inotify_list_del_cur may return NULL */
     905        if (litem)
     906          {
     907            ++count;
     908           
     909            if (litem->file && litem->watch == -1)
     910              {
     911               
     912                switch (litem->class)
     913                  {
     914                  case 1:
     915                    CuAssertStrEquals(tc, litem->file, "a1");
     916                    break;
     917                  case 2:
     918                    CuAssertStrEquals(tc, litem->file, "a2");
     919                    break;
     920                  case 3:
     921                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     922                    break;
     923                  case 4:
     924                    CuAssertStrEquals(tc, litem->file, "a4");
     925                    break;
     926                  case 5:
     927                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     928                    break;
     929                  default:
     930                    CuAssertStrEquals(tc, litem->file, "deadbeef");
     931                  }
     932                litem = sh_inotify_list_del_cur(&listcursor, &twatch);
     933                goto have_next;
     934              }
     935            switch (litem->class)
     936              {
     937              case 3:
     938                CuAssertStrEquals(tc, litem->file, "a3");
     939                break;
     940              case 5:
     941                CuAssertStrEquals(tc, litem->file, "a5");
     942                break;
     943              default:
     944                CuAssertStrEquals(tc, litem->file, "foobar");
     945              }     
     946          }
     947      }
     948   
     949    CuAssertIntEquals(tc, count, 5);
     950   
     951    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     952    CuAssertStrEquals(tc, p, "a5");
     953   
     954    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     955    CuAssertStrEquals(tc, p, "a3");
     956    CuAssertIntEquals(tc, class, 3);
     957   
     958    p = sh_inotify_pop_dormant(&twatch, &class, &check_mask);
     959    CuAssertTrue(tc, NULL == p);
     960    CuAssertTrue(tc, NULL == twatch.dormant_watches);
     961
     962    ++nrun;
     963
     964  } while (nrun < 100);
     965
     966#else
     967  (void) tc;
     968#endif
     969
     970  return;
     971}
     972#endif
  • trunk/src/sh_modules.c

    r294 r367  
    1818#include "sh_logmon.h"
    1919#include "sh_registry.h"
     20#include "sh_fInotify.h"
    2021
    2122sh_mtype modList[] = {
     
    173174#endif
    174175
     176#if defined(HAVE_SYS_INOTIFY_H)
     177  {
     178    N_("INOTIFY"),
     179    -1,
     180    SH_MODFL_NOTIMER,
     181    sh_fInotify_init,
     182    sh_fInotify_timer,
     183    sh_fInotify_run,
     184    sh_fInotify_cleanup,
     185    sh_fInotify_reconf,
     186
     187    N_("[Inotify]"),
     188    sh_fInotify_table,
     189    PTHREAD_MUTEX_INITIALIZER,
     190  },
     191#endif
     192
    175193  {
    176194    NULL,
  • trunk/src/sh_readconf.c

    r347 r367  
    3131#include "sh_error.h"
    3232#include "sh_extern.h"
     33#include "sh_unix.h"
    3334#include "sh_files.h"
    3435#include "sh_forward.h"
     
    4647#include "sh_tiger.h"
    4748#include "sh_tools.h"
    48 #include "sh_unix.h"
    4949#include "sh_utils.h"
    5050#include "sh_restrict.h"
  • trunk/src/sh_unix.c

    r362 r367  
    35853585#endif   
    35863586
     3587
     3588static void * sh_dummy_filename;
     3589static void * sh_dummy_tmp;
     3590static void * sh_dummy_tmp2;
     3591
    35873592int sh_unix_getinfo (int level, char * filename, file_type * theFile,
    35883593                     char * fileHash, int policy)
     
    35933598  struct stat   lbuf;
    35943599  struct stat   fbuf;
    3595   int           stat_return;
    3596   int           stat_errno = 0;
     3600  volatile int  stat_return;
     3601  volatile int  stat_errno = 0;
    35973602
    35983603  ShFileType    type;
     
    36023607
    36033608  char        * linknamebuf;
    3604   int           linksize;
     3609  volatile int  linksize;
    36053610
    36063611  extern int get_the_fd (SL_TICKET ticket);
    36073612
    3608   SL_TICKET     rval_open;
    3609   int           err_open = 0;
    3610 
    3611   int           fd;
    3612   int           fstat_return;
    3613   int           fstat_errno = 0;
    3614   int           try         = 0;
     3613  volatile SL_TICKET     rval_open;
     3614  volatile int           err_open = 0;
     3615
     3616  volatile int           fd;
     3617  volatile int           fstat_return;
     3618  volatile int           fstat_errno = 0;
     3619  volatile int           try         = 0;
    36153620
    36163621  sh_string   * content = NULL;
     
    36223627  char * path = NULL;
    36233628
    3624   int alert_timeout   = 120;
     3629  volatile int alert_timeout   = 120;
    36253630
    36263631  path = theFile->fullpath;
    36273632
    36283633  SL_ENTER(_("sh_unix_getinfo"));
     3634
     3635  /* Take the address to keep gcc from putting it into a register.
     3636   * Avoids the 'clobbered by longjmp' warning.
     3637   */
     3638  sh_dummy_filename = (void *) &filename;
     3639  sh_dummy_tmp      = (void *) &tmp;
     3640  sh_dummy_tmp2     = (void *) &tmp2;
    36293641
    36303642  /* --- Stat the file, and get checksum. ---
     
    36563668          if (stale)
    36573669            {
     3670              SH_MUTEX_LOCK(mutex_thread_nolog);
    36583671              sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, err_open, MSG_E_SUBGEN,
    36593672                              stale, _("sh_unix_getinfo_open"));
     3673              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    36603674            }
    36613675
     
    36883702    {
    36893703      tmp2 = sh_util_safe_name (theFile->fullpath);
     3704      SH_MUTEX_LOCK(mutex_thread_nolog);
    36903705      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_TOOLATE,
    36913706                       (long)(tend - tstart), tmp2);
     3707      SH_MUTEX_UNLOCK(mutex_thread_nolog);
    36923708      SH_FREE(tmp2);
    36933709    }
     
    37073723          if (stale)
    37083724            {
     3725              SH_MUTEX_LOCK(mutex_thread_nolog);
    37093726              sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, fstat_errno,
    37103727                              MSG_E_SUBGEN,
    37113728                              stale, _("sh_unix_getinfo_fstat"));
     3729              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    37123730            }
    37133731
     
    37423760            (void) sl_get_euid(&euid);
    37433761            tmp2 = sh_util_safe_name (theFile->fullpath);
     3762            SH_MUTEX_LOCK(mutex_thread_nolog);
    37443763            sh_error_handle (level, FIL__, __LINE__, stat_return, MSG_FI_STAT,
    37453764                             _("lstat"),
     
    37473766                             (long) euid,
    37483767                             tmp2);
     3768            SH_MUTEX_UNLOCK(mutex_thread_nolog);
    37493769            SH_FREE(tmp2);
    37503770          }
     
    38943914              (void) sl_get_euid(&euid);
    38953915
     3916              SH_MUTEX_LOCK(mutex_thread_nolog);
    38963917              sh_error_handle (level, FIL__, __LINE__, stat_return, MSG_FI_STAT,
    38973918                               _("fstat"),
     
    38993920                               (long) euid,
    39003921                               tmp2);
     3922              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    39013923            }
    39023924          else if (fd >= 0 && !S_ISREG(fbuf.st_mode))
    39033925            {
     3926              SH_MUTEX_LOCK(mutex_thread_nolog);
    39043927              sh_error_handle (level, FIL__, __LINE__, fstat_errno,
    39053928                               MSG_E_NOTREG, tmp2);
     3929              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    39063930            }
    39073931          else
     
    39113935              sl_strlcpy(errbuf, sl_error_string(rval_open), sizeof(errbuf));
    39123936              sh_error_message(err_open, errbuf2, sizeof(errbuf2));
     3937              SH_MUTEX_LOCK(mutex_thread_nolog);
    39133938              sh_error_handle (level, FIL__, __LINE__, err_open,
    39143939                               MSG_E_READ, errbuf, errbuf2, tmp2);
     3940              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    39153941            }
    39163942          SH_FREE(tmp2);
     
    40044030    if (policy == SH_LEVEL_ALLIGNORE)
    40054031      {
     4032        SH_MUTEX_LOCK(mutex_thread_nolog);
    40064033        sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, ENOENT,
    40074034                         MSG_FI_NOGRP,
    40084035                         (long) buf.st_gid, tmp2);
     4036        SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40094037      }
    40104038    else
    40114039      {
     4040        SH_MUTEX_LOCK(mutex_thread_nolog);
    40124041        sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, ENOENT,
    40134042                         MSG_FI_NOGRP,
    40144043                         (long) buf.st_gid, tmp2);
     4044        SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40154045      }
    40164046    SH_FREE(tmp2);
     
    40254055    if (policy == SH_LEVEL_ALLIGNORE)
    40264056      {
     4057        SH_MUTEX_LOCK(mutex_thread_nolog);
    40274058        sh_error_handle (SH_ERR_ALL, FIL__, __LINE__, ENOENT,
    40284059                         MSG_FI_NOUSR,
    40294060                         (long) buf.st_uid, tmp2);
     4061        SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40304062      }
    40314063    else
    40324064      {
     4065        SH_MUTEX_LOCK(mutex_thread_nolog);
    40334066        sh_error_handle (ShDFLevel[SH_ERR_T_NAME], FIL__, __LINE__, ENOENT,
    40344067                         MSG_FI_NOUSR,
    40354068                         (long) buf.st_uid, tmp2);
     4069        SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40364070      }
    40374071    SH_FREE(tmp2);
     
    40464080                                theFile->fullpath : filename);
    40474081      (void) sh_unix_time(theFile->mtime, timestr, sizeof(timestr));
     4082      SH_MUTEX_LOCK(mutex_thread_nolog);
    40484083      sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_LIST,
    40494084                       theFile->c_mode,
     
    40544089                       timestr,
    40554090                       tmp2);
     4091      SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40564092      SH_FREE(tmp2);
    40574093    }
     
    40764112          linksize = errno;
    40774113          tmp2 = sh_util_safe_name (theFile->fullpath);
     4114          SH_MUTEX_LOCK(mutex_thread_nolog);
    40784115          sh_error_handle (level, FIL__, __LINE__, linksize, MSG_FI_RDLNK,
    40794116                           sh_error_message (linksize, errbuf, sizeof(errbuf)), tmp2);
     4117          SH_MUTEX_UNLOCK(mutex_thread_nolog);
    40804118          SH_FREE(tmp2);
    40814119          SH_FREE(linknamebuf);
     
    41304168
    41314169              (void) sl_get_euid(&euid);
     4170              SH_MUTEX_LOCK(mutex_thread_nolog);
    41324171              sh_error_handle (level, FIL__, __LINE__, stat_return,
    41334172                               MSG_FI_STAT,
     
    41364175                               (long) euid,
    41374176                               tmp2);
     4177              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    41384178            }
    41394179          else
     
    41414181              /* a dangling link -- everybody seems to have plenty of them
    41424182               */
     4183              SH_MUTEX_LOCK(mutex_thread_nolog);
    41434184              sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_DLNK,
    41444185                               tmp, tmp2);
     4186              SH_MUTEX_UNLOCK(mutex_thread_nolog);
    41454187            }
    41464188          theFile->linkisok = BAD;
     
    41754217        {
    41764218          tmp2 = sh_util_safe_name (linknamebuf);     
     4219          SH_MUTEX_LOCK(mutex_thread_nolog);
    41774220          sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_FI_LLNK,
    41784221                           theFile->link_c_mode, tmp2);
     4222          SH_MUTEX_UNLOCK(mutex_thread_nolog);
    41794223          SH_FREE(tmp2);
    41804224        }
     
    42134257                                _("compressed file too large (%lu bytes)"),
    42144258                                clen);
     4259                    SH_MUTEX_LOCK(mutex_thread_nolog);
    42154260                    sh_error_handle (SH_ERR_WARN, FIL__, __LINE__, -1,
    42164261                                     MSG_E_SUBGPATH, tmsg,
    42174262                                     _("sh_unix_getinfo"), tpath);
     4263                    SH_MUTEX_UNLOCK(mutex_thread_nolog);
    42184264                    SH_FREE(tpath);
    42194265                  }
Note: See TracChangeset for help on using the changeset viewer.