NeoMutt  2018-07-16 +1783-b00bd9
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/mutt.h"
#include "monitor.h"
#include "context.h"
#include "curs_lib.h"
#include "globals.h"
#include "mailbox.h"
#include "mutt_curses.h"
#include "mx.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)
 
#define RESOLVERES_FAIL_NOMAILBOX   -3
 
#define RESOLVERES_FAIL_NOMAGIC   -2
 
#define RESOLVERES_FAIL_STAT   -1
 
#define RESOLVERES_OK_NOTEXISTING   0
 
#define RESOLVERES_OK_EXISTING   1
 

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 int 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

int MonitorFilesChanged = 0
 true after a monitored file has changed More...
 
int MonitorContextChanged = 0
 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

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

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

Definition at line 60 of file monitor.c.

#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE

Definition at line 61 of file monitor.c.

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

Definition at line 63 of file monitor.c.

#define RESOLVERES_FAIL_NOMAILBOX   -3

Definition at line 65 of file monitor.c.

#define RESOLVERES_FAIL_NOMAGIC   -2

Definition at line 66 of file monitor.c.

#define RESOLVERES_FAIL_STAT   -1

Definition at line 67 of file monitor.c.

#define RESOLVERES_OK_NOTEXISTING   0

Definition at line 68 of file monitor.c.

#define RESOLVERES_OK_EXISTING   1

Definition at line 69 of file monitor.c.

Function Documentation

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 103 of file monitor.c.

104 {
105  int i = 0;
106  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
107  ;
108 
109  if (i == PollFdsCount)
110  {
111  if (PollFdsCount == PollFdsLen)
112  {
113  PollFdsLen += 2;
114  mutt_mem_realloc(&PollFds, PollFdsLen * sizeof(struct pollfd));
115  }
116  PollFdsCount++;
117  PollFds[i].fd = fd;
118  PollFds[i].events = events;
119  }
120  else
121  PollFds[i].events |= events;
122 }
static size_t PollFdsLen
Definition: monitor.c:55
static struct pollfd * PollFds
Definition: monitor.c:56
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:121
static size_t PollFdsCount
Definition: monitor.c:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 130 of file monitor.c.

131 {
132  int i = 0;
133  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
134  ;
135  if (i == PollFdsCount)
136  return -1;
137  int d = PollFdsCount - i - 1;
138  if (d != 0)
139  memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd));
140  PollFdsCount--;
141  return 0;
142 }
static struct pollfd * PollFds
Definition: monitor.c:56
static size_t PollFdsCount
Definition: monitor.c:54

+ Here is the caller graph for this function:

static int monitor_init ( void  )
static

Set up file monitoring.

Return values
0Success
-1Error

Definition at line 149 of file monitor.c.

150 {
151  if (INotifyFd == -1)
152  {
153  INotifyFd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
154  if (INotifyFd == -1)
155  {
156  mutt_debug(LL_DEBUG2, "inotify_init1 failed, errno=%d %s\n", errno, strerror(errno));
157  return -1;
158  }
159  mutt_poll_fd_add(0, POLLIN);
160  mutt_poll_fd_add(INotifyFd, POLLIN);
161  }
162  return 0;
163 }
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
static void mutt_poll_fd_add(int fd, short events)
Add a file to the watch list.
Definition: monitor.c:103
#define mutt_debug(LEVEL,...)
Definition: logging.h:80

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void monitor_check_free ( void  )
static

Close down file monitoring.

Definition at line 168 of file monitor.c.

169 {
170  if (!Monitor && (INotifyFd != -1))
171  {
173  close(INotifyFd);
174  INotifyFd = -1;
176  }
177 }
A watch on a file.
Definition: monitor.c:74
static int INotifyFd
Definition: monitor.c:52
int MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:49
static int mutt_poll_fd_remove(int fd)
Remove a file from the watch list.
Definition: monitor.c:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 185 of file monitor.c.

186 {
187  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
188  monitor->magic = info->magic;
189  monitor->st_dev = info->st_dev;
190  monitor->st_ino = info->st_ino;
191  monitor->desc = descriptor;
192  monitor->next = Monitor;
193  if (info->magic == MUTT_MH)
194  monitor->mh_backup_path = mutt_str_strdup(info->path);
195 
196  Monitor = monitor;
197 
198  return monitor;
199 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
enum MailboxType magic
Definition: monitor.c:89
ino_t st_ino
Definition: monitor.c:79
int desc
Definition: monitor.c:81
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
char * mh_backup_path
Definition: monitor.c:77
enum MailboxType magic
Definition: monitor.c:80
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
const char * path
Definition: monitor.c:91
&#39;MH&#39; Mailbox type
Definition: magic.h:39
dev_t st_dev
Definition: monitor.c:92
ino_t st_ino
Definition: monitor.c:93

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void monitor_info_init ( struct MonitorInfo info)
static

Set up a file monitor.

Parameters
infoMonitor to initialise

Definition at line 205 of file monitor.c.

206 {
207  memset(info, 0, sizeof(*info));
208 }

+ Here is the caller graph for this function:

static void monitor_info_free ( struct MonitorInfo info)
static

Shutdown a file monitor.

Parameters
infoMonitor to shut down

Definition at line 214 of file monitor.c.

215 {
216  mutt_buffer_free(&info->path_buf);
217 }
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:138
struct Buffer * path_buf
Definition: monitor.c:95

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void monitor_delete ( struct Monitor monitor)
static

Free a file monitor.

Parameters
monitorMonitor to free

Definition at line 223 of file monitor.c.

224 {
225  if (!monitor)
226  return;
227 
228  struct Monitor **ptr = &Monitor;
229 
230  while (true)
231  {
232  if (!*ptr)
233  return;
234  if (*ptr == monitor)
235  break;
236  ptr = &(*ptr)->next;
237  }
238 
239  FREE(&monitor->mh_backup_path);
240  monitor = monitor->next;
241  FREE(ptr);
242  *ptr = monitor;
243 }
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
char * mh_backup_path
Definition: monitor.c:77
static struct Monitor * Monitor
Definition: monitor.c:53
#define FREE(x)
Definition: memory.h:40

+ Here is the caller graph for this function:

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 251 of file monitor.c.

252 {
253  int new_desc = -1;
254  struct Monitor *iter = Monitor;
255  struct stat sb;
256 
257  while (iter && (iter->desc != desc))
258  iter = iter->next;
259 
260  if (iter)
261  {
262  if ((iter->magic == MUTT_MH) && (stat(iter->mh_backup_path, &sb) == 0))
263  {
264  new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE);
265  if (new_desc == -1)
266  {
267  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
268  iter->mh_backup_path, errno, strerror(errno));
269  }
270  else
271  {
272  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n",
273  desc, iter->mh_backup_path);
274  iter->st_dev = sb.st_dev;
275  iter->st_ino = sb.st_ino;
276  iter->desc = new_desc;
277  }
278  }
279  else
280  {
281  mutt_debug(LL_DEBUG3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc);
282  }
283 
284  if (MonitorContextDescriptor == desc)
285  MonitorContextDescriptor = new_desc;
286 
287  if (new_desc == -1)
288  {
289  monitor_delete(iter);
291  }
292  }
293 
294  return new_desc;
295 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
ino_t st_ino
Definition: monitor.c:79
int desc
Definition: monitor.c:81
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:223
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
char * mh_backup_path
Definition: monitor.c:77
enum MailboxType magic
Definition: monitor.c:80
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
&#39;MH&#39; Mailbox type
Definition: magic.h:39
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:168
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
Log at debug level 3.
Definition: logging.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int 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)
-2magic not set
-1stat() failed (see errno; MonitorInfo fields: magic, isdir, path)

If m is NULL, the current mailbox (Context) is used.

Definition at line 309 of file monitor.c.

310 {
311  struct Monitor *iter;
312  char *fmt = NULL;
313  struct stat sb;
314 
315  if (m)
316  {
317  info->magic = m->magic;
318  info->path = m->realpath;
319  }
320  else if (Context)
321  {
322  info->magic = Context->mailbox->magic;
323  info->path = Context->mailbox->realpath;
324  }
325  else
326  {
328  }
329 
330  if (info->magic == MUTT_UNKNOWN)
331  {
333  }
334  else if (info->magic == MUTT_MAILDIR)
335  {
336  info->isdir = 1;
337  fmt = "%s/new";
338  }
339  else
340  {
341  info->isdir = 0;
342  if (info->magic == MUTT_MH)
343  fmt = "%s/.mh_sequences";
344  }
345 
346  if (fmt)
347  {
348  if (!info->path_buf)
349  info->path_buf = mutt_buffer_new();
350  mutt_buffer_printf(info->path_buf, fmt, info->path);
351  info->path = mutt_b2s(info->path_buf);
352  }
353  if (stat(info->path, &sb) != 0)
354  return RESOLVERES_FAIL_STAT;
355 
356  iter = Monitor;
357  while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev)))
358  iter = iter->next;
359 
360  info->st_dev = sb.st_dev;
361  info->st_ino = sb.st_ino;
362  info->monitor = iter;
363 
365 }
The "current" mailbox.
Definition: context.h:38
enum MailboxType magic
Definition: monitor.c:89
ino_t st_ino
Definition: monitor.c:79
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
&#39;Maildir&#39; Mailbox type
Definition: magic.h:40
short isdir
Definition: monitor.c:90
char * realpath
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:86
A watch on a file.
Definition: monitor.c:74
struct Monitor * next
Definition: monitor.c:76
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
struct Mailbox * mailbox
Definition: context.h:52
enum MailboxType magic
mailbox type
Definition: mailbox.h:105
struct Monitor * monitor
Definition: monitor.c:94
#define mutt_b2s(buf)
Definition: buffer.h:42
#define RESOLVERES_FAIL_NOMAGIC
Definition: monitor.c:66
static struct Monitor * Monitor
Definition: monitor.c:53
dev_t st_dev
Definition: monitor.c:78
struct Buffer * mutt_buffer_new(void)
Create and initialise a Buffer.
Definition: buffer.c:52
Mailbox wasn&#39;t recognised.
Definition: magic.h:36
const char * path
Definition: monitor.c:91
&#39;MH&#39; Mailbox type
Definition: magic.h:39
dev_t st_dev
Definition: monitor.c:92
struct Buffer * path_buf
Definition: monitor.c:95
#define RESOLVERES_FAIL_NOMAILBOX
Definition: monitor.c:65
#define RESOLVERES_FAIL_STAT
Definition: monitor.c:67
ino_t st_ino
Definition: monitor.c:93
#define RESOLVERES_OK_NOTEXISTING
Definition: monitor.c:68

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 381 of file monitor.c.

382 {
383  int rc = 0;
384  char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event))));
385 
387 
388  if (INotifyFd != -1)
389  {
390  int fds = poll(PollFds, PollFdsLen, MuttGetchTimeout);
391 
392  if (fds == -1)
393  {
394  rc = -1;
395  if (errno != EINTR)
396  {
397  mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
398  }
399  }
400  else
401  {
402  bool input_ready = false;
403  for (int i = 0; fds && (i < PollFdsCount); i++)
404  {
405  if (PollFds[i].revents)
406  {
407  fds--;
408  if (PollFds[i].fd == 0)
409  {
410  input_ready = true;
411  }
412  else if (PollFds[i].fd == INotifyFd)
413  {
415  mutt_debug(LL_DEBUG3, "file change(s) detected\n");
416  char *ptr = buf;
417  const struct inotify_event *event;
418 
419  while (true)
420  {
421  int len = read(INotifyFd, buf, sizeof(buf));
422  if (len == -1)
423  {
424  if (errno != EAGAIN)
425  mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
426  errno, strerror(errno));
427  break;
428  }
429 
430  while (ptr < (buf + len))
431  {
432  event = (const struct inotify_event *) ptr;
433  mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
434  event->wd, event->mask);
435  if (event->mask & IN_IGNORED)
436  monitor_handle_ignore(event->wd);
437  else if (event->wd == MonitorContextDescriptor)
439  ptr += sizeof(struct inotify_event) + event->len;
440  }
441  }
442  }
443  }
444  }
445  if (!input_ready)
446  rc = MonitorFilesChanged ? -2 : -3;
447  }
448  }
449 
450  return rc;
451 }
#define EVENT_BUFLEN
Definition: monitor.c:63
static size_t PollFdsLen
Definition: monitor.c:55
static struct pollfd * PollFds
Definition: monitor.c:56
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
int MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:49
int MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:50
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
static size_t PollFdsCount
Definition: monitor.c:54
Log at debug level 3.
Definition: logging.h:58
int MuttGetchTimeout
Timeout in ms for mutt_getch()
Definition: curs_lib.c:94
static int monitor_handle_ignore(int desc)
Listen for when a backup file is closed.
Definition: monitor.c:251

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 mailbox is NULL, the current mailbox (Context) is used.

Definition at line 461 of file monitor.c.

462 {
463  struct MonitorInfo info;
464  monitor_info_init(&info);
465 
466  int rc = 0;
467  int desc = monitor_resolve(&info, m);
468  if (desc != RESOLVERES_OK_NOTEXISTING)
469  {
470  if (!m && (desc == RESOLVERES_OK_EXISTING))
471  MonitorContextDescriptor = info.monitor->desc;
472  rc = (desc == RESOLVERES_OK_EXISTING) ? 0 : -1;
473  goto cleanup;
474  }
475 
476  uint32_t mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
477  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
478  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
479  {
480  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
481  info.path, errno, strerror(errno));
482  rc = -1;
483  goto cleanup;
484  }
485 
486  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
487  if (!m)
489 
490  monitor_new(&info, desc);
491 
492 cleanup:
493  monitor_info_free(&info);
494  return rc;
495 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
Information about a monitored file.
Definition: monitor.c:87
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:149
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
#define INOTIFY_MASK_DIR
Definition: monitor.c:60
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:205
static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:309
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:185
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:214
Log at debug level 3.
Definition: logging.h:58
#define RESOLVERES_OK_NOTEXISTING
Definition: monitor.c:68

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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 mailbox is NULL, the current mailbox (Context) is used.

Definition at line 506 of file monitor.c.

507 {
508  struct MonitorInfo info, info2;
509  int rc = 0;
510 
511  monitor_info_init(&info);
512  monitor_info_init(&info2);
513 
514  if (!m)
515  {
518  }
519 
520  if (monitor_resolve(&info, m) != RESOLVERES_OK_EXISTING)
521  {
522  rc = 2;
523  goto cleanup;
524  }
525 
526  if (Context)
527  {
528  if (m)
529  {
530  if ((monitor_resolve(&info2, NULL) == RESOLVERES_OK_EXISTING) &&
531  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
532  {
533  rc = 1;
534  goto cleanup;
535  }
536  }
537  else
538  {
540  {
541  rc = 1;
542  goto cleanup;
543  }
544  }
545  }
546 
547  inotify_rm_watch(info.monitor->desc, INotifyFd);
548  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
549  info.monitor->desc);
550 
551  monitor_delete(info.monitor);
553 
554 cleanup:
555  monitor_info_free(&info);
556  monitor_info_free(&info2);
557  return rc;
558 }
The "current" mailbox.
Definition: context.h:38
struct Mailbox * mutt_find_mailbox(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:267
Information about a monitored file.
Definition: monitor.c:87
#define RESOLVERES_OK_EXISTING
Definition: monitor.c:69
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:223
char * realpath
used for duplicate detection, context comparison, and the sidebar
Definition: mailbox.h:86
static int INotifyFd
Definition: monitor.c:52
struct Mailbox * mailbox
Definition: context.h:52
int MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:50
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:205
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:168
static int monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:309
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:214
Log at debug level 3.
Definition: logging.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

int MonitorFilesChanged = 0

true after a monitored file has changed

Definition at line 49 of file monitor.c.

int MonitorContextChanged = 0

true after the current mailbox has changed

Definition at line 50 of file monitor.c.

int INotifyFd = -1
static

Definition at line 52 of file monitor.c.

struct Monitor* Monitor = NULL
static

Definition at line 53 of file monitor.c.

size_t PollFdsCount = 0
static

Definition at line 54 of file monitor.c.

size_t PollFdsLen = 0
static

Definition at line 55 of file monitor.c.

struct pollfd* PollFds = NULL
static

Definition at line 56 of file monitor.c.

int MonitorContextDescriptor = -1
static

Definition at line 58 of file monitor.c.