NeoMutt  2022-04-29-70-g0c028c
Teaching an old dog new tricks
DOXYGEN
monitor.c File Reference

Monitor files for changes. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "monitor.h"
#include "index/lib.h"
#include <fcntl.h>
+ Include dependency graph for monitor.c:

Go to the source code of this file.

Data Structures

struct  Monitor
 A watch on a file. More...
 
struct  MonitorInfo
 Information about a monitored file. More...
 

Macros

#define INOTIFY_MASK_DIR   (IN_MOVED_TO | IN_ATTRIB | IN_CLOSE_WRITE | IN_ISDIR)
 
#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE
 
#define EVENT_BUFLEN   MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1)
 

Enumerations

enum  ResolveResult {
  RESOLVE_RES_FAIL_NOMAILBOX = -3 , RESOLVE_RES_FAIL_NOTYPE = -2 , RESOLVE_RES_FAIL_STAT = -1 , RESOLVE_RES_OK_NOTEXISTING = 0 ,
  RESOLVE_RES_OK_EXISTING = 1
}
 Results for the Monitor functions. More...
 

Functions

static void mutt_poll_fd_add (int fd, short events)
 Add a file to the watch list. More...
 
static int mutt_poll_fd_remove (int fd)
 Remove a file from the watch list. More...
 
static int monitor_init (void)
 Set up file monitoring. More...
 
static void monitor_check_free (void)
 Close down file monitoring. More...
 
static struct Monitormonitor_new (struct MonitorInfo *info, int descriptor)
 Create a new file monitor. More...
 
static void monitor_info_init (struct MonitorInfo *info)
 Set up a file monitor. More...
 
static void monitor_info_free (struct MonitorInfo *info)
 Shutdown a file monitor. More...
 
static void monitor_delete (struct Monitor *monitor)
 Free a file monitor. More...
 
static int monitor_handle_ignore (int desc)
 Listen for when a backup file is closed. More...
 
static enum ResolveResult monitor_resolve (struct MonitorInfo *info, struct Mailbox *m)
 Get the monitor for a mailbox. More...
 
int mutt_monitor_poll (void)
 Check for filesystem changes. More...
 
int mutt_monitor_add (struct Mailbox *m)
 Add a watch for a mailbox. More...
 
int mutt_monitor_remove (struct Mailbox *m)
 Remove a watch for a mailbox. More...
 

Variables

bool MonitorFilesChanged = false
 true after a monitored file has changed More...
 
bool MonitorContextChanged = false
 true after the current mailbox has changed More...
 
static int INotifyFd = -1
 
static struct MonitorMonitor = NULL
 
static size_t PollFdsCount = 0
 
static size_t PollFdsLen = 0
 
static struct pollfd * PollFds = NULL
 
static int MonitorContextDescriptor = -1
 

Detailed Description

Monitor files for changes.

Authors
  • Gero Treuer
  • R Primus

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file monitor.c.

Macro Definition Documentation

◆ INOTIFY_MASK_DIR

#define INOTIFY_MASK_DIR   (IN_MOVED_TO | IN_ATTRIB | IN_CLOSE_WRITE | IN_ISDIR)

Definition at line 61 of file monitor.c.

◆ INOTIFY_MASK_FILE

#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE

Definition at line 62 of file monitor.c.

◆ EVENT_BUFLEN

#define EVENT_BUFLEN   MAX(4096, sizeof(struct inotify_event) + NAME_MAX + 1)

Definition at line 64 of file monitor.c.

Enumeration Type Documentation

◆ ResolveResult

Results for the Monitor functions.

Enumerator
RESOLVE_RES_FAIL_NOMAILBOX 

No Mailbox to work on.

RESOLVE_RES_FAIL_NOTYPE 

Can't identify Mailbox type.

RESOLVE_RES_FAIL_STAT 

Can't stat() the Mailbox file.

RESOLVE_RES_OK_NOTEXISTING 

File exists, no monitor is attached.

RESOLVE_RES_OK_EXISTING 

File exists, monitor is already attached.

Definition at line 69 of file monitor.c.

70 {
76 };
@ RESOLVE_RES_FAIL_NOTYPE
Can't identify Mailbox type.
Definition: monitor.c:72
@ RESOLVE_RES_FAIL_STAT
Can't stat() the Mailbox file.
Definition: monitor.c:73
@ RESOLVE_RES_OK_NOTEXISTING
File exists, no monitor is attached.
Definition: monitor.c:74
@ RESOLVE_RES_FAIL_NOMAILBOX
No Mailbox to work on.
Definition: monitor.c:71
@ RESOLVE_RES_OK_EXISTING
File exists, monitor is already attached.
Definition: monitor.c:75

Function Documentation

◆ mutt_poll_fd_add()

static void mutt_poll_fd_add ( int  fd,
short  events 
)
static

Add a file to the watch list.

Parameters
fdFile to watch
eventsEvents to listen for, e.g. POLLIN

Definition at line 110 of file monitor.c.

111 {
112  int i = 0;
113  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
114  ; // do nothing
115 
116  if (i == PollFdsCount)
117  {
118  if (PollFdsCount == PollFdsLen)
119  {
120  PollFdsLen += 2;
121  mutt_mem_realloc(&PollFds, PollFdsLen * sizeof(struct pollfd));
122  }
123  PollFdsCount++;
124  PollFds[i].fd = fd;
125  PollFds[i].events = events;
126  }
127  else
128  PollFds[i].events |= events;
129 }
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static size_t PollFdsCount
Definition: monitor.c:55
static size_t PollFdsLen
Definition: monitor.c:56
static struct pollfd * PollFds
Definition: monitor.c:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_poll_fd_remove()

static int mutt_poll_fd_remove ( int  fd)
static

Remove a file from the watch list.

Parameters
fdFile to remove
Return values
0Success
-1Error

Definition at line 137 of file monitor.c.

138 {
139  int i = 0;
140  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
141  ; // do nothing
142 
143  if (i == PollFdsCount)
144  return -1;
145  int d = PollFdsCount - i - 1;
146  if (d != 0)
147  memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd));
148  PollFdsCount--;
149  return 0;
150 }
+ Here is the caller graph for this function:

◆ monitor_init()

static int monitor_init ( void  )
static

Set up file monitoring.

Return values
0Success
-1Error

Definition at line 157 of file monitor.c.

158 {
159  if (INotifyFd != -1)
160  return 0;
161 
162 #ifdef HAVE_INOTIFY_INIT1
163  INotifyFd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
164  if (INotifyFd == -1)
165  {
166  mutt_debug(LL_DEBUG2, "inotify_init1 failed, errno=%d %s\n", errno, strerror(errno));
167  return -1;
168  }
169 #else
170  INotifyFd = inotify_init();
171  if (INotifyFd == -1)
172  {
173  mutt_debug(LL_DEBUG2, "monitor: inotify_init failed, errno=%d %s\n", errno,
174  strerror(errno));
175  return -1;
176  }
177  fcntl(INotifyFd, F_SETFL, O_NONBLOCK);
178  fcntl(INotifyFd, F_SETFD, FD_CLOEXEC);
179 #endif
180  mutt_poll_fd_add(0, POLLIN);
181  mutt_poll_fd_add(INotifyFd, POLLIN);
182 
183  return 0;
184 }
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
static int INotifyFd
Definition: monitor.c:53
static void mutt_poll_fd_add(int fd, short events)
Add a file to the watch list.
Definition: monitor.c:110
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_check_free()

static void monitor_check_free ( void  )
static

Close down file monitoring.

Definition at line 189 of file monitor.c.

190 {
191  if (!Monitor && (INotifyFd != -1))
192  {
194  close(INotifyFd);
195  INotifyFd = -1;
196  MonitorFilesChanged = false;
197  }
198 }
static int mutt_poll_fd_remove(int fd)
Remove a file from the watch list.
Definition: monitor.c:137
bool MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:50
A watch on a file.
Definition: monitor.c:82
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_new()

static struct Monitor* monitor_new ( struct MonitorInfo info,
int  descriptor 
)
static

Create a new file monitor.

Parameters
infoDetails of file to monitor
descriptorWatch descriptor
Return values
ptrNewly allocated Monitor

Definition at line 206 of file monitor.c.

207 {
208  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
209  monitor->type = info->type;
210  monitor->st_dev = info->st_dev;
211  monitor->st_ino = info->st_ino;
212  monitor->desc = descriptor;
213  monitor->next = Monitor;
214  if (info->type == MUTT_MH)
215  monitor->mh_backup_path = mutt_str_dup(info->path);
216 
217  Monitor = monitor;
218 
219  return monitor;
220 }
@ MUTT_MH
'MH' Mailbox type
Definition: mailbox.h:47
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static struct Monitor * Monitor
Definition: monitor.c:54
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
dev_t st_dev
Definition: monitor.c:99
enum MailboxType type
Definition: monitor.c:96
ino_t st_ino
Definition: monitor.c:100
const char * path
Definition: monitor.c:98
struct Monitor * next
Linked list.
Definition: monitor.c:83
ino_t st_ino
Definition: monitor.c:86
dev_t st_dev
Definition: monitor.c:85
int desc
Definition: monitor.c:88
enum MailboxType type
Definition: monitor.c:87
char * mh_backup_path
Definition: monitor.c:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_info_init()

static void monitor_info_init ( struct MonitorInfo info)
static

Set up a file monitor.

Parameters
infoMonitor to initialise

Definition at line 226 of file monitor.c.

227 {
228  memset(info, 0, sizeof(*info));
229 }
+ Here is the caller graph for this function:

◆ monitor_info_free()

static void monitor_info_free ( struct MonitorInfo info)
static

Shutdown a file monitor.

Parameters
infoMonitor to shut down

Definition at line 235 of file monitor.c.

236 {
238 }
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
struct Buffer path_buf
access via path only (maybe not initialized)
Definition: monitor.c:102
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_delete()

static void monitor_delete ( struct Monitor monitor)
static

Free a file monitor.

Parameters
monitorMonitor to free

Definition at line 244 of file monitor.c.

245 {
246  if (!monitor)
247  return;
248 
249  struct Monitor **ptr = &Monitor;
250 
251  while (true)
252  {
253  if (!*ptr)
254  return;
255  if (*ptr == monitor)
256  break;
257  ptr = &(*ptr)->next;
258  }
259 
260  FREE(&monitor->mh_backup_path);
261  monitor = monitor->next;
262  FREE(ptr);
263  *ptr = monitor;
264 }
#define FREE(x)
Definition: memory.h:40
+ Here is the caller graph for this function:

◆ monitor_handle_ignore()

static int monitor_handle_ignore ( int  desc)
static

Listen for when a backup file is closed.

Parameters
descWatch descriptor
Return values
>=0New descriptor
-1Error

Definition at line 272 of file monitor.c.

273 {
274  int new_desc = -1;
275  struct Monitor *iter = Monitor;
276  struct stat st = { 0 };
277 
278  while (iter && (iter->desc != desc))
279  iter = iter->next;
280 
281  if (iter)
282  {
283  if ((iter->type == MUTT_MH) && (stat(iter->mh_backup_path, &st) == 0))
284  {
285  new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE);
286  if (new_desc == -1)
287  {
288  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
289  iter->mh_backup_path, errno, strerror(errno));
290  }
291  else
292  {
293  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n",
294  desc, iter->mh_backup_path);
295  iter->st_dev = st.st_dev;
296  iter->st_ino = st.st_ino;
297  iter->desc = new_desc;
298  }
299  }
300  else
301  {
302  mutt_debug(LL_DEBUG3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc);
303  }
304 
305  if (MonitorContextDescriptor == desc)
306  MonitorContextDescriptor = new_desc;
307 
308  if (new_desc == -1)
309  {
310  monitor_delete(iter);
312  }
313  }
314 
315  return new_desc;
316 }
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:244
static int MonitorContextDescriptor
Definition: monitor.c:59
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:189
#define INOTIFY_MASK_FILE
Definition: monitor.c:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ monitor_resolve()

static enum ResolveResult monitor_resolve ( struct MonitorInfo info,
struct Mailbox m 
)
static

Get the monitor for a mailbox.

Parameters
[out]infoDetails of the mailbox's monitor
[in]mMailbox
Return values
>=0mailbox is valid and locally accessible: 0: no monitor / 1: preexisting monitor
-3no mailbox (MonitorInfo: no fields set)
-2type not set
-1stat() failed (see errno; MonitorInfo fields: type, is_dir, path)

If m is NULL, try to get the current mailbox from the Index.

Definition at line 272 of file monitor.c.

331 {
332  char *fmt = NULL;
333  struct stat st = { 0 };
334 
335  struct Mailbox *m_cur = get_current_mailbox();
336  if (m)
337  {
338  info->type = m->type;
339  info->path = m->realpath;
340  }
341  else if (m_cur)
342  {
343  info->type = m_cur->type;
344  info->path = m_cur->realpath;
345  }
346  else
347  {
349  }
350 
351  if (info->type == MUTT_UNKNOWN)
352  {
354  }
355  else if (info->type == MUTT_MAILDIR)
356  {
357  info->is_dir = true;
358  fmt = "%s/new";
359  }
360  else
361  {
362  info->is_dir = false;
363  if (info->type == MUTT_MH)
364  fmt = "%s/.mh_sequences";
365  }
366  if (fmt)
367  {
368  mutt_buffer_printf(&info->path_buf, fmt, info->path);
369  info->path = mutt_buffer_string(&info->path_buf);
370  }
371  if (stat(info->path, &st) != 0)
372  return RESOLVE_RES_FAIL_STAT;
373 
374  struct Monitor *iter = Monitor;
375  while (iter && ((iter->st_ino != st.st_ino) || (iter->st_dev != st.st_dev)))
376  iter = iter->next;
377 
378  info->st_dev = st.st_dev;
379  info->st_ino = st.st_ino;
380  info->monitor = iter;
381 
383 }
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:603
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:48
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
struct Monitor * monitor
Definition: monitor.c:101
bool is_dir
Definition: monitor.c:97
+ Here is the caller graph for this function:

◆ mutt_monitor_poll()

int mutt_monitor_poll ( void  )

Check for filesystem changes.

Return values
-3unknown/unexpected events: poll timeout / fds not handled by us
-2monitor detected changes, no STDIN input
-1error (see errno)
0(1) input ready from STDIN, or (2) monitoring inactive -> no poll()

Wait for I/O ready file descriptors or signals.

MonitorFilesChanged also reflects changes to monitored files.

Only STDIN and INotify file handles currently expected/supported. More would ask for common infrastructure (sockets?).

Definition at line 399 of file monitor.c.

400 {
401  int rc = 0;
402  char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event))));
403 
404  MonitorFilesChanged = false;
405 
406  if (INotifyFd != -1)
407  {
408  int fds = poll(PollFds, PollFdsCount, MuttGetchTimeout);
409 
410  if (fds == -1)
411  {
412  rc = -1;
413  if (errno != EINTR)
414  {
415  mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
416  }
417  }
418  else
419  {
420  bool input_ready = false;
421  for (int i = 0; fds && (i < PollFdsCount); i++)
422  {
423  if (PollFds[i].revents)
424  {
425  fds--;
426  if (PollFds[i].fd == 0)
427  {
428  input_ready = true;
429  }
430  else if (PollFds[i].fd == INotifyFd)
431  {
432  MonitorFilesChanged = true;
433  mutt_debug(LL_DEBUG3, "file change(s) detected\n");
434  char *ptr = buf;
435  const struct inotify_event *event = NULL;
436 
437  while (true)
438  {
439  int len = read(INotifyFd, buf, sizeof(buf));
440  if (len == -1)
441  {
442  if (errno != EAGAIN)
443  {
444  mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
445  errno, strerror(errno));
446  }
447  break;
448  }
449 
450  while (ptr < (buf + len))
451  {
452  event = (const struct inotify_event *) ptr;
453  mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
454  event->wd, event->mask);
455  if (event->mask & IN_IGNORED)
456  monitor_handle_ignore(event->wd);
457  else if (event->wd == MonitorContextDescriptor)
458  MonitorContextChanged = true;
459  ptr += sizeof(struct inotify_event) + event->len;
460  }
461  }
462  }
463  }
464  }
465  if (!input_ready)
466  rc = MonitorFilesChanged ? -2 : -3;
467  }
468  }
469 
470  return rc;
471 }
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:125
static int monitor_handle_ignore(int desc)
Listen for when a backup file is closed.
Definition: monitor.c:272
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:51
#define EVENT_BUFLEN
Definition: monitor.c:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_add()

int mutt_monitor_add ( struct Mailbox m)

Add a watch for a mailbox.

Parameters
mMailbox to watch
Return values
0success: new or already existing monitor
-1failed: no mailbox, inaccessible file, create monitor/watcher failed

If m is NULL, try to get the current mailbox from the Index.

Definition at line 481 of file monitor.c.

482 {
483  struct MonitorInfo info;
484  monitor_info_init(&info);
485 
486  int rc = 0;
487  enum ResolveResult desc = monitor_resolve(&info, m);
488  if (desc != RESOLVE_RES_OK_NOTEXISTING)
489  {
490  if (!m && (desc == RESOLVE_RES_OK_EXISTING))
491  MonitorContextDescriptor = info.monitor->desc;
492  rc = (desc == RESOLVE_RES_OK_EXISTING) ? 0 : -1;
493  goto cleanup;
494  }
495 
496  uint32_t mask = info.is_dir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
497  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
498  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
499  {
500  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
501  info.path, errno, strerror(errno));
502  rc = -1;
503  goto cleanup;
504  }
505 
506  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
507  if (!m)
509 
510  monitor_new(&info, desc);
511 
512 cleanup:
513  monitor_info_free(&info);
514  return rc;
515 }
#define INOTIFY_MASK_DIR
Definition: monitor.c:61
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:330
ResolveResult
Results for the Monitor functions.
Definition: monitor.c:70
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:157
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:226
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:206
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:235
Information about a monitored file.
Definition: monitor.c:95
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_monitor_remove()

int mutt_monitor_remove ( struct Mailbox m)

Remove a watch for a mailbox.

Parameters
mMailbox
Return values
0monitor removed (not shared)
1monitor not removed (shared)
2no monitor

If m is NULL, try to get the current mailbox from the Index.

Definition at line 526 of file monitor.c.

527 {
528  struct MonitorInfo info, info2;
529  int rc = 0;
530 
531  monitor_info_init(&info);
532  monitor_info_init(&info2);
533 
534  if (!m)
535  {
537  MonitorContextChanged = false;
538  }
539 
540  if (monitor_resolve(&info, m) != RESOLVE_RES_OK_EXISTING)
541  {
542  rc = 2;
543  goto cleanup;
544  }
545 
546  struct Mailbox *m_cur = get_current_mailbox();
547  if (m_cur)
548  {
549  if (m)
550  {
551  if ((monitor_resolve(&info2, NULL) == RESOLVE_RES_OK_EXISTING) &&
552  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
553  {
554  rc = 1;
555  goto cleanup;
556  }
557  }
558  else
559  {
560  if (mailbox_find(m_cur->realpath))
561  {
562  rc = 1;
563  goto cleanup;
564  }
565  }
566  }
567 
568  inotify_rm_watch(info.monitor->desc, INotifyFd);
569  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
570  info.monitor->desc);
571 
572  monitor_delete(info.monitor);
574 
575 cleanup:
576  monitor_info_free(&info);
577  monitor_info_free(&info2);
578  return rc;
579 }
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:139
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ MonitorFilesChanged

bool MonitorFilesChanged = false

true after a monitored file has changed

Definition at line 50 of file monitor.c.

◆ MonitorContextChanged

bool MonitorContextChanged = false

true after the current mailbox has changed

Definition at line 51 of file monitor.c.

◆ INotifyFd

int INotifyFd = -1
static

Definition at line 53 of file monitor.c.

◆ Monitor

struct Monitor* Monitor = NULL
static

Definition at line 54 of file monitor.c.

◆ PollFdsCount

size_t PollFdsCount = 0
static

Definition at line 55 of file monitor.c.

◆ PollFdsLen

size_t PollFdsLen = 0
static

Definition at line 56 of file monitor.c.

◆ PollFds

struct pollfd* PollFds = NULL
static

Definition at line 57 of file monitor.c.

◆ MonitorContextDescriptor

int MonitorContextDescriptor = -1
static

Definition at line 59 of file monitor.c.