NeoMutt  2018-07-16 +2388-bcedc8
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 "core/lib.h"
#include "monitor.h"
#include "context.h"
#include "curs_lib.h"
#include "globals.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_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

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

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

#define INOTIFY_MASK_FILE   IN_CLOSE_WRITE

Definition at line 59 of file monitor.c.

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

Definition at line 61 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 66 of file monitor.c.

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

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

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

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

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

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

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

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

173 {
174  if (!Monitor && (INotifyFd != -1))
175  {
177  close(INotifyFd);
178  INotifyFd = -1;
179  MonitorFilesChanged = false;
180  }
181 }
A watch on a file.
Definition: monitor.c:78
bool MonitorFilesChanged
true after a monitored file has changed
Definition: monitor.c:47
static int INotifyFd
Definition: monitor.c:50
static int mutt_poll_fd_remove(int fd)
Remove a file from the watch list.
Definition: monitor.c:134

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

190 {
191  struct Monitor *monitor = mutt_mem_calloc(1, sizeof(struct Monitor));
192  monitor->magic = info->magic;
193  monitor->st_dev = info->st_dev;
194  monitor->st_ino = info->st_ino;
195  monitor->desc = descriptor;
196  monitor->next = Monitor;
197  if (info->magic == MUTT_MH)
198  monitor->mh_backup_path = mutt_str_strdup(info->path);
199 
200  Monitor = monitor;
201 
202  return monitor;
203 }
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:93
ino_t st_ino
Definition: monitor.c:83
int desc
Definition: monitor.c:85
A watch on a file.
Definition: monitor.c:78
struct Monitor * next
Definition: monitor.c:80
char * mh_backup_path
Definition: monitor.c:81
enum MailboxType magic
Definition: monitor.c:84
static struct Monitor * Monitor
Definition: monitor.c:51
&#39;MH&#39; Mailbox type
Definition: mailbox.h:49
dev_t st_dev
Definition: monitor.c:82
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
const char * path
Definition: monitor.c:95
dev_t st_dev
Definition: monitor.c:96
ino_t st_ino
Definition: monitor.c:97

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

210 {
211  memset(info, 0, sizeof(*info));
212 }

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

219 {
220  mutt_buffer_free(&info->path_buf);
221 }
void mutt_buffer_free(struct Buffer **p)
Release a Buffer and its contents.
Definition: buffer.c:134
struct Buffer * path_buf
Definition: monitor.c:99

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

228 {
229  if (!monitor)
230  return;
231 
232  struct Monitor **ptr = &Monitor;
233 
234  while (true)
235  {
236  if (!*ptr)
237  return;
238  if (*ptr == monitor)
239  break;
240  ptr = &(*ptr)->next;
241  }
242 
243  FREE(&monitor->mh_backup_path);
244  monitor = monitor->next;
245  FREE(ptr);
246  *ptr = monitor;
247 }
A watch on a file.
Definition: monitor.c:78
struct Monitor * next
Definition: monitor.c:80
char * mh_backup_path
Definition: monitor.c:81
static struct Monitor * Monitor
Definition: monitor.c:51
#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 255 of file monitor.c.

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

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

Definition at line 313 of file monitor.c.

314 {
315  char *fmt = NULL;
316  struct stat sb;
317 
318  if (m)
319  {
320  info->magic = m->magic;
321  info->path = m->realpath;
322  }
323  else if (Context && Context->mailbox)
324  {
325  info->magic = Context->mailbox->magic;
326  info->path = Context->mailbox->realpath;
327  }
328  else
329  {
331  }
332 
333  if (info->magic == MUTT_UNKNOWN)
334  {
336  }
337  else if (info->magic == MUTT_MAILDIR)
338  {
339  info->is_dir = true;
340  fmt = "%s/new";
341  }
342  else
343  {
344  info->is_dir = false;
345  if (info->magic == MUTT_MH)
346  fmt = "%s/.mh_sequences";
347  }
348  if (fmt)
349  {
350  if (!info->path_buf)
351  info->path_buf = mutt_buffer_new();
352  mutt_buffer_printf(info->path_buf, fmt, info->path);
353  info->path = mutt_b2s(info->path_buf);
354  }
355  if (stat(info->path, &sb) != 0)
356  return RESOLVE_RES_FAIL_STAT;
357 
358  struct Monitor *iter = Monitor;
359  while (iter && ((iter->st_ino != sb.st_ino) || (iter->st_dev != sb.st_dev)))
360  iter = iter->next;
361 
362  info->st_dev = sb.st_dev;
363  info->st_ino = sb.st_ino;
364  info->monitor = iter;
365 
367 }
The "current" mailbox.
Definition: context.h:36
Can&#39;t identify Mailbox type.
Definition: monitor.c:69
enum MailboxType magic
Definition: monitor.c:93
ino_t st_ino
Definition: monitor.c:83
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:95
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:46
A watch on a file.
Definition: monitor.c:78
struct Monitor * next
Definition: monitor.c:80
File exists, monitor is already attached.
Definition: monitor.c:72
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:191
bool is_dir
Definition: monitor.c:94
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
No Mailbox to work on.
Definition: monitor.c:68
struct Monitor * monitor
Definition: monitor.c:98
#define mutt_b2s(buf)
Definition: buffer.h:41
static struct Monitor * Monitor
Definition: monitor.c:51
&#39;MH&#39; Mailbox type
Definition: mailbox.h:49
dev_t st_dev
Definition: monitor.c:82
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:70
File exists, no monitor is attached.
Definition: monitor.c:71
const char * path
Definition: monitor.c:95
dev_t st_dev
Definition: monitor.c:96
struct Buffer * path_buf
Definition: monitor.c:99
ino_t st_ino
Definition: monitor.c:97

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

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

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

464 {
465  struct MonitorInfo info;
466  monitor_info_init(&info);
467 
468  int rc = 0;
469  enum ResolveResult desc = monitor_resolve(&info, m);
470  if (desc != RESOLVE_RES_OK_NOTEXISTING)
471  {
472  if (!m && (desc == RESOLVE_RES_OK_EXISTING))
473  MonitorContextDescriptor = info.monitor->desc;
474  rc = (desc == RESOLVE_RES_OK_EXISTING) ? 0 : -1;
475  goto cleanup;
476  }
477 
478  uint32_t mask = info.is_dir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
479  if (((INotifyFd == -1) && (monitor_init() == -1)) ||
480  ((desc = inotify_add_watch(INotifyFd, info.path, mask)) == -1))
481  {
482  mutt_debug(LL_DEBUG2, "inotify_add_watch failed for '%s', errno=%d %s\n",
483  info.path, errno, strerror(errno));
484  rc = -1;
485  goto cleanup;
486  }
487 
488  mutt_debug(LL_DEBUG3, "inotify_add_watch descriptor=%d for '%s'\n", desc, info.path);
489  if (!m)
491 
492  monitor_new(&info, desc);
493 
494 cleanup:
495  monitor_info_free(&info);
496  return rc;
497 }
#define INOTIFY_MASK_FILE
Definition: monitor.c:59
Information about a monitored file.
Definition: monitor.c:91
File exists, monitor is already attached.
Definition: monitor.c:72
static int monitor_init(void)
Set up file monitoring.
Definition: monitor.c:153
static int INotifyFd
Definition: monitor.c:50
Log at debug level 2.
Definition: logging.h:57
ResolveResult
Results for the Monitor functions.
Definition: monitor.c:66
#define INOTIFY_MASK_DIR
Definition: monitor.c:58
File exists, no monitor is attached.
Definition: monitor.c:71
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:209
static int MonitorContextDescriptor
Definition: monitor.c:56
#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:189
static enum ResolveResult monitor_resolve(struct MonitorInfo *info, struct Mailbox *m)
Get the monitor for a mailbox.
Definition: monitor.c:313
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:218
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:

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

509 {
510  struct MonitorInfo info, info2;
511  int rc = 0;
512 
513  monitor_info_init(&info);
514  monitor_info_init(&info2);
515 
516  if (!m)
517  {
519  MonitorContextChanged = false;
520  }
521 
522  if (monitor_resolve(&info, m) != RESOLVE_RES_OK_EXISTING)
523  {
524  rc = 2;
525  goto cleanup;
526  }
527 
528  if (Context && Context->mailbox)
529  {
530  if (m)
531  {
532  if ((monitor_resolve(&info2, NULL) == RESOLVE_RES_OK_EXISTING) &&
533  (info.st_ino == info2.st_ino) && (info.st_dev == info2.st_dev))
534  {
535  rc = 1;
536  goto cleanup;
537  }
538  }
539  else
540  {
542  {
543  rc = 1;
544  goto cleanup;
545  }
546  }
547  }
548 
549  inotify_rm_watch(info.monitor->desc, INotifyFd);
550  mutt_debug(LL_DEBUG3, "inotify_rm_watch for '%s' descriptor=%d\n", info.path,
551  info.monitor->desc);
552 
553  monitor_delete(info.monitor);
555 
556 cleanup:
557  monitor_info_free(&info);
558  monitor_info_free(&info2);
559  return rc;
560 }
The "current" mailbox.
Definition: context.h:36
Information about a monitored file.
Definition: monitor.c:91
static void monitor_delete(struct Monitor *monitor)
Free a file monitor.
Definition: monitor.c:227
struct Mailbox * mailbox_find(const char *path)
Find the mailbox with a given path.
Definition: mailbox.c:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:95
File exists, monitor is already attached.
Definition: monitor.c:72
static int INotifyFd
Definition: monitor.c:50
struct Mailbox * mailbox
Definition: context.h:50
static void monitor_info_init(struct MonitorInfo *info)
Set up a file monitor.
Definition: monitor.c:209
bool MonitorContextChanged
true after the current mailbox has changed
Definition: monitor.c:48
static void monitor_check_free(void)
Close down file monitoring.
Definition: monitor.c:172
static int MonitorContextDescriptor
Definition: monitor.c:56
#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:313
static void monitor_info_free(struct MonitorInfo *info)
Shutdown a file monitor.
Definition: monitor.c:218
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

bool MonitorFilesChanged = false

true after a monitored file has changed

Definition at line 47 of file monitor.c.

bool MonitorContextChanged = false

true after the current mailbox has changed

Definition at line 48 of file monitor.c.

int INotifyFd = -1
static

Definition at line 50 of file monitor.c.

struct Monitor* Monitor = NULL
static

Definition at line 51 of file monitor.c.

size_t PollFdsCount = 0
static

Definition at line 52 of file monitor.c.

size_t PollFdsLen = 0
static

Definition at line 53 of file monitor.c.

struct pollfd* PollFds = NULL
static

Definition at line 54 of file monitor.c.

int MonitorContextDescriptor = -1
static

Definition at line 56 of file monitor.c.