NeoMutt  2018-07-16 +2225-8687db
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 "core/lib.h"
#include "curs_lib.h"
#include "globals.h"
#include "mutt_curses.h"
#include "mx.h"

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_NOMAGIC = -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

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.

Enumeration Type Documentation

Results for the Monitor functions.

Enumerator
RESOLVE_RES_FAIL_NOMAILBOX 

No Mailbox to work on.

RESOLVE_RES_FAIL_NOMAGIC 

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

69 {
75 };
Can&#39;t identify Mailbox type.
Definition: monitor.c:71
File exists, monitor is already attached.
Definition: monitor.c:74
No Mailbox to work on.
Definition: monitor.c:70
Can&#39;t stat() the Mailbox file.
Definition: monitor.c:72
File exists, no monitor is attached.
Definition: monitor.c:73

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

110 {
111  int i = 0;
112  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
113  ;
114 
115  if (i == PollFdsCount)
116  {
117  if (PollFdsCount == PollFdsLen)
118  {
119  PollFdsLen += 2;
120  mutt_mem_realloc(&PollFds, PollFdsLen * sizeof(struct pollfd));
121  }
122  PollFdsCount++;
123  PollFds[i].fd = fd;
124  PollFds[i].events = events;
125  }
126  else
127  PollFds[i].events |= events;
128 }
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:114
static size_t PollFdsCount
Definition: monitor.c:54
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 136 of file monitor.c.

137 {
138  int i = 0;
139  for (; (i < PollFdsCount) && (PollFds[i].fd != fd); i++)
140  ;
141  if (i == PollFdsCount)
142  return -1;
143  int d = PollFdsCount - i - 1;
144  if (d != 0)
145  memmove(&PollFds[i], &PollFds[i + 1], d * sizeof(struct pollfd));
146  PollFdsCount--;
147  return 0;
148 }
static struct pollfd * PollFds
Definition: monitor.c:56
static size_t PollFdsCount
Definition: monitor.c:54
static int monitor_init ( void  )
static

Set up file monitoring.

Return values
0Success
-1Error

Definition at line 155 of file monitor.c.

156 {
157  if (INotifyFd == -1)
158  {
159  INotifyFd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
160  if (INotifyFd == -1)
161  {
162  mutt_debug(LL_DEBUG2, "inotify_init1 failed, errno=%d %s\n", errno, strerror(errno));
163  return -1;
164  }
165  mutt_poll_fd_add(0, POLLIN);
166  mutt_poll_fd_add(INotifyFd, POLLIN);
167  }
168  return 0;
169 }
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:109
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static void monitor_check_free ( void  )
static

Close down file monitoring.

Definition at line 174 of file monitor.c.

175 {
176  if (!Monitor && (INotifyFd != -1))
177  {
179  close(INotifyFd);
180  INotifyFd = -1;
182  }
183 }
A watch on a file.
Definition: monitor.c:80
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:136
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 191 of file monitor.c.

192 {
193  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
194  monitor->magic = info->magic;
195  monitor->st_dev = info->st_dev;
196  monitor->st_ino = info->st_ino;
197  monitor->desc = descriptor;
198  monitor->next = Monitor;
199  if (info->magic == MUTT_MH)
200  monitor->mh_backup_path = mutt_str_strdup(info->path);
201 
202  Monitor = monitor;
203 
204  return monitor;
205 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
enum MailboxType magic
Definition: monitor.c:95
ino_t st_ino
Definition: monitor.c:85
int desc
Definition: monitor.c:87
A watch on a file.
Definition: monitor.c:80
struct Monitor * next
Definition: monitor.c:82
char * mh_backup_path
Definition: monitor.c:83
enum MailboxType magic
Definition: monitor.c:86
static struct Monitor * Monitor
Definition: monitor.c:53
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:84
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
const char * path
Definition: monitor.c:97
dev_t st_dev
Definition: monitor.c:98
ino_t st_ino
Definition: monitor.c:99
static void monitor_info_init ( struct MonitorInfo info)
static

Set up a file monitor.

Parameters
infoMonitor to initialise

Definition at line 211 of file monitor.c.

212 {
213  memset(info, 0, sizeof(*info));
214 }
static void monitor_info_free ( struct MonitorInfo info)
static

Shutdown a file monitor.

Parameters
infoMonitor to shut down

Definition at line 220 of file monitor.c.

221 {
222  mutt_buffer_free(&info->path_buf);
223 }
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:134
struct Buffer * path_buf
Definition: monitor.c:101
static void monitor_delete ( struct Monitor monitor)
static

Free a file monitor.

Parameters
monitorMonitor to free

Definition at line 229 of file monitor.c.

230 {
231  if (!monitor)
232  return;
233 
234  struct Monitor **ptr = &Monitor;
235 
236  while (true)
237  {
238  if (!*ptr)
239  return;
240  if (*ptr == monitor)
241  break;
242  ptr = &(*ptr)->next;
243  }
244 
245  FREE(&monitor->mh_backup_path);
246  monitor = monitor->next;
247  FREE(ptr);
248  *ptr = monitor;
249 }
A watch on a file.
Definition: monitor.c:80
struct Monitor * next
Definition: monitor.c:82
char * mh_backup_path
Definition: monitor.c:83
static struct Monitor * Monitor
Definition: monitor.c:53
#define FREE(x)
Definition: memory.h:40
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 257 of file monitor.c.

258 {
259  int new_desc = -1;
260  struct Monitor *iter = Monitor;
261  struct stat sb;
262 
263  while (iter && (iter->desc != desc))
264  iter = iter->next;
265 
266  if (iter)
267  {
268  if ((iter->magic == MUTT_MH) && (stat(iter->mh_backup_path, &sb) == 0))
269  {
270  new_desc = inotify_add_watch(INotifyFd, iter->mh_backup_path, INOTIFY_MASK_FILE);
271  if (new_desc == -1)
272  {
273  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
274  iter->mh_backup_path, errno, strerror(errno));
275  }
276  else
277  {
278  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n",
279  desc, iter->mh_backup_path);
280  iter->st_dev = sb.st_dev;
281  iter->st_ino = sb.st_ino;
282  iter->desc = new_desc;
283  }
284  }
285  else
286  {
287  mutt_debug(LL_DEBUG3, "cleanup watch (implicitly removed) - descriptor=%d\n", desc);
288  }
289 
290  if (MonitorContextDescriptor == desc)
291  MonitorContextDescriptor = new_desc;
292 
293  if (new_desc == -1)
294  {
295  monitor_delete(iter);
297  }
298  }
299 
300  return new_desc;
301 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
ino_t st_ino
Definition: monitor.c:85
int desc
Definition: monitor.c:87
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:229
A watch on a file.
Definition: monitor.c:80
struct Monitor * next
Definition: monitor.c:82
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
char * mh_backup_path
Definition: monitor.c:83
enum MailboxType magic
Definition: monitor.c:86
static struct Monitor * Monitor
Definition: monitor.c:53
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:84
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:174
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:58
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)
-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 315 of file monitor.c.

316 {
317  char *fmt = NULL;
318  struct stat sb;
319 
320  if (m)
321  {
322  info->magic = m->magic;
323  info->path = m->realpath;
324  }
325  else if (Context)
326  {
327  info->magic = Context->mailbox->magic;
328  info->path = Context->mailbox->realpath;
329  }
330  else
331  {
333  }
334 
335  if (info->magic == MUTT_UNKNOWN)
336  {
338  }
339  else if (info->magic == MUTT_MAILDIR)
340  {
341  info->isdir = 1;
342  fmt = "%s/new";
343  }
344  else
345  {
346  info->isdir = 0;
347  if (info->magic == MUTT_MH)
348  fmt = "%s/.mh_sequences";
349  }
350 
351  if (fmt)
352  {
353  if (!info->path_buf)
354  info->path_buf = mutt_buffer_new();
355  mutt_buffer_printf(info->path_buf, fmt, info->path);
356  info->path = mutt_b2s(info->path_buf);
357  }
358  if (stat(info->path, &sb) != 0)
359  return RESOLVE_RES_FAIL_STAT;
360 
361  struct Monitor *iter = Monitor;
362  while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev)))
363  iter = iter->next;
364 
365  info->st_dev = sb.st_dev;
366  info->st_ino = sb.st_ino;
367  info->monitor = iter;
368 
370 }
The "current" mailbox.
Definition: context.h:39
Can&#39;t identify Mailbox type.
Definition: monitor.c:71
enum MailboxType magic
Definition: monitor.c:95
ino_t st_ino
Definition: monitor.c:85
short isdir
Definition: monitor.c:96
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:96
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
A watch on a file.
Definition: monitor.c:80
struct Monitor * next
Definition: monitor.c:82
File exists, monitor is already attached.
Definition: monitor.c:74
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:191
struct Mailbox * mailbox
Definition: context.h:53
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:117
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
No Mailbox to work on.
Definition: monitor.c:70
struct Monitor * monitor
Definition: monitor.c:100
#define mutt_b2s(buf)
Definition: buffer.h:42
static struct Monitor * Monitor
Definition: monitor.c:53
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
dev_t st_dev
Definition: monitor.c:84
struct Buffer * mutt_buffer_new(void)
Create and initialise a Buffer.
Definition: buffer.c:45
Can&#39;t stat() the Mailbox file.
Definition: monitor.c:72
File exists, no monitor is attached.
Definition: monitor.c:73
const char * path
Definition: monitor.c:97
dev_t st_dev
Definition: monitor.c:98
struct Buffer * path_buf
Definition: monitor.c:101
ino_t st_ino
Definition: monitor.c:99
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 386 of file monitor.c.

387 {
388  int rc = 0;
389  char buf[EVENT_BUFLEN] __attribute__((aligned(__alignof__(struct inotify_event))));
390 
392 
393  if (INotifyFd != -1)
394  {
395  int fds = poll(PollFds, PollFdsLen, MuttGetchTimeout);
396 
397  if (fds == -1)
398  {
399  rc = -1;
400  if (errno != EINTR)
401  {
402  mutt_debug(LL_DEBUG2, "poll() failed, errno=%d %s\n", errno, strerror(errno));
403  }
404  }
405  else
406  {
407  bool input_ready = false;
408  for (int i = 0; fds && (i < PollFdsCount); i++)
409  {
410  if (PollFds[i].revents)
411  {
412  fds--;
413  if (PollFds[i].fd == 0)
414  {
415  input_ready = true;
416  }
417  else if (PollFds[i].fd == INotifyFd)
418  {
420  mutt_debug(LL_DEBUG3, "file change(s) detected\n");
421  char *ptr = buf;
422  const struct inotify_event *event = NULL;
423 
424  while (true)
425  {
426  int len = read(INotifyFd, buf, sizeof(buf));
427  if (len == -1)
428  {
429  if (errno != EAGAIN)
430  mutt_debug(LL_DEBUG2, "read inotify events failed, errno=%d %s\n",
431  errno, strerror(errno));
432  break;
433  }
434 
435  while (ptr < (buf + len))
436  {
437  event = (const struct inotify_event *) ptr;
438  mutt_debug(LL_DEBUG3, "+ detail: descriptor=%d mask=0x%x\n",
439  event->wd, event->mask);
440  if (event->mask & IN_IGNORED)
441  monitor_handle_ignore(event->wd);
442  else if (event->wd == MonitorContextDescriptor)
444  ptr += sizeof(struct inotify_event) + event->len;
445  }
446  }
447  }
448  }
449  }
450  if (!input_ready)
451  rc = MonitorFilesChanged ? -2 : -3;
452  }
453  }
454 
455  return rc;
456 }
#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:81
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:257
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 466 of file monitor.c.

467 {
468  struct MonitorInfo info;
469  monitor_info_init(&info);
470 
471  int rc = 0;
472  enum ResolveResult desc = monitor_resolve(&info, m);
473  if (desc != RESOLVE_RES_OK_NOTEXISTING)
474  {
475  if (!m && (desc == RESOLVE_RES_OK_EXISTING))
476  MonitorContextDescriptor = info.monitor->desc;
477  rc = (desc == RESOLVE_RES_OK_EXISTING) ? 0 : -1;
478  goto cleanup;
479  }
480 
481  uint32_t mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
482  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
483  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
484  {
485  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
486  info.path, errno, strerror(errno));
487  rc = -1;
488  goto cleanup;
489  }
490 
491  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
492  if (!m)
494 
495  monitor_new(&info, desc);
496 
497 cleanup:
498  monitor_info_free(&info);
499  return rc;
500 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:61
Information about a monitored file.
Definition: monitor.c:93
File exists, monitor is already attached.
Definition: monitor.c:74
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:155
static int INotifyFd
Definition: monitor.c:52
Log at debug level 2.
Definition: logging.h:57
ResolveResult
Results for the Monitor functions.
Definition: monitor.c:68
#define INOTIFY_MASK_DIR
Definition: monitor.c:60
File exists, no monitor is attached.
Definition: monitor.c:73
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:211
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static struct Monitor * monitor_new(struct MonitorInfo *info, int descriptor)
Create a new file monitor.
Definition: monitor.c:191
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:315
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:220
Log at debug level 3.
Definition: logging.h:58
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 511 of file monitor.c.

512 {
513  struct MonitorInfo info, info2;
514  int rc = 0;
515 
516  monitor_info_init(&info);
517  monitor_info_init(&info2);
518 
519  if (!m)
520  {
523  }
524 
525  if (monitor_resolve(&info, m) != RESOLVE_RES_OK_EXISTING)
526  {
527  rc = 2;
528  goto cleanup;
529  }
530 
531  if (Context)
532  {
533  if (m)
534  {
535  if ((monitor_resolve(&info2, NULL) == RESOLVE_RES_OK_EXISTING) &&
536  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
537  {
538  rc = 1;
539  goto cleanup;
540  }
541  }
542  else
543  {
545  {
546  rc = 1;
547  goto cleanup;
548  }
549  }
550  }
551 
552  inotify_rm_watch(info.monitor->desc, INotifyFd);
553  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
554  info.monitor->desc);
555 
556  monitor_delete(info.monitor);
558 
559 cleanup:
560  monitor_info_free(&info);
561  monitor_info_free(&info2);
562  return rc;
563 }
The "current" mailbox.
Definition: context.h:39
Information about a monitored file.
Definition: monitor.c:93
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:229
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:78
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:96
File exists, monitor is already attached.
Definition: monitor.c:74
static int INotifyFd
Definition: monitor.c:52
struct Mailbox * mailbox
Definition: context.h:53
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:211
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:174
static int MonitorContextDescriptor
Definition: monitor.c:58
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:315
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:220
Log at debug level 3.
Definition: logging.h:58

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.